From 6891c57e25d67a8deac5f1d7c8bb6ea2d69e1faf Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 5 Oct 2023 12:12:22 -0400 Subject: [PATCH 001/182] Implement prototype ice ocean model --- examples/melting_baroclinicity.jl | 244 ++++++++++++++++++++ src/ClimaOcean.jl | 1 + src/IceOceanModel/IceOceanModel.jl | 348 +++++++++++++++++++++++++++++ 3 files changed, 593 insertions(+) create mode 100644 examples/melting_baroclinicity.jl create mode 100644 src/IceOceanModel/IceOceanModel.jl diff --git a/examples/melting_baroclinicity.jl b/examples/melting_baroclinicity.jl new file mode 100644 index 00000000..fda05588 --- /dev/null +++ b/examples/melting_baroclinicity.jl @@ -0,0 +1,244 @@ +using Oceananigans +using Oceananigans.Architectures: arch_array +using Oceananigans.Fields: ZeroField, ConstantField +using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity +using Oceananigans.Units +using Oceananigans.Utils: prettysummary + +using SeawaterPolynomials: TEOS10EquationOfState, thermal_expansion, haline_contraction + +using ClimaSeaIce +using ClimaSeaIce: melting_temperature +using ClimaSeaIce.ThermalBoundaryConditions: RadiativeEmission, IceWaterThermalEquilibrium + +using Printf +using GLMakie +using Statistics + +include("ice_ocean_model.jl") + +arch = GPU() +Nx = Ny = 256 +Nz = 10 +Lz = 400 +x = y = (-50kilometers, 50kilometers) +halo = (4, 4, 4) +topology = (Periodic, Bounded, Bounded) + +ice_grid = RectilinearGrid(arch; x, y, + size = (Nx, Ny), + topology = (topology[1], topology[2], Flat), + halo = halo[1:2]) + +ocean_grid = RectilinearGrid(arch; topology, halo, x, y, + size = (Nx, Ny, Nz), + z = (-Lz, 0)) + +# Top boundary conditions: +# - outgoing radiative fluxes emitted from surface +# - incoming shortwave radiation starting after 40 days + +ice_ocean_heat_flux = Field{Center, Center, Nothing}(ice_grid) +top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(ice_grid) +top_salt_flux = Qˢ = Field{Center, Center, Nothing}(ice_grid) +# top_salt_flux = Qˢ = arch_array(arch, zeros(Nx, Ny)) + +# Generate a zero-dimensional grid for a single column slab model + +boundary_conditions = (T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Qˢ))) + +equation_of_state = TEOS10EquationOfState() +buoyancy = SeawaterBuoyancy(; equation_of_state) +horizontal_biharmonic_diffusivity = HorizontalScalarBiharmonicDiffusivity(κ=5e6) + +ocean_model = HydrostaticFreeSurfaceModel(; buoyancy, boundary_conditions, + grid = ocean_grid, + momentum_advection = WENO(), + tracer_advection = WENO(), + #closure = (horizontal_biharmonic_diffusivity, CATKEVerticalDiffusivity()), + closure = CATKEVerticalDiffusivity(), + coriolis = FPlane(f=1.4e-4), + tracers = (:T, :S, :e)) + +Nz = size(ocean_grid, 3) +So = ocean_model.tracers.S +ocean_surface_salinity = view(So, :, :, Nz) +bottom_bc = IceWaterThermalEquilibrium(ConstantField(30)) #ocean_surface_salinity) + +u, v, w = ocean_model.velocities +ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), + v = view(v, :, :, Nz), #interior(v, :, :, Nz), + w = ZeroField()) + +ice_model = SlabSeaIceModel(ice_grid; + velocities = ocean_surface_velocities, + advection = nothing, #WENO(), + ice_consolidation_thickness = 0.05, + ice_salinity = 4, + internal_thermal_flux = ConductiveFlux(conductivity=2), + #top_thermal_flux = ConstantField(-100), # W m⁻² + top_thermal_flux = ConstantField(0), # W m⁻² + top_thermal_boundary_condition = PrescribedTemperature(0), + bottom_thermal_boundary_condition = bottom_bc, + bottom_thermal_flux = ice_ocean_heat_flux) + +ocean_simulation = Simulation(ocean_model; Δt=20minutes, verbose=false) +ice_simulation = Simulation(ice_model, Δt=20minutes, verbose=false) + +# Initial condition +S₀ = 30 +T₀ = melting_temperature(ice_model.phase_transitions.liquidus, S₀) + 2.0 + +N²S = 1e-6 +β = haline_contraction(T₀, S₀, 0, equation_of_state) +g = ocean_model.buoyancy.model.gravitational_acceleration +dSdz = - g * β * N²S + +uᵢ(x, y, z) = 0.0 +Tᵢ(x, y, z) = T₀ # + 0.1 * randn() +Sᵢ(x, y, z) = S₀ + dSdz * z #+ 0.1 * randn() + +function hᵢ(x, y) + if sqrt(x^2 + y^2) < 20kilometers + #return 1 + 0.1 * rand() + return 2 + else + return 0 + end +end + +set!(ocean_model, u=uᵢ, S=Sᵢ, T=T₀) +set!(ice_model, h=hᵢ) + +coupled_model = IceOceanModel(ice_simulation, ocean_simulation) +coupled_simulation = Simulation(coupled_model, Δt=1minutes, stop_time=20days) + +S = ocean_model.tracers.S +by = - g * β * ∂y(S) + +function progress(sim) + h = sim.model.ice.model.ice_thickness + S = sim.model.ocean.model.tracers.S + T = sim.model.ocean.model.tracers.T + u = sim.model.ocean.model.velocities.u + msg1 = @sprintf("Iter: % 6d, time: % 12s", iteration(sim), prettytime(sim)) + msg2 = @sprintf(", max(h): %.2f", maximum(h)) + msg3 = @sprintf(", min(S): %.2f", minimum(S)) + msg4 = @sprintf(", extrema(T): (%.2f, %.2f)", minimum(T), maximum(T)) + msg5 = @sprintf(", max|∂y b|: %.2e", maximum(abs, by)) + msg6 = @sprintf(", max|u|: %.2e", maximum(abs, u)) + @info msg1 * msg2 * msg3 * msg4 * msg5 * msg6 + return nothing +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +h = ice_model.ice_thickness +T = ocean_model.tracers.T +S = ocean_model.tracers.S +u, v, w = ocean_model.velocities +η = ocean_model.free_surface.η + +ht = [] +Tt = [] +Ft = [] +Qt = [] +St = [] +ut = [] +vt = [] +ηt = [] +ζt = [] +tt = [] + +ζ = Field(∂x(v) - ∂y(u)) + +function saveoutput(sim) + compute!(ζ) + hn = Array(interior(h, :, :, 1)) + Fn = Array(interior(Qˢ, :, :, 1)) + Qn = Array(interior(Qᵀ, :, :, 1)) + Tn = Array(interior(T, :, :, Nz)) + Sn = Array(interior(S, :, :, Nz)) + un = Array(interior(u, :, :, Nz)) + vn = Array(interior(v, :, :, Nz)) + ηn = Array(interior(η, :, :, 1)) + ζn = Array(interior(ζ, :, :, Nz)) + push!(ht, hn) + push!(Ft, Fn) + push!(Qt, Qn) + push!(Tt, Tn) + push!(St, Sn) + push!(ut, un) + push!(vt, vn) + push!(ηt, ηn) + push!(ζt, ζn) + push!(tt, time(sim)) +end + +coupled_simulation.callbacks[:output] = Callback(saveoutput, IterationInterval(10)) + +run!(coupled_simulation) + +##### +##### Viz +##### + +set_theme!(Theme(fontsize=24)) + +x = xnodes(ocean_grid, Center()) +y = ynodes(ocean_grid, Center()) + +fig = Figure(resolution=(2400, 700)) + +axh = Axis(fig[1, 1], xlabel="x (km)", ylabel="y (km)", title="Ice thickness") +axT = Axis(fig[1, 2], xlabel="x (km)", ylabel="y (km)", title="Ocean surface temperature") +axS = Axis(fig[1, 3], xlabel="x (km)", ylabel="y (km)", title="Ocean surface salinity") +axZ = Axis(fig[1, 4], xlabel="x (km)", ylabel="y (km)", title="Ocean vorticity") + +Nt = length(tt) +slider = Slider(fig[2, 1:4], range=1:Nt, startvalue=Nt) +n = slider.value + +title = @lift string("Melt-driven baroclinic instability after ", prettytime(tt[$n])) +Label(fig[0, 1:3], title) + +hn = @lift ht[$n] +Fn = @lift Ft[$n] +Tn = @lift Tt[$n] +Sn = @lift St[$n] +un = @lift ut[$n] +vn = @lift vt[$n] +ηn = @lift ηt[$n] +ζn = @lift ζt[$n] +Un = @lift mean(ut[$n], dims=1)[:] + +x = x ./ 1e3 +y = y ./ 1e3 + +Stop = view(S, :, :, Nz) +Smax = maximum(Stop) +Smin = minimum(Stop) + +compute!(ζ) +ζtop = view(ζ, :, :, Nz) +ζmax = maximum(abs, ζtop) +ζlim = 2e-4 #ζmax / 2 + +heatmap!(axh, x, y, hn, colorrange=(0, 1), colormap=:grays) +heatmap!(axT, x, y, Tn, colormap=:thermal) +heatmap!(axS, x, y, Sn, colorrange = (29, 30), colormap=:haline) +heatmap!(axZ, x, y, ζn, colorrange=(-ζlim, ζlim), colormap=:redblue) + +#heatmap!(axZ, x, y, Tn, colormap=:thermal) +#heatmap!(axF, x, y, Fn) + +display(fig) + +#= +record(fig, "salty_baroclinic_ice_cube.mp4", 1:Nt, framerate=48) do nn + @info string(nn) + n[] = nn +end +=# + diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 64a8aaf9..903436ab 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -105,5 +105,6 @@ include("DataWrangling.jl") include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") include("IdealizedSimulations/IdealizedSimulations.jl") +include("IceOceanModel/IceOceanModel.jl") end # module diff --git a/src/IceOceanModel/IceOceanModel.jl b/src/IceOceanModel/IceOceanModel.jl new file mode 100644 index 00000000..d4b9696e --- /dev/null +++ b/src/IceOceanModel/IceOceanModel.jl @@ -0,0 +1,348 @@ +module IceOceanModel + +using Oceananigans.Operators + +using Oceananigans.Architectures: architecture +using Oceananigans.BoundaryConditions: fill_halo_regions! +using Oceananigans.Models: AbstractModel +using Oceananigans.TimeSteppers: tick! +using Oceananigans.Utils: launch! + +using KernelAbstractions: @kernel, @index +using KernelAbstractions.Extras.LoopInfo: @unroll + +# Simulations interface +import Oceananigans: fields, prognostic_fields +import Oceananigans.Fields: set! +import Oceananigans.Models: timestepper, NaNChecker, default_nan_checker +import Oceananigans.OutputWriters: default_included_properties +import Oceananigans.Simulations: reset!, initialize!, iteration +import Oceananigans.TimeSteppers: time_step!, update_state!, time +import Oceananigans.Utils: prettytime + +struct IceOceanModel{FT, C, G, I, O, S, PI, PC} <: AbstractModel{Nothing} + clock :: C + grid :: G # TODO: make it so simulation does not require this + ice :: I + previous_ice_thickness :: PI + previous_ice_concentration :: PC + ocean :: O + solar_insolation :: S + ocean_density :: FT + ocean_heat_capacity :: FT + ocean_emissivity :: FT + stefan_boltzmann_constant :: FT + reference_temperature :: FT +end + +const IOM = IceOceanModel + +Base.summary(::IOM) = "IceOceanModel" +prettytime(model::IOM) = prettytime(model.clock.time) +iteration(model::IOM) = model.clock.iteration +timestepper(::IOM) = nothing +reset!(::IOM) = nothing +initialize!(::IOM) = nothing +default_included_properties(::IOM) = tuple() +update_state!(::IOM) = nothing +prognostic_fields(cm::IOM) = nothing +fields(::IOM) = NamedTuple() + +function IceOceanModel(ice, ocean; clock = Clock{Float64}(0, 0, 1)) + + previous_ice_thickness = deepcopy(ice.model.ice_thickness) + previous_ice_concentration = deepcopy(ice.model.ice_concentration) + + grid = ocean.model.grid + ice_ocean_thermal_flux = Field{Center, Center, Nothing}(grid) + ice_ocean_salt_flux = Field{Center, Center, Nothing}(grid) + solar_insolation = Field{Center, Center, Nothing}(grid) + + ocean_density = 1024 + ocean_heat_capacity = 3991 + ocean_emissivity = 1 + reference_temperature = 273.15 + stefan_boltzmann_constant = 5.67e-8 + + # How would we ensure consistency? + try + if ice.model.external_thermal_fluxes.top isa RadiativeEmission + radiation = ice.model.external_thermal_fluxes.top + else + radiation = filter(flux isa RadiativeEmission, ice.model.external_thermal_fluxes.top) |> first + end + + stefan_boltzmann_constant = radiation.stefan_boltzmann_constant + reference_temperature = radiation.reference_temperature + catch + end + + FT = eltype(ocean.model.grid) + + return IceOceanModel(clock, + ocean.model.grid, + ice, + previous_ice_thickness, + previous_ice_concentration, + ocean, + solar_insolation, + convert(FT, ocean_density), + convert(FT, ocean_heat_capacity), + convert(FT, ocean_emissivity), + convert(FT, stefan_boltzmann_constant), + convert(FT, reference_temperature)) +end + +time(coupled_model::IceOceanModel) = coupled_model.clock.time + +function compute_air_sea_flux!(coupled_model) + ocean = coupled_model.ocean + ice = coupled_model.ice + + T = ocean.model.tracers.T + Nx, Ny, Nz = size(ocean.model.grid) + + grid = ocean.model.grid + arch = architecture(grid) + + σ = coupled_model.stefan_boltzmann_constant + ρₒ = coupled_model.ocean_density + cₒ = coupled_model.ocean_heat_capacity + Tᵣ = coupled_model.reference_temperature + Qᵀ = T.boundary_conditions.top.condition + Tₒ = ocean.model.tracers.T + hᵢ = ice.model.ice_thickness + ℵᵢ = ice.model.ice_concentration + I₀ = coupled_model.solar_insolation + + launch!(arch, grid, :xy, _compute_air_sea_flux!, + Qᵀ, grid, Tₒ, hᵢ, ℵᵢ, I₀, + σ, ρₒ, cₒ, Tᵣ) +end + +@kernel function _compute_air_sea_flux!(temperature_flux, + grid, + ocean_temperature, + ice_thickness, + ice_concentration, + solar_insolation, + σ, ρₒ, cₒ, Tᵣ) + + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + + @inbounds begin + T₀ = ocean_temperature[i, j, Nz] # at the surface + h = ice_thickness[i, j, 1] + ℵ = ice_concentration[i, j, 1] + I₀ = solar_insolation[i, j, 1] + end + + # Radiation model + ϵ = 1 # ocean emissivity + ΣQᵀ = ϵ * σ * (T₀ + Tᵣ)^4 / (ρₒ * cₒ) + + # Also add solar insolation + ΣQᵀ += I₀ / (ρₒ * cₒ) + + # Set the surface flux only if ice-free + Qᵀ = temperature_flux + + # @inbounds Qᵀ[i, j, 1] = 0 #(1 - ℵ) * ΣQᵀ +end + +function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) + ocean = coupled_model.ocean + ice = coupled_model.ice + liquidus = ice.model.phase_transitions.liquidus + grid = ocean.model.grid + ice.Δt = Δt + ocean.Δt = Δt + + fill_halo_regions!(h) + + # Initialization + if coupled_model.clock.iteration == 0 + h⁻ = coupled_model.previous_ice_thickness + hⁿ = coupled_model.ice.model.ice_thickness + parent(h⁻) .= parent(hⁿ) + end + + time_step!(ice) + + # TODO: put this in update_state! + compute_ice_ocean_salinity_flux!(coupled_model) + ice_ocean_latent_heat!(coupled_model) + #compute_solar_insolation!(coupled_model) + #compute_air_sea_flux!(coupled_model) + + time_step!(ocean) + + # TODO: + # - Store fractional ice-free / ice-covered _time_ for more + # accurate flux computation? + # - Or, input "excess heat flux" into ocean after the ice melts + # - Currently, non-conservative for heat due bc we don't account for excess + + # TODO after ice time-step: + # - Adjust ocean temperature if the ice completely melts? + + tick!(coupled_model.clock, Δt) + + return nothing +end + +function compute_ice_ocean_salinity_flux!(coupled_model) + # Compute salinity increment due to changes in ice thickness + + ice = coupled_model.ice + ocean = coupled_model.ocean + grid = ocean.model.grid + arch = architecture(grid) + Qˢ = ocean.model.tracers.S.boundary_conditions.top.condition + Sₒ = ocean.model.tracers.S + Sᵢ = ice.model.ice_salinity + Δt = ocean.Δt + hⁿ = ice.model.ice_thickness + h⁻ = coupled_model.previous_ice_thickness + + launch!(arch, grid, :xy, _compute_ice_ocean_salinity_flux!, + Qˢ, grid, hⁿ, h⁻, Sᵢ, Sₒ, Δt) + + return nothing +end + + +@kernel function _compute_ice_ocean_salinity_flux!(ice_ocean_salinity_flux, + grid, + ice_thickness, + previous_ice_thickness, + ice_salinity, + ocean_salinity, + Δt) + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + + hⁿ = ice_thickness + h⁻ = previous_ice_thickness + Qˢ = ice_ocean_salinity_flux + Sᵢ = ice_salinity + Sₒ = ocean_salinity + + @inbounds begin + # Thickness of surface grid cell + Δh = hⁿ[i, j, 1] - h⁻[i, j, 1] + + # Update surface salinity flux. + # Note: the Δt below is the ocean time-step, eg. + # ΔS = ⋯ - ∮ Qˢ dt ≈ ⋯ - Δtₒ * Qˢ + Qˢ[i, j, 1] = Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) + + # Update previous ice thickness + h⁻[i, j, 1] = hⁿ[i, j, 1] + end +end + +function ice_ocean_latent_heat!(coupled_model) + ocean = coupled_model.ocean + ice = coupled_model.ice + ρₒ = coupled_model.ocean_density + cₒ = coupled_model.ocean_heat_capacity + Qₒ = ice.model.external_thermal_fluxes.bottom + Tₒ = ocean.model.tracers.T + Sₒ = ocean.model.tracers.S + Δt = ocean.Δt + hᵢ = ice.model.ice_thickness + + liquidus = ice.model.phase_transitions.liquidus + grid = ocean.model.grid + arch = architecture(grid) + + launch!(arch, grid, :xy, _compute_ice_ocean_latent_heat!, + Qₒ, grid, hᵢ, Tₒ, Sₒ, liquidus, ρₒ, cₒ, Δt) + + return nothing +end + +@kernel function _compute_ice_ocean_latent_heat!(latent_heat, + grid, + ice_thickness, + ocean_temperature, + ocean_salinity, + liquidus, + ρₒ, cₒ, Δt) + + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + Qₒ = latent_heat + hᵢ = ice_thickness + Tₒ = ocean_temperature + Sₒ = ocean_salinity + + δQ = zero(grid) + icy_cell = @inbounds hᵢ[i, j, 1] > 0 # make ice bath approximation then + + @unroll for k = Nz:-1:1 + @inbounds begin + # Various quantities + Δz = Δzᶜᶜᶜ(i, j, k, grid) + Tᴺ = Tₒ[i, j, k] + Sᴺ = Sₒ[i, j, k] + end + + # Melting / freezing temperature at the surface of the ocean + Tₘ = melting_temperature(liquidus, Sᴺ) + + # Conditions for non-zero ice-ocean flux: + # - the ocean is below the freezing temperature, causing formation of ice. + freezing = Tᴺ < Tₘ + + # - We are at the surface and the cell is covered by ice. + icy_surface_cell = (k == Nz) & icy_cell + + # When there is a non-zero ice-ocean flux, we will instantaneously adjust the + # temperature of the grid cells accordingly. + adjust_temperature = freezing | icy_surface_cell + + # Compute change in ocean thermal energy. + # + # - When Tᴺ < Tₘ, we heat the ocean back to melting temperature by extracting heat from the ice, + # assuming that the heat flux (which is carried by nascent ice crystals called frazil ice) floats + # instantaneously to the surface. + # + # - When Tᴺ > Tₘ and we are in a surface cell covered by ice, we assume equilibrium + # and cool the ocean by injecting excess heat into the ice. + # + δEₒ = adjust_temperature * ρₒ * cₒ * (Tₘ - Tᴺ) + + # Perform temperature adjustment + @inline Tₒ[i, j, k] = ifelse(adjust_temperature, Tₘ, Tᴺ) + + # Compute the heat flux from ocean into ice. + # + # A positive value δQ > 0 implies that the ocean is cooled; ie heat + # is fluxing upwards, into the ice. This occurs when applying the + # ice bath equilibrium condition to cool down a warm ocean (δEₒ < 0). + # + # A negative value δQ < 0 implies that heat is fluxed from the ice into + # the ocean, cooling the ice and heating the ocean (δEₒ > 0). This occurs when + # frazil ice is formed within the ocean. + + δQ -= δEₒ * Δz / Δt + end + + # Store ice-ocean flux + @inbounds Qₒ[i, j, 1] = δQ +end + +# Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). +function default_nan_checker(model::IceOceanModel) + u_ocean = model.ocean.model.velocities.u + nan_checker = NaNChecker((; u_ocean)) + return nan_checker +end + +end # module From a108beb2865507d6e702b3b27453fc2b8476d431 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 5 Oct 2023 12:15:29 -0400 Subject: [PATCH 002/182] Add OceanOnlyModel --- src/IceOceanModel/IceOceanModel.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/IceOceanModel/IceOceanModel.jl b/src/IceOceanModel/IceOceanModel.jl index d4b9696e..ccac5b12 100644 --- a/src/IceOceanModel/IceOceanModel.jl +++ b/src/IceOceanModel/IceOceanModel.jl @@ -20,7 +20,7 @@ import Oceananigans.Simulations: reset!, initialize!, iteration import Oceananigans.TimeSteppers: time_step!, update_state!, time import Oceananigans.Utils: prettytime -struct IceOceanModel{FT, C, G, I, O, S, PI, PC} <: AbstractModel{Nothing} +struct IceOceanModel{FT, I, C, G, O, S, PI, PC} <: AbstractModel{Nothing} clock :: C grid :: G # TODO: make it so simulation does not require this ice :: I @@ -36,6 +36,7 @@ struct IceOceanModel{FT, C, G, I, O, S, PI, PC} <: AbstractModel{Nothing} end const IOM = IceOceanModel +const OceanOnlyModel = IceOceanModel{<:Any, Nothing} Base.summary(::IOM) = "IceOceanModel" prettytime(model::IOM) = prettytime(model.clock.time) From 1eab2c0e9a55c2eae40dda7664e434ebc2ffc559 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 5 Oct 2023 12:17:46 -0400 Subject: [PATCH 003/182] Add constructor for ocean only model --- src/IceOceanModel/IceOceanModel.jl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/IceOceanModel/IceOceanModel.jl b/src/IceOceanModel/IceOceanModel.jl index ccac5b12..63f626b6 100644 --- a/src/IceOceanModel/IceOceanModel.jl +++ b/src/IceOceanModel/IceOceanModel.jl @@ -35,9 +35,6 @@ struct IceOceanModel{FT, I, C, G, O, S, PI, PC} <: AbstractModel{Nothing} reference_temperature :: FT end -const IOM = IceOceanModel -const OceanOnlyModel = IceOceanModel{<:Any, Nothing} - Base.summary(::IOM) = "IceOceanModel" prettytime(model::IOM) = prettytime(model.clock.time) iteration(model::IOM) = model.clock.iteration @@ -49,7 +46,16 @@ update_state!(::IOM) = nothing prognostic_fields(cm::IOM) = nothing fields(::IOM) = NamedTuple() -function IceOceanModel(ice, ocean; clock = Clock{Float64}(0, 0, 1)) + +default_clock(FT) = Clock{FT}(0, 0, 1) + +const IOM = IceOceanModel + +# "Ocean only" +const OceanOnlyModel = IceOceanModel{<:Any, Nothing} +OceanOnlyModel(ocean; clock=default_clock(eltype(ocean.model))) = IceOceanModel(nothing, ocean; clock) + +function IceOceanModel(ice, ocean; clock = default_clock(eltype(ocean.model))) previous_ice_thickness = deepcopy(ice.model.ice_thickness) previous_ice_concentration = deepcopy(ice.model.ice_concentration) From 11d75500e0733f47219c2c2c1f9d3f9cdb634ab2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 15:32:46 -0400 Subject: [PATCH 004/182] starting out --- src/IceOceanModel/IceOceanModel.jl | 14 ++++++++++---- .../atmosphere_boundary_conditions.jl | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/IceOceanModel/atmosphere_boundary_conditions.jl diff --git a/src/IceOceanModel/IceOceanModel.jl b/src/IceOceanModel/IceOceanModel.jl index 63f626b6..3f68811e 100644 --- a/src/IceOceanModel/IceOceanModel.jl +++ b/src/IceOceanModel/IceOceanModel.jl @@ -20,13 +20,14 @@ import Oceananigans.Simulations: reset!, initialize!, iteration import Oceananigans.TimeSteppers: time_step!, update_state!, time import Oceananigans.Utils: prettytime -struct IceOceanModel{FT, I, C, G, O, S, PI, PC} <: AbstractModel{Nothing} +struct IceOceanModel{FT, I, O, F, C, G, S, PI, PC} <: AbstractModel{Nothing} clock :: C grid :: G # TODO: make it so simulation does not require this ice :: I previous_ice_thickness :: PI previous_ice_concentration :: PC ocean :: O + atmospheric_forcing :: F solar_insolation :: S ocean_density :: FT ocean_heat_capacity :: FT @@ -53,9 +54,13 @@ const IOM = IceOceanModel # "Ocean only" const OceanOnlyModel = IceOceanModel{<:Any, Nothing} -OceanOnlyModel(ocean; clock=default_clock(eltype(ocean.model))) = IceOceanModel(nothing, ocean; clock) - -function IceOceanModel(ice, ocean; clock = default_clock(eltype(ocean.model))) + +OceanOnlyModel(ocean; atmospheric_forcing = nothing, clock = default_clock(eltype(ocean.model))) = + IceOceanModel(nothing, ocean; atmospheric_forcing, clock) + +function IceOceanModel(ice, ocean; + atmospheric_forcing = nothing, + clock = default_clock(eltype(ocean.model))) previous_ice_thickness = deepcopy(ice.model.ice_thickness) previous_ice_concentration = deepcopy(ice.model.ice_concentration) @@ -93,6 +98,7 @@ function IceOceanModel(ice, ocean; clock = default_clock(eltype(ocean.model))) previous_ice_concentration, ocean, solar_insolation, + atmospheric_forcing, convert(FT, ocean_density), convert(FT, ocean_heat_capacity), convert(FT, ocean_emissivity), diff --git a/src/IceOceanModel/atmosphere_boundary_conditions.jl b/src/IceOceanModel/atmosphere_boundary_conditions.jl new file mode 100644 index 00000000..bd38aeeb --- /dev/null +++ b/src/IceOceanModel/atmosphere_boundary_conditions.jl @@ -0,0 +1,18 @@ +module AtmosphericForcings + +# We generally have 2 types of atmospheric forcing: Prescribed fluxes and +# Prescribed atmospheric state (to treat with bulk formulae) + +export PrescribedAtmosphere, PrescribedFluxes + +abstract type AbstractAtmospericForcing end + +struct PrescribedAtmosphere{} <: AbstractAtmospericForcing + + +end + + + + +end \ No newline at end of file From 1126d03f0dcda60aafdb83f5a07ca35d56bff3c4 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 15:33:47 -0400 Subject: [PATCH 005/182] airseafluxes --- .../atmosphere_boundary_conditions.jl | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) diff --git a/src/IceOceanModel/atmosphere_boundary_conditions.jl b/src/IceOceanModel/atmosphere_boundary_conditions.jl index bd38aeeb..db595587 100644 --- a/src/IceOceanModel/atmosphere_boundary_conditions.jl +++ b/src/IceOceanModel/atmosphere_boundary_conditions.jl @@ -12,7 +12,194 @@ struct PrescribedAtmosphere{} <: AbstractAtmospericForcing end +# To put in ClimaOcean.jl integrating with ClimaSeaIce.jl (To modify) +#= +using Adapt +using KernelAbstractions.Extras.LoopInfo: @unroll +using Oceananigans.Utils: Time + +struct AirSeaFlux{A, R, H, P, W, T, Q, D, C, E} <: Function + adiabatic_lapse_rate :: R # - + atmosphere_state_height :: H # m + reference_height :: H # m + surface_pressure :: P # Pa + wind_speed :: W # m/s + air_temperature :: T # deg ᵒC + air_humidity :: Q # kg/m³ + air_density :: D # kg/m³ + cloud_cover_feedback :: C # - + gamma_air :: C # - + ocean_emissivity :: E # - + + AirSeaFlux{A}(adiabatic_lapse_rate::R, + atmosphere_state_height::H, + reference_height::H, + surface_pressure::P, + wind_speed::W, + air_temperature::T, + air_humidity::Q, + air_density::D, + cloud_cover_coeff::C, + gamma_air::C, + ocean_emissivity::E) where {A, R, H, P, W, T, Q, D, C, E} = + new{A, R, H, P, W, T, Q, D, C, E}(adiabatic_lapse_rate, + atmosphere_state_height, + reference_height, + surface_pressure, + wind_speed, + air_temperature, + air_humidity, + air_density, + cloud_cover_coeff, + gamma_air, + ocean_emissivity) +end + +struct HeatFlux end +struct WindStress end + +function AirSeaFlux(; + adiabatic_lapse_rate = 0.08, + atmosphere_state_height = 10, # m + reference_height = 10, # m + surface_pressure = 1e5, # Pa + wind_speed, # m/s + air_temperature, # deg ᵒC + air_humidity = 0.01, # kg/m³ + air_density = 1.25, # kg/m³ + cloud_cover_coeff = 0.8, + gamma_air = 0.01, + ocean_emissivity = 0.9, + flux_or_stress::A = HeatFlux()) where A + + return AirSeaFlux{A}(adiabatic_lapse_rate, + atmosphere_state_height, + reference_height, + surface_pressure, + wind_speed, + air_temperature, + air_humidity, + air_density, + cloud_cover_coeff, + gamma_air, + ocean_emissivity) +end + +Adapt.adapt_structure(to, f::AirSeaFlux{A}) where A = + AirSeaFlux{A}(Adapt.adapt(to, f.adiabatic_lapse_rate), + Adapt.adapt(to, f.atmosphere_state_height), + Adapt.adapt(to, f.reference_height), + Adapt.adapt(to, f.surface_pressure), + Adapt.adapt(to, f.wind_speed), + Adapt.adapt(to, f.air_temperature), + Adapt.adapt(to, f.air_humidity), + Adapt.adapt(to, f.air_density), + Adapt.adapt(to, f.cloud_cover_feedback), + Adapt.adapt(to, f.gamma_air), + Adapt.adapt(to, f.ocean_emissivity)) + +const AirSeaHeatFlux = AirSeaFlux{HeatFlux} +const AirSeaWindStress = AirSeaFlux{WindStress} + +function (f::AirSeaHeatFlux)(i, j, grid, clock, fields) + + hᵀ = f.atmosphere_state_height + α = f.adiabatic_lapse_rate + Tₐ = f.air_temperature[i, j, 1, Time(clock.time)] + uₛ = f.wind_speed[i, j, 1, Time(clock.time)] + qₐ = f.air_humidity + ρₐ = f.air_density + γ = f.gamma_air + p₀ = f.surface_pressure + + FT = eltype(grid) + + # latent heat of evaporation + ℒ = convert(FT, 2.5e6) + + Tₛ = fields.T[i, j, grid.Nz] + T₀ = Tₐ*(1 - γ * qₐ) + + # sea-air temperature difference + ΔT = T₀ - Tₛ + α*hᵀ + + # saturation vapour pressure (Pa) + eₛ = convert(FT, 611.2) * exp(convert(FT, 17.67) * Tₛ / (Tₛ + convert(FT, 243.5))) + + # saturation air humidity (kg/m³) + qₛ = convert(FT, 0.622) * eₛ / (p₀ - eₛ) + + # air excess humidity + Δq = qₐ - qₛ + + # Turbulent heat transfer coefficients + Cᵀ, Cᵁ, Cq = turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) + + # sensible heat flux (W/m²) + H = ρₐ * uₛ * Cᵀ * Cᵁ * ΔT + + # latent heat flux (W/m²) + L = ρₐ * uₛ * Cq * Cᵁ * Δq * ℒ + + # net longwave radiation (W/m²) + Rₙ = f.ocean_emissivity * convert(FT, 5.67e-8) * (Tₛ + convert(FT, 273.15))^4 * (1 - f.cloud_cover_feedback) + + return H + L + Rₙ +end + +function (f::AirSeaWindStress)(i, j, grid, clock, fields) + + uₛ = f.wind_speed[i, j, 1, Time(clock.time)] + ρₐ = f.air_density + FT = eltype(grid) + + # Drag coefficient + Cᴰ = ifelse(uₛ > 25, convert(FT, 2.3e-3), convert(FT, 1.3e-3)) + + return ρₐ * Cᴰ * uₛ^2 +end + +# Follows MITgcm +@inline function turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) + hᵀ = f.atmosphere_state_height + zᴿ = f.reference_height + λ = log(hᵀ / zᴿ) + γ = f.gamma_air + + Cᵀ = Cᵁ = Cq = convert(FT, 0.41) / log(zᴿ * 2) + u★ = Cᵁ * uₛ + T★ = Cᵀ * ΔT + q★ = Cq * Δq + + @unroll for iter in 1:5 + G = Γ(FT, u★, T★, q★, T₀, qₐ, f) + χ = sqrt(1 - 16 * G) + + ψˢ = ifelse(G > 0, -5G, 2 * log((1 + χ^2) / 2)) + ψᵐ = ifelse(G > 0, -5G, 2 * log((1 + χ) / 2) + ψˢ / 2 - 2 * atan(χ) + convert(FT, π/2)) + + Cᵁ = Cᵁ / (1 + Cᵁ * (λ - ψᵐ) / convert(FT, 0.41)) + Cᵀ = Cᵀ / (1 + Cᵀ * (λ - ψˢ) / convert(FT, 0.41)) + u★ = Cᵁ * uₛ + T★ = Cᵀ * ΔT + q★ = Cq * Δq + end + + return Cᵀ, Cᵁ, Cq +end + +@inline Γ(FT, u★, T★, q★, T₀, qₐ, f) = convert(FT, 0.41) * convert(FT, 9.80655) * f.reference_height / u★^2 * + (T★ / T₀ - q★ / (1/f.gamma_air - qₐ)) + +AirSeaHeatFluxBoundaryCondition(; kwargs...) = + FluxBoundaryCondition(AirSeaFlux(; flux_or_stress = HeatFlux(), kwargs...), discrete_form = true) + +AirSeaWindStressBoundaryCondition(; kwargs...) = + FluxBoundaryCondition(AirSeaFlux(; flux_or_stress = WindStress(), kwargs...), discrete_form = true) + + +=# end \ No newline at end of file From 12e89d44fd46a089bc560796be88cff024a394c8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 15:34:20 -0400 Subject: [PATCH 006/182] atmospheric state --- src/IceOceanModel/atmosphere_boundary_conditions.jl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/IceOceanModel/atmosphere_boundary_conditions.jl b/src/IceOceanModel/atmosphere_boundary_conditions.jl index db595587..6e0c9d8f 100644 --- a/src/IceOceanModel/atmosphere_boundary_conditions.jl +++ b/src/IceOceanModel/atmosphere_boundary_conditions.jl @@ -8,8 +8,16 @@ export PrescribedAtmosphere, PrescribedFluxes abstract type AbstractAtmospericForcing end struct PrescribedAtmosphere{} <: AbstractAtmospericForcing - - + adiabatic_lapse_rate :: R # - + atmosphere_state_height :: H # m + reference_height :: H # m + surface_pressure :: P # Pa + wind_speed :: W # m/s + air_temperature :: T # deg ᵒC + air_humidity :: Q # kg/m³ + air_density :: D # kg/m³ + cloud_cover_feedback :: C # - + gamma_air :: C # - end # To put in ClimaOcean.jl integrating with ClimaSeaIce.jl (To modify) From 923030b825ffdf861123657ad5d71a38b8c80928 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:34:20 -0400 Subject: [PATCH 007/182] more changes --- src/IceOceanModel/IceOceanModel.jl | 26 ++++++---- .../atmosphere_boundary_conditions.jl | 49 +++++++++++++++++-- src/IceOceanModel/model_utils.jl | 9 ++++ src/IceOceanModel/only_ocean_model.jl | 39 +++++++++++++++ 4 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 src/IceOceanModel/model_utils.jl create mode 100644 src/IceOceanModel/only_ocean_model.jl diff --git a/src/IceOceanModel/IceOceanModel.jl b/src/IceOceanModel/IceOceanModel.jl index 3f68811e..c54d7db0 100644 --- a/src/IceOceanModel/IceOceanModel.jl +++ b/src/IceOceanModel/IceOceanModel.jl @@ -111,6 +111,7 @@ time(coupled_model::IceOceanModel) = coupled_model.clock.time function compute_air_sea_flux!(coupled_model) ocean = coupled_model.ocean ice = coupled_model.ice + atmosphere = coupled_model.atmospheric_forcing T = ocean.model.tracers.T Nx, Ny, Nz = size(ocean.model.grid) @@ -128,7 +129,7 @@ function compute_air_sea_flux!(coupled_model) ℵᵢ = ice.model.ice_concentration I₀ = coupled_model.solar_insolation - launch!(arch, grid, :xy, _compute_air_sea_flux!, + launch!(ocean, :xy, _compute_air_sea_flux!, Qᵀ, grid, Tₒ, hᵢ, ℵᵢ, I₀, σ, ρₒ, cₒ, Tᵣ) end @@ -159,7 +160,7 @@ end # Also add solar insolation ΣQᵀ += I₀ / (ρₒ * cₒ) - # Set the surface flux only if ice-free + # Set the surface flux only if ice-free or the moment Qᵀ = temperature_flux # @inbounds Qᵀ[i, j, 1] = 0 #(1 - ℵ) * ΣQᵀ @@ -168,9 +169,7 @@ end function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) ocean = coupled_model.ocean ice = coupled_model.ice - liquidus = ice.model.phase_transitions.liquidus - grid = ocean.model.grid - ice.Δt = Δt + ice.Δt = Δt ocean.Δt = Δt fill_halo_regions!(h) @@ -185,10 +184,11 @@ function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) time_step!(ice) # TODO: put this in update_state! - compute_ice_ocean_salinity_flux!(coupled_model) - ice_ocean_latent_heat!(coupled_model) + # Air-sea and Air-ice fluxes substitute the previous values + # while ice-ocean fluxes are additive + compute_air_sea_flux!(coupled_model) + compute_ice_ocean_flux!(coupled_model) #compute_solar_insolation!(coupled_model) - #compute_air_sea_flux!(coupled_model) time_step!(ocean) @@ -206,6 +206,12 @@ function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) return nothing end +function compute_ice_ocean_flux!(coupled_model) + compute_ice_ocean_salinity_flux!(coupled_model) + ice_ocean_latent_heat!(coupled_model) +end + + function compute_ice_ocean_salinity_flux!(coupled_model) # Compute salinity increment due to changes in ice thickness @@ -251,7 +257,7 @@ end # Update surface salinity flux. # Note: the Δt below is the ocean time-step, eg. # ΔS = ⋯ - ∮ Qˢ dt ≈ ⋯ - Δtₒ * Qˢ - Qˢ[i, j, 1] = Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) + Qˢ[i, j, 1] += Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) # Update previous ice thickness h⁻[i, j, 1] = hⁿ[i, j, 1] @@ -273,6 +279,8 @@ function ice_ocean_latent_heat!(coupled_model) grid = ocean.model.grid arch = architecture(grid) + # What about the latent heat removed from the ocean when ice forms? + # Is it immediately removed from the ocean? Or is it stored in the ice? launch!(arch, grid, :xy, _compute_ice_ocean_latent_heat!, Qₒ, grid, hᵢ, Tₒ, Sₒ, liquidus, ρₒ, cₒ, Δt) diff --git a/src/IceOceanModel/atmosphere_boundary_conditions.jl b/src/IceOceanModel/atmosphere_boundary_conditions.jl index 6e0c9d8f..bf73e9f0 100644 --- a/src/IceOceanModel/atmosphere_boundary_conditions.jl +++ b/src/IceOceanModel/atmosphere_boundary_conditions.jl @@ -1,18 +1,57 @@ module AtmosphericForcings +export PrescribedAtmosphere, PrescribedFluxes + +using Adapt +using Oceananigans +using Oceananigans.Utils +using Oceananigans.BoundaryConditions: getbc +using KernelAbstractions: @kernel, @index + +import IceOceanModel: compute_air_sea_fluxes! + +abstract type AbstractAtmospericForcing end + # We generally have 2 types of atmospheric forcing: Prescribed fluxes and # Prescribed atmospheric state (to treat with bulk formulae) -export PrescribedAtmosphere, PrescribedFluxes +# Prescribed fluxes can be arrays, fields, of functions. +# When functions, the signature should be +# `f(i, j, grid, clock, fields)` where `fields` are the ocean model's prognostic fields +# in case of OnyOceanModel and the coupled model's prognostic fields in case of an `IceOceanModel` +# Parameters can be implemented using callable structs that subtype `Function` +struct PrescribedFluxes{T, S, U, V} <: AbstractAtmospericForcing + heat_flux :: T # heat flux + freshwater_flux :: S # freshwater flux + zonal_stress :: U # zonal stress + meriodional_stress :: V # meriodional stress +end -abstract type AbstractAtmospericForcing end +Adapt.adapt_structure(to, f::PrescribedFluxes) = + PrescribedFluxes(Adapt.adapt(to, f.heat_flux), + Adapt.adapt(to, f.freshwater_flux), + Adapt.adapt(to, f.zonal_stress), + Adapt.adapt(to, f.meriodional_stress)) + +# Here we leverage a `getflux` function similar to the `getbc` from Oceananigans.jl to extract the fluxes, +# In this way we allow prescribed fluxes as well as relaxation fluxes +@kernel function _calculate_prescribed_fluxes!(Qˢ, Fˢ, τˣ, τʸ, fields, f::PrescribedFluxes) + i, j = @index(Global, NTuple) + @inbounds begin + Qˢ[i, j] = getflux(f.heat_flux, i, j, grid, clock, fields) + Fˢ[i, j] = getflux(f.freshwater_fluxes, i, j, grid, clock, fields) + τˣ[i, j] = getflux(f.zonal_stress, i, j, grid, clock, fields) + τʸ[i, j] = getflux(f.meriodional_stress, i, j, grid, clock, fields) + end +end -struct PrescribedAtmosphere{} <: AbstractAtmospericForcing + +struct PrescribedAtmosphere{R, H, P, W, T, Q, D, C, G} <: AbstractAtmospericForcing adiabatic_lapse_rate :: R # - atmosphere_state_height :: H # m reference_height :: H # m surface_pressure :: P # Pa - wind_speed :: W # m/s + atmosphere_velocity :: W # (m/s, m/s) air_temperature :: T # deg ᵒC air_humidity :: Q # kg/m³ air_density :: D # kg/m³ @@ -20,6 +59,8 @@ struct PrescribedAtmosphere{} <: AbstractAtmospericForcing gamma_air :: C # - end +const PrescribedAtmosphereModel = IceOceanModel{<:Any, <:Any, PrescribedAtmosphere} + # To put in ClimaOcean.jl integrating with ClimaSeaIce.jl (To modify) #= using Adapt diff --git a/src/IceOceanModel/model_utils.jl b/src/IceOceanModel/model_utils.jl new file mode 100644 index 00000000..698e114f --- /dev/null +++ b/src/IceOceanModel/model_utils.jl @@ -0,0 +1,9 @@ +using Oceananigans.Grids: architecture +using Oceananigans.Models: AbstractModel +import Oceananigans.Grids: launch! + +launch!(model::AbstractModel, args...; kwargs...) = launch!(architecture(model.grid), model.grid, args...; kwargs...) + + +@inline getflux(f::Function, i, j, grid, clock, fields) = f(i, j, grid, clock, fields) + \ No newline at end of file diff --git a/src/IceOceanModel/only_ocean_model.jl b/src/IceOceanModel/only_ocean_model.jl new file mode 100644 index 00000000..56adc510 --- /dev/null +++ b/src/IceOceanModel/only_ocean_model.jl @@ -0,0 +1,39 @@ + +##### +##### No ice-ocean fluxes in this model!! +##### + +compute_ice_ocean_salinity_flux!(::OnlyOceanModel) = nothing +ice_ocean_latent_heat!(::OnlyOceanModel) = nothing + +##### +##### Air-sea fluxes +##### + +function time_step!(coupled_model::OnlyOceanModel, Δt; callbacks=nothing) + compute_air_sea_flux!(coupled_model) + time_step!(ocean) + tick!(coupled_model.clock, Δt) + return nothing +end + +function compute_air_sea_fluxes!(coupled_model::OnlyOceanModel) + ocean = coupled_model.ocean + forcing = coupled_model.atmospheric_forcing + + (; T, S) = ocean.model.tracers + (; u, v) = ocean.model.velocities + + grid = ocean.model.grid + clock = ocean.model.clock + fields = prognostic_fields(ocean.model) + + Qˢ = T.boundary_conditions.top.condition + Fˢ = S.boundary_conditions.top.condition + τˣ = u.boundary_conditions.top.condition + τʸ = v.boundary_conditions.top.condition + + launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, grid, clock, fields, forcing) + + return nothing +end \ No newline at end of file From 74dbc06c1977fb9e2d53948f23bb2d0b60d7898f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 16:52:06 -0400 Subject: [PATCH 008/182] changes... --- src/IceOceanModel/model_utils.jl | 13 +++++++++++-- src/IceOceanModel/only_ocean_model.jl | 4 +++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/IceOceanModel/model_utils.jl b/src/IceOceanModel/model_utils.jl index 698e114f..e0f04a22 100644 --- a/src/IceOceanModel/model_utils.jl +++ b/src/IceOceanModel/model_utils.jl @@ -1,9 +1,18 @@ +using Oceananigans +using Oceananigans.Utils: Time using Oceananigans.Grids: architecture using Oceananigans.Models: AbstractModel import Oceananigans.Grids: launch! launch!(model::AbstractModel, args...; kwargs...) = launch!(architecture(model.grid), model.grid, args...; kwargs...) +@inline getflux(::Nothing, f::Function, i, j, grid, clock, fields) = f(i, j, grid, clock, fields) +@inline getflux(::Nothing, f::AbstractArray{<:Any, 2}, i, j, grid, args...) = @inbounds f[i, j] +@inline getflux(::Nothing, f::AbstractField, i, j, grid, args...) = @inbounds f[i, j, 1] +@inline getflux(::Nothing, f::FieldTimeSeries, i, j, grid, clock, args...) = @inbounds f[i, j, Time(clock.time)] -@inline getflux(f::Function, i, j, grid, clock, fields) = f(i, j, grid, clock, fields) - \ No newline at end of file +# If we have ice, do not compute fluxes! +@inline function get_flux(ice_thickness, f, i, j, args...) + h = @inbounds ice_thickness[i, j, 1] + return ifelse(h > 0, getflux(nothing, f, i, j, args...), 0) +end \ No newline at end of file diff --git a/src/IceOceanModel/only_ocean_model.jl b/src/IceOceanModel/only_ocean_model.jl index 56adc510..b67f32dc 100644 --- a/src/IceOceanModel/only_ocean_model.jl +++ b/src/IceOceanModel/only_ocean_model.jl @@ -32,8 +32,10 @@ function compute_air_sea_fluxes!(coupled_model::OnlyOceanModel) Fˢ = S.boundary_conditions.top.condition τˣ = u.boundary_conditions.top.condition τʸ = v.boundary_conditions.top.condition + + ε = coupled_model.ocean_emissivity - launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, grid, clock, fields, forcing) + launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ε, grid, clock, fields, forcing, nothing) return nothing end \ No newline at end of file From cf8a8d9bcb8bdc4fd4655285212d61b631aea1a6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:09:44 -0400 Subject: [PATCH 009/182] easy bulk formulae --- src/IceOceanModel/IceOceanModel.jl | 7 +- .../atmosphere_boundary_conditions.jl | 189 ++++++------------ src/IceOceanModel/model_utils.jl | 13 +- 3 files changed, 75 insertions(+), 134 deletions(-) diff --git a/src/IceOceanModel/IceOceanModel.jl b/src/IceOceanModel/IceOceanModel.jl index c54d7db0..468a0f0a 100644 --- a/src/IceOceanModel/IceOceanModel.jl +++ b/src/IceOceanModel/IceOceanModel.jl @@ -20,6 +20,9 @@ import Oceananigans.Simulations: reset!, initialize!, iteration import Oceananigans.TimeSteppers: time_step!, update_state!, time import Oceananigans.Utils: prettytime +const ℒₑ = 2.5e6 # J/kg Latent heat of evaporation +const σᴮ = 5.67e-8 # W/m²/K⁴ Stefan-Boltzmann constant + struct IceOceanModel{FT, I, O, F, C, G, S, PI, PC} <: AbstractModel{Nothing} clock :: C grid :: G # TODO: make it so simulation does not require this @@ -32,7 +35,6 @@ struct IceOceanModel{FT, I, O, F, C, G, S, PI, PC} <: AbstractModel{Nothing} ocean_density :: FT ocean_heat_capacity :: FT ocean_emissivity :: FT - stefan_boltzmann_constant :: FT reference_temperature :: FT end @@ -74,7 +76,6 @@ function IceOceanModel(ice, ocean; ocean_heat_capacity = 3991 ocean_emissivity = 1 reference_temperature = 273.15 - stefan_boltzmann_constant = 5.67e-8 # How would we ensure consistency? try @@ -84,7 +85,6 @@ function IceOceanModel(ice, ocean; radiation = filter(flux isa RadiativeEmission, ice.model.external_thermal_fluxes.top) |> first end - stefan_boltzmann_constant = radiation.stefan_boltzmann_constant reference_temperature = radiation.reference_temperature catch end @@ -111,7 +111,6 @@ time(coupled_model::IceOceanModel) = coupled_model.clock.time function compute_air_sea_flux!(coupled_model) ocean = coupled_model.ocean ice = coupled_model.ice - atmosphere = coupled_model.atmospheric_forcing T = ocean.model.tracers.T Nx, Ny, Nz = size(ocean.model.grid) diff --git a/src/IceOceanModel/atmosphere_boundary_conditions.jl b/src/IceOceanModel/atmosphere_boundary_conditions.jl index bf73e9f0..7a687d3e 100644 --- a/src/IceOceanModel/atmosphere_boundary_conditions.jl +++ b/src/IceOceanModel/atmosphere_boundary_conditions.jl @@ -35,23 +35,22 @@ Adapt.adapt_structure(to, f::PrescribedFluxes) = # Here we leverage a `getflux` function similar to the `getbc` from Oceananigans.jl to extract the fluxes, # In this way we allow prescribed fluxes as well as relaxation fluxes -@kernel function _calculate_prescribed_fluxes!(Qˢ, Fˢ, τˣ, τʸ, fields, f::PrescribedFluxes) +@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, grid, clock, fields, ice_thickness, f::PrescribedFluxes) i, j = @index(Global, NTuple) @inbounds begin - Qˢ[i, j] = getflux(f.heat_flux, i, j, grid, clock, fields) - Fˢ[i, j] = getflux(f.freshwater_fluxes, i, j, grid, clock, fields) - τˣ[i, j] = getflux(f.zonal_stress, i, j, grid, clock, fields) - τʸ[i, j] = getflux(f.meriodional_stress, i, j, grid, clock, fields) + Qˢ[i, j] = getflux(ice_thickness, f.heat_flux, i, j, grid, clock, fields) + Fˢ[i, j] = getflux(ice_thickness, f.freshwater_fluxes, i, j, grid, clock, fields) + τˣ[i, j] = getflux(ice_thickness, f.zonal_stress, i, j, grid, clock, fields) + τʸ[i, j] = getflux(ice_thickness, f.meriodional_stress, i, j, grid, clock, fields) end end - struct PrescribedAtmosphere{R, H, P, W, T, Q, D, C, G} <: AbstractAtmospericForcing adiabatic_lapse_rate :: R # - atmosphere_state_height :: H # m reference_height :: H # m surface_pressure :: P # Pa - atmosphere_velocity :: W # (m/s, m/s) + atmosphere_velocities :: W # (m/s, m/s) air_temperature :: T # deg ᵒC air_humidity :: Q # kg/m³ air_density :: D # kg/m³ @@ -59,113 +58,70 @@ struct PrescribedAtmosphere{R, H, P, W, T, Q, D, C, G} <: AbstractAtmospericForc gamma_air :: C # - end -const PrescribedAtmosphereModel = IceOceanModel{<:Any, <:Any, PrescribedAtmosphere} - -# To put in ClimaOcean.jl integrating with ClimaSeaIce.jl (To modify) -#= -using Adapt -using KernelAbstractions.Extras.LoopInfo: @unroll - -using Oceananigans.Utils: Time - -struct AirSeaFlux{A, R, H, P, W, T, Q, D, C, E} <: Function - adiabatic_lapse_rate :: R # - - atmosphere_state_height :: H # m - reference_height :: H # m - surface_pressure :: P # Pa - wind_speed :: W # m/s - air_temperature :: T # deg ᵒC - air_humidity :: Q # kg/m³ - air_density :: D # kg/m³ - cloud_cover_feedback :: C # - - gamma_air :: C # - - ocean_emissivity :: E # - - - AirSeaFlux{A}(adiabatic_lapse_rate::R, - atmosphere_state_height::H, - reference_height::H, - surface_pressure::P, - wind_speed::W, - air_temperature::T, - air_humidity::Q, - air_density::D, - cloud_cover_coeff::C, - gamma_air::C, - ocean_emissivity::E) where {A, R, H, P, W, T, Q, D, C, E} = - new{A, R, H, P, W, T, Q, D, C, E}(adiabatic_lapse_rate, - atmosphere_state_height, - reference_height, - surface_pressure, - wind_speed, - air_temperature, - air_humidity, - air_density, - cloud_cover_coeff, - gamma_air, - ocean_emissivity) -end - -struct HeatFlux end -struct WindStress end - -function AirSeaFlux(; +function PrescribedAtmosphere(; adiabatic_lapse_rate = 0.08, atmosphere_state_height = 10, # m reference_height = 10, # m surface_pressure = 1e5, # Pa - wind_speed, # m/s + atmosphere_velocities, # (m/s, m/s) air_temperature, # deg ᵒC air_humidity = 0.01, # kg/m³ air_density = 1.25, # kg/m³ cloud_cover_coeff = 0.8, - gamma_air = 0.01, - ocean_emissivity = 0.9, - flux_or_stress::A = HeatFlux()) where A - - return AirSeaFlux{A}(adiabatic_lapse_rate, - atmosphere_state_height, - reference_height, - surface_pressure, - wind_speed, - air_temperature, - air_humidity, - air_density, - cloud_cover_coeff, - gamma_air, - ocean_emissivity) + gamma_air = 0.01) + + return PrescribedAtmosphere(adiabatic_lapse_rate, + atmosphere_state_height, + reference_height, + surface_pressure, + atmosphere_velocities, + air_temperature, + air_humidity, + air_density, + cloud_cover_coeff, + gamma_air) end -Adapt.adapt_structure(to, f::AirSeaFlux{A}) where A = - AirSeaFlux{A}(Adapt.adapt(to, f.adiabatic_lapse_rate), - Adapt.adapt(to, f.atmosphere_state_height), - Adapt.adapt(to, f.reference_height), - Adapt.adapt(to, f.surface_pressure), - Adapt.adapt(to, f.wind_speed), - Adapt.adapt(to, f.air_temperature), - Adapt.adapt(to, f.air_humidity), - Adapt.adapt(to, f.air_density), - Adapt.adapt(to, f.cloud_cover_feedback), - Adapt.adapt(to, f.gamma_air), - Adapt.adapt(to, f.ocean_emissivity)) - -const AirSeaHeatFlux = AirSeaFlux{HeatFlux} -const AirSeaWindStress = AirSeaFlux{WindStress} - -function (f::AirSeaHeatFlux)(i, j, grid, clock, fields) +Adapt.adapt_structure(to, f::PrescribedAtmosphere) = + PrescribedAtmosphere(Adapt.adapt(to, f.adiabatic_lapse_rate), + Adapt.adapt(to, f.atmosphere_state_height), + Adapt.adapt(to, f.reference_height), + Adapt.adapt(to, f.surface_pressure), + Adapt.adapt(to, f.atmosphere_velocities), + Adapt.adapt(to, f.air_temperature), + Adapt.adapt(to, f.air_humidity), + Adapt.adapt(to, f.air_density), + Adapt.adapt(to, f.cloud_cover_feedback), + Adapt.adapt(to, f.gamma_air)) + +@inline clausius_clapeyron(FT, Tₛ) = convert(FT, 611.2) * exp(convert(FT, 17.67) * Tₛ / (Tₛ + convert(FT, 243.5))) + +# Follows MITgcm +@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, grid, clock, fields, ice_thickness, f::PrescribedAtmosphere) + + hᵀ = f.atmosphere_state_height + α = f.adiabatic_lapse_rate + uˢ, vˢ = f.atmosphere_velocities + + # These can be Values, Arrays, Functions, Fields or FieldTimeSerieses + Tₐ = getflux(f.air_temperature, i, j, grid, clock, fields) + uₐ = getflux(uˢ, i, j, grid, clock, fields) + vₐ = getflux(vˢ, i, j, grid, clock, fields) + qₐ = getflux(f.air_humidity, i, j, grid, clock, fields) + ρₐ = getflux(f.air_density, i, j, grid, clock, fields) + p₀ = getflux(f.surface_pressure, i, j, grid, clock, fields) + + s = sqrt(uₐ^2 + vₐ^2) # speed m / s + γ = f.gamma_air + + # Physical constants + σ = convert(FT, σᴮ) # W/m²/K⁴ Stefan-Boltzmann constant + ℒ = convert(FT, ℒₑ) # J/kg Latent heat of evaporation - hᵀ = f.atmosphere_state_height - α = f.adiabatic_lapse_rate - Tₐ = f.air_temperature[i, j, 1, Time(clock.time)] - uₛ = f.wind_speed[i, j, 1, Time(clock.time)] - qₐ = f.air_humidity - ρₐ = f.air_density - γ = f.gamma_air - p₀ = f.surface_pressure - FT = eltype(grid) # latent heat of evaporation - ℒ = convert(FT, 2.5e6) + ℒ = convert(FT, ℒₑ) Tₛ = fields.T[i, j, grid.Nz] T₀ = Tₐ*(1 - γ * qₐ) @@ -174,7 +130,7 @@ function (f::AirSeaHeatFlux)(i, j, grid, clock, fields) ΔT = T₀ - Tₛ + α*hᵀ # saturation vapour pressure (Pa) - eₛ = convert(FT, 611.2) * exp(convert(FT, 17.67) * Tₛ / (Tₛ + convert(FT, 243.5))) + eₛ = clausius_clapeyron(FT, Tₛ) # saturation air humidity (kg/m³) qₛ = convert(FT, 0.622) * eₛ / (p₀ - eₛ) @@ -192,21 +148,16 @@ function (f::AirSeaHeatFlux)(i, j, grid, clock, fields) L = ρₐ * uₛ * Cq * Cᵁ * Δq * ℒ # net longwave radiation (W/m²) - Rₙ = f.ocean_emissivity * convert(FT, 5.67e-8) * (Tₛ + convert(FT, 273.15))^4 * (1 - f.cloud_cover_feedback) + Rₙ = ε * σ * (Tₛ + convert(FT, 273.15))^4 * (1 - f.cloud_cover_feedback) - return H + L + Rₙ -end - -function (f::AirSeaWindStress)(i, j, grid, clock, fields) - - uₛ = f.wind_speed[i, j, 1, Time(clock.time)] - ρₐ = f.air_density - FT = eltype(grid) - - # Drag coefficient - Cᴰ = ifelse(uₛ > 25, convert(FT, 2.3e-3), convert(FT, 1.3e-3)) + @inbounds begin + Qˢ[i, j, 1] = H + L + Rₙ + Fˢ[i, j, 1] = L / ℒ + τˣ[i, j, 1] = ρₐ * uₛ * Cᵁ * uₛ + τʸ[i, j, 1] = ρₐ * uₛ * Cᵁ * vₛ + end - return ρₐ * Cᴰ * uₛ^2 + return nothing end # Follows MITgcm @@ -241,14 +192,4 @@ end @inline Γ(FT, u★, T★, q★, T₀, qₐ, f) = convert(FT, 0.41) * convert(FT, 9.80655) * f.reference_height / u★^2 * (T★ / T₀ - q★ / (1/f.gamma_air - qₐ)) -AirSeaHeatFluxBoundaryCondition(; kwargs...) = - FluxBoundaryCondition(AirSeaFlux(; flux_or_stress = HeatFlux(), kwargs...), discrete_form = true) - -AirSeaWindStressBoundaryCondition(; kwargs...) = - FluxBoundaryCondition(AirSeaFlux(; flux_or_stress = WindStress(), kwargs...), discrete_form = true) - - -=# - - end \ No newline at end of file diff --git a/src/IceOceanModel/model_utils.jl b/src/IceOceanModel/model_utils.jl index e0f04a22..f67aa4e0 100644 --- a/src/IceOceanModel/model_utils.jl +++ b/src/IceOceanModel/model_utils.jl @@ -6,13 +6,14 @@ import Oceananigans.Grids: launch! launch!(model::AbstractModel, args...; kwargs...) = launch!(architecture(model.grid), model.grid, args...; kwargs...) -@inline getflux(::Nothing, f::Function, i, j, grid, clock, fields) = f(i, j, grid, clock, fields) -@inline getflux(::Nothing, f::AbstractArray{<:Any, 2}, i, j, grid, args...) = @inbounds f[i, j] -@inline getflux(::Nothing, f::AbstractField, i, j, grid, args...) = @inbounds f[i, j, 1] -@inline getflux(::Nothing, f::FieldTimeSeries, i, j, grid, clock, args...) = @inbounds f[i, j, Time(clock.time)] +@inline getflux(f::Number, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f +@inline getflux(f::Function, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f(i, j, grid, clock, fields) +@inline getflux(f::AbstractArray{<:Any, 2}, i::Int, j::Int, grid::AbstractGrid, args...) = @inbounds f[i, j] +@inline getflux(f::AbstractField, i::Int, j::Int, grid::AbstractGrid, args...) = @inbounds f[i, j, 1] +@inline getflux(f::FieldTimeSeries, i::Int, j::Int, grid::AbstractGrid, clock, args...) = @inbounds f[i, j, Time(clock.time)] # If we have ice, do not compute fluxes! -@inline function get_flux(ice_thickness, f, i, j, args...) +@inline function get_flux(ice_thickness, f, i::Int, j::Int, grid::AbstractGrid, args...) h = @inbounds ice_thickness[i, j, 1] - return ifelse(h > 0, getflux(nothing, f, i, j, args...), 0) + return ifelse(h > 0, getflux(f, i, j, grid,args...), 0) end \ No newline at end of file From 4a65d4463f5e8d76f2ef0d754c91a33188b9c261 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:10:44 -0400 Subject: [PATCH 010/182] comment --- src/IceOceanModel/atmosphere_boundary_conditions.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/IceOceanModel/atmosphere_boundary_conditions.jl b/src/IceOceanModel/atmosphere_boundary_conditions.jl index 7a687d3e..c6238889 100644 --- a/src/IceOceanModel/atmosphere_boundary_conditions.jl +++ b/src/IceOceanModel/atmosphere_boundary_conditions.jl @@ -14,6 +14,7 @@ abstract type AbstractAtmospericForcing end # We generally have 2 types of atmospheric forcing: Prescribed fluxes and # Prescribed atmospheric state (to treat with bulk formulae) +# This implementation also allows to have a future prognostic atmospheric model # Prescribed fluxes can be arrays, fields, of functions. # When functions, the signature should be From ce19c04e0aeb4226773679f9e52a1d29c693225e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:12:46 -0400 Subject: [PATCH 011/182] more --- ..._boundary_conditions.jl => AtmosphericForcings.jl} | 2 +- src/IceOceanModel/IceOceanModel.jl | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) rename src/IceOceanModel/{atmosphere_boundary_conditions.jl => AtmosphericForcings.jl} (98%) diff --git a/src/IceOceanModel/atmosphere_boundary_conditions.jl b/src/IceOceanModel/AtmosphericForcings.jl similarity index 98% rename from src/IceOceanModel/atmosphere_boundary_conditions.jl rename to src/IceOceanModel/AtmosphericForcings.jl index c6238889..c46203f1 100644 --- a/src/IceOceanModel/atmosphere_boundary_conditions.jl +++ b/src/IceOceanModel/AtmosphericForcings.jl @@ -14,7 +14,7 @@ abstract type AbstractAtmospericForcing end # We generally have 2 types of atmospheric forcing: Prescribed fluxes and # Prescribed atmospheric state (to treat with bulk formulae) -# This implementation also allows to have a future prognostic atmospheric model +# This implementation also allows to have in future a prognostic atmospheric model # Prescribed fluxes can be arrays, fields, of functions. # When functions, the signature should be diff --git a/src/IceOceanModel/IceOceanModel.jl b/src/IceOceanModel/IceOceanModel.jl index 468a0f0a..92b79ae9 100644 --- a/src/IceOceanModel/IceOceanModel.jl +++ b/src/IceOceanModel/IceOceanModel.jl @@ -206,10 +206,13 @@ function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) end function compute_ice_ocean_flux!(coupled_model) + + # probably need to expand this compute_ice_ocean_salinity_flux!(coupled_model) ice_ocean_latent_heat!(coupled_model) -end + return nothing +end function compute_ice_ocean_salinity_flux!(coupled_model) # Compute salinity increment due to changes in ice thickness @@ -231,7 +234,6 @@ function compute_ice_ocean_salinity_flux!(coupled_model) return nothing end - @kernel function _compute_ice_ocean_salinity_flux!(ice_ocean_salinity_flux, grid, ice_thickness, @@ -365,4 +367,9 @@ function default_nan_checker(model::IceOceanModel) return nan_checker end +include("AtmosphericForcings.jl") + +using .AtmosphericForcings + + end # module From f1f02cebbb133620558b6a89717d29af0c954700 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:13:30 -0400 Subject: [PATCH 012/182] comment --- src/IceOceanModel/AtmosphericForcings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IceOceanModel/AtmosphericForcings.jl b/src/IceOceanModel/AtmosphericForcings.jl index c46203f1..43c70c17 100644 --- a/src/IceOceanModel/AtmosphericForcings.jl +++ b/src/IceOceanModel/AtmosphericForcings.jl @@ -104,7 +104,7 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = α = f.adiabatic_lapse_rate uˢ, vˢ = f.atmosphere_velocities - # These can be Values, Arrays, Functions, Fields or FieldTimeSerieses + # The atmospheric state (T, u, v, q, ρ and p) can all be Values, Arrays, Functions, Fields or FieldTimeSerieses Tₐ = getflux(f.air_temperature, i, j, grid, clock, fields) uₐ = getflux(uˢ, i, j, grid, clock, fields) vₐ = getflux(vˢ, i, j, grid, clock, fields) From 38773873e26697d431d7906fc259777f047171c9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:13:48 -0400 Subject: [PATCH 013/182] comment --- src/IceOceanModel/AtmosphericForcings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IceOceanModel/AtmosphericForcings.jl b/src/IceOceanModel/AtmosphericForcings.jl index 43c70c17..3e3e403c 100644 --- a/src/IceOceanModel/AtmosphericForcings.jl +++ b/src/IceOceanModel/AtmosphericForcings.jl @@ -59,6 +59,7 @@ struct PrescribedAtmosphere{R, H, P, W, T, Q, D, C, G} <: AbstractAtmospericForc gamma_air :: C # - end +# The atmospheric state (T, u, v, q, ρ and p) can all be Values, Arrays, Functions, Fields or FieldTimeSerieses function PrescribedAtmosphere(; adiabatic_lapse_rate = 0.08, atmosphere_state_height = 10, # m @@ -104,7 +105,6 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = α = f.adiabatic_lapse_rate uˢ, vˢ = f.atmosphere_velocities - # The atmospheric state (T, u, v, q, ρ and p) can all be Values, Arrays, Functions, Fields or FieldTimeSerieses Tₐ = getflux(f.air_temperature, i, j, grid, clock, fields) uₐ = getflux(uˢ, i, j, grid, clock, fields) vₐ = getflux(vˢ, i, j, grid, clock, fields) From 85e9139120a2a7c4133e7f18df23bea463288019 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:38:23 -0400 Subject: [PATCH 014/182] cleaning up a bit --- src/IceOceanModel/AtmosphericForcings.jl | 21 +- src/IceOceanModel/IceOceanModel.jl | 345 +----------------- .../ice_ocean_atmosphere_fluxes.jl | 188 ++++++++++ src/IceOceanModel/ice_ocean_model.jl | 125 +++++++ src/IceOceanModel/model_utils.jl | 1 + ...an_model.jl => only_ocean_model_fluxes.jl} | 10 +- 6 files changed, 338 insertions(+), 352 deletions(-) create mode 100644 src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl create mode 100644 src/IceOceanModel/ice_ocean_model.jl rename src/IceOceanModel/{only_ocean_model.jl => only_ocean_model_fluxes.jl} (79%) diff --git a/src/IceOceanModel/AtmosphericForcings.jl b/src/IceOceanModel/AtmosphericForcings.jl index 3e3e403c..7b96c144 100644 --- a/src/IceOceanModel/AtmosphericForcings.jl +++ b/src/IceOceanModel/AtmosphericForcings.jl @@ -36,10 +36,11 @@ Adapt.adapt_structure(to, f::PrescribedFluxes) = # Here we leverage a `getflux` function similar to the `getbc` from Oceananigans.jl to extract the fluxes, # In this way we allow prescribed fluxes as well as relaxation fluxes -@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, grid, clock, fields, ice_thickness, f::PrescribedFluxes) +@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, grid, clock, fields, ice_thickness, solar_insolation, f::PrescribedFluxes) i, j = @index(Global, NTuple) @inbounds begin - Qˢ[i, j] = getflux(ice_thickness, f.heat_flux, i, j, grid, clock, fields) + I₀ = solar_insolation[i, j, 1] + Qˢ[i, j] = getflux(ice_thickness, f.heat_flux, i, j, grid, clock, fields) + ε * I₀ / (ρₒ * cₒ) Fˢ[i, j] = getflux(ice_thickness, f.freshwater_fluxes, i, j, grid, clock, fields) τˣ[i, j] = getflux(ice_thickness, f.zonal_stress, i, j, grid, clock, fields) τʸ[i, j] = getflux(ice_thickness, f.meriodional_stress, i, j, grid, clock, fields) @@ -99,7 +100,7 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = @inline clausius_clapeyron(FT, Tₛ) = convert(FT, 611.2) * exp(convert(FT, 17.67) * Tₛ / (Tₛ + convert(FT, 243.5))) # Follows MITgcm -@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, grid, clock, fields, ice_thickness, f::PrescribedAtmosphere) +@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, ρₒ, cₒ, grid, clock, fields, ice_thickness, f::PrescribedAtmosphere) hᵀ = f.atmosphere_state_height α = f.adiabatic_lapse_rate @@ -111,6 +112,9 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = qₐ = getflux(f.air_humidity, i, j, grid, clock, fields) ρₐ = getflux(f.air_density, i, j, grid, clock, fields) p₀ = getflux(f.surface_pressure, i, j, grid, clock, fields) + + h = getflux(ice_thickness, i, j, grid, clock, fields) + I₀ = solar_insolation[i, j, 1] s = sqrt(uₐ^2 + vₐ^2) # speed m / s γ = f.gamma_air @@ -150,12 +154,12 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = # net longwave radiation (W/m²) Rₙ = ε * σ * (Tₛ + convert(FT, 273.15))^4 * (1 - f.cloud_cover_feedback) - + @inbounds begin - Qˢ[i, j, 1] = H + L + Rₙ - Fˢ[i, j, 1] = L / ℒ - τˣ[i, j, 1] = ρₐ * uₛ * Cᵁ * uₛ - τʸ[i, j, 1] = ρₐ * uₛ * Cᵁ * vₛ + Qˢ[i, j, 1] = ifelse(ice_thickness(H + L + Rₙ + I₀ * ε) / (ρₒ * cₒ) + # Fˢ[i, j, 1] = L / ℒ + τˣ[i, j, 1] = ρₐ * uₛ * Cᵁ * uₐ / ρₒ + τʸ[i, j, 1] = ρₐ * uₛ * Cᵁ * vₐ / ρₒ end return nothing @@ -166,7 +170,6 @@ end hᵀ = f.atmosphere_state_height zᴿ = f.reference_height λ = log(hᵀ / zᴿ) - γ = f.gamma_air Cᵀ = Cᵁ = Cq = convert(FT, 0.41) / log(zᴿ * 2) u★ = Cᵁ * uₛ diff --git a/src/IceOceanModel/IceOceanModel.jl b/src/IceOceanModel/IceOceanModel.jl index 92b79ae9..21c20bd7 100644 --- a/src/IceOceanModel/IceOceanModel.jl +++ b/src/IceOceanModel/IceOceanModel.jl @@ -23,342 +23,12 @@ import Oceananigans.Utils: prettytime const ℒₑ = 2.5e6 # J/kg Latent heat of evaporation const σᴮ = 5.67e-8 # W/m²/K⁴ Stefan-Boltzmann constant -struct IceOceanModel{FT, I, O, F, C, G, S, PI, PC} <: AbstractModel{Nothing} - clock :: C - grid :: G # TODO: make it so simulation does not require this - ice :: I - previous_ice_thickness :: PI - previous_ice_concentration :: PC - ocean :: O - atmospheric_forcing :: F - solar_insolation :: S - ocean_density :: FT - ocean_heat_capacity :: FT - ocean_emissivity :: FT - reference_temperature :: FT -end - -Base.summary(::IOM) = "IceOceanModel" -prettytime(model::IOM) = prettytime(model.clock.time) -iteration(model::IOM) = model.clock.iteration -timestepper(::IOM) = nothing -reset!(::IOM) = nothing -initialize!(::IOM) = nothing -default_included_properties(::IOM) = tuple() -update_state!(::IOM) = nothing -prognostic_fields(cm::IOM) = nothing -fields(::IOM) = NamedTuple() - - -default_clock(FT) = Clock{FT}(0, 0, 1) - -const IOM = IceOceanModel - -# "Ocean only" -const OceanOnlyModel = IceOceanModel{<:Any, Nothing} - -OceanOnlyModel(ocean; atmospheric_forcing = nothing, clock = default_clock(eltype(ocean.model))) = - IceOceanModel(nothing, ocean; atmospheric_forcing, clock) - -function IceOceanModel(ice, ocean; - atmospheric_forcing = nothing, - clock = default_clock(eltype(ocean.model))) - - previous_ice_thickness = deepcopy(ice.model.ice_thickness) - previous_ice_concentration = deepcopy(ice.model.ice_concentration) - - grid = ocean.model.grid - ice_ocean_thermal_flux = Field{Center, Center, Nothing}(grid) - ice_ocean_salt_flux = Field{Center, Center, Nothing}(grid) - solar_insolation = Field{Center, Center, Nothing}(grid) - - ocean_density = 1024 - ocean_heat_capacity = 3991 - ocean_emissivity = 1 - reference_temperature = 273.15 - - # How would we ensure consistency? - try - if ice.model.external_thermal_fluxes.top isa RadiativeEmission - radiation = ice.model.external_thermal_fluxes.top - else - radiation = filter(flux isa RadiativeEmission, ice.model.external_thermal_fluxes.top) |> first - end - - reference_temperature = radiation.reference_temperature - catch - end - - FT = eltype(ocean.model.grid) - - return IceOceanModel(clock, - ocean.model.grid, - ice, - previous_ice_thickness, - previous_ice_concentration, - ocean, - solar_insolation, - atmospheric_forcing, - convert(FT, ocean_density), - convert(FT, ocean_heat_capacity), - convert(FT, ocean_emissivity), - convert(FT, stefan_boltzmann_constant), - convert(FT, reference_temperature)) -end - -time(coupled_model::IceOceanModel) = coupled_model.clock.time - -function compute_air_sea_flux!(coupled_model) - ocean = coupled_model.ocean - ice = coupled_model.ice - - T = ocean.model.tracers.T - Nx, Ny, Nz = size(ocean.model.grid) - - grid = ocean.model.grid - arch = architecture(grid) - - σ = coupled_model.stefan_boltzmann_constant - ρₒ = coupled_model.ocean_density - cₒ = coupled_model.ocean_heat_capacity - Tᵣ = coupled_model.reference_temperature - Qᵀ = T.boundary_conditions.top.condition - Tₒ = ocean.model.tracers.T - hᵢ = ice.model.ice_thickness - ℵᵢ = ice.model.ice_concentration - I₀ = coupled_model.solar_insolation - - launch!(ocean, :xy, _compute_air_sea_flux!, - Qᵀ, grid, Tₒ, hᵢ, ℵᵢ, I₀, - σ, ρₒ, cₒ, Tᵣ) -end - -@kernel function _compute_air_sea_flux!(temperature_flux, - grid, - ocean_temperature, - ice_thickness, - ice_concentration, - solar_insolation, - σ, ρₒ, cₒ, Tᵣ) - - i, j = @index(Global, NTuple) - - Nz = size(grid, 3) - - @inbounds begin - T₀ = ocean_temperature[i, j, Nz] # at the surface - h = ice_thickness[i, j, 1] - ℵ = ice_concentration[i, j, 1] - I₀ = solar_insolation[i, j, 1] - end - - # Radiation model - ϵ = 1 # ocean emissivity - ΣQᵀ = ϵ * σ * (T₀ + Tᵣ)^4 / (ρₒ * cₒ) - - # Also add solar insolation - ΣQᵀ += I₀ / (ρₒ * cₒ) - - # Set the surface flux only if ice-free or the moment - Qᵀ = temperature_flux - - # @inbounds Qᵀ[i, j, 1] = 0 #(1 - ℵ) * ΣQᵀ -end - -function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) - ocean = coupled_model.ocean - ice = coupled_model.ice - ice.Δt = Δt - ocean.Δt = Δt - - fill_halo_regions!(h) - - # Initialization - if coupled_model.clock.iteration == 0 - h⁻ = coupled_model.previous_ice_thickness - hⁿ = coupled_model.ice.model.ice_thickness - parent(h⁻) .= parent(hⁿ) - end - - time_step!(ice) - - # TODO: put this in update_state! - # Air-sea and Air-ice fluxes substitute the previous values - # while ice-ocean fluxes are additive - compute_air_sea_flux!(coupled_model) - compute_ice_ocean_flux!(coupled_model) - #compute_solar_insolation!(coupled_model) - - time_step!(ocean) - - # TODO: - # - Store fractional ice-free / ice-covered _time_ for more - # accurate flux computation? - # - Or, input "excess heat flux" into ocean after the ice melts - # - Currently, non-conservative for heat due bc we don't account for excess - - # TODO after ice time-step: - # - Adjust ocean temperature if the ice completely melts? - - tick!(coupled_model.clock, Δt) - - return nothing -end - -function compute_ice_ocean_flux!(coupled_model) - - # probably need to expand this - compute_ice_ocean_salinity_flux!(coupled_model) - ice_ocean_latent_heat!(coupled_model) - - return nothing -end - -function compute_ice_ocean_salinity_flux!(coupled_model) - # Compute salinity increment due to changes in ice thickness - - ice = coupled_model.ice - ocean = coupled_model.ocean - grid = ocean.model.grid - arch = architecture(grid) - Qˢ = ocean.model.tracers.S.boundary_conditions.top.condition - Sₒ = ocean.model.tracers.S - Sᵢ = ice.model.ice_salinity - Δt = ocean.Δt - hⁿ = ice.model.ice_thickness - h⁻ = coupled_model.previous_ice_thickness - - launch!(arch, grid, :xy, _compute_ice_ocean_salinity_flux!, - Qˢ, grid, hⁿ, h⁻, Sᵢ, Sₒ, Δt) - - return nothing -end - -@kernel function _compute_ice_ocean_salinity_flux!(ice_ocean_salinity_flux, - grid, - ice_thickness, - previous_ice_thickness, - ice_salinity, - ocean_salinity, - Δt) - i, j = @index(Global, NTuple) - - Nz = size(grid, 3) - - hⁿ = ice_thickness - h⁻ = previous_ice_thickness - Qˢ = ice_ocean_salinity_flux - Sᵢ = ice_salinity - Sₒ = ocean_salinity - - @inbounds begin - # Thickness of surface grid cell - Δh = hⁿ[i, j, 1] - h⁻[i, j, 1] - - # Update surface salinity flux. - # Note: the Δt below is the ocean time-step, eg. - # ΔS = ⋯ - ∮ Qˢ dt ≈ ⋯ - Δtₒ * Qˢ - Qˢ[i, j, 1] += Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) - - # Update previous ice thickness - h⁻[i, j, 1] = hⁿ[i, j, 1] - end -end - -function ice_ocean_latent_heat!(coupled_model) - ocean = coupled_model.ocean - ice = coupled_model.ice - ρₒ = coupled_model.ocean_density - cₒ = coupled_model.ocean_heat_capacity - Qₒ = ice.model.external_thermal_fluxes.bottom - Tₒ = ocean.model.tracers.T - Sₒ = ocean.model.tracers.S - Δt = ocean.Δt - hᵢ = ice.model.ice_thickness - - liquidus = ice.model.phase_transitions.liquidus - grid = ocean.model.grid - arch = architecture(grid) - - # What about the latent heat removed from the ocean when ice forms? - # Is it immediately removed from the ocean? Or is it stored in the ice? - launch!(arch, grid, :xy, _compute_ice_ocean_latent_heat!, - Qₒ, grid, hᵢ, Tₒ, Sₒ, liquidus, ρₒ, cₒ, Δt) - - return nothing -end - -@kernel function _compute_ice_ocean_latent_heat!(latent_heat, - grid, - ice_thickness, - ocean_temperature, - ocean_salinity, - liquidus, - ρₒ, cₒ, Δt) - - i, j = @index(Global, NTuple) - - Nz = size(grid, 3) - Qₒ = latent_heat - hᵢ = ice_thickness - Tₒ = ocean_temperature - Sₒ = ocean_salinity - - δQ = zero(grid) - icy_cell = @inbounds hᵢ[i, j, 1] > 0 # make ice bath approximation then - - @unroll for k = Nz:-1:1 - @inbounds begin - # Various quantities - Δz = Δzᶜᶜᶜ(i, j, k, grid) - Tᴺ = Tₒ[i, j, k] - Sᴺ = Sₒ[i, j, k] - end - - # Melting / freezing temperature at the surface of the ocean - Tₘ = melting_temperature(liquidus, Sᴺ) - - # Conditions for non-zero ice-ocean flux: - # - the ocean is below the freezing temperature, causing formation of ice. - freezing = Tᴺ < Tₘ - - # - We are at the surface and the cell is covered by ice. - icy_surface_cell = (k == Nz) & icy_cell - - # When there is a non-zero ice-ocean flux, we will instantaneously adjust the - # temperature of the grid cells accordingly. - adjust_temperature = freezing | icy_surface_cell - - # Compute change in ocean thermal energy. - # - # - When Tᴺ < Tₘ, we heat the ocean back to melting temperature by extracting heat from the ice, - # assuming that the heat flux (which is carried by nascent ice crystals called frazil ice) floats - # instantaneously to the surface. - # - # - When Tᴺ > Tₘ and we are in a surface cell covered by ice, we assume equilibrium - # and cool the ocean by injecting excess heat into the ice. - # - δEₒ = adjust_temperature * ρₒ * cₒ * (Tₘ - Tᴺ) - - # Perform temperature adjustment - @inline Tₒ[i, j, k] = ifelse(adjust_temperature, Tₘ, Tᴺ) - - # Compute the heat flux from ocean into ice. - # - # A positive value δQ > 0 implies that the ocean is cooled; ie heat - # is fluxing upwards, into the ice. This occurs when applying the - # ice bath equilibrium condition to cool down a warm ocean (δEₒ < 0). - # - # A negative value δQ < 0 implies that heat is fluxed from the ice into - # the ocean, cooling the ice and heating the ocean (δEₒ > 0). This occurs when - # frazil ice is formed within the ocean. - - δQ -= δEₒ * Δz / Δt - end +include("ice_ocean_model.jl") +include("ice_ocean_atmosphere_fluxes.jl") +include("only_ocean_model_fluxes.jl") +include("AtmosphericForcings.jl") - # Store ice-ocean flux - @inbounds Qₒ[i, j, 1] = δQ -end +using .AtmosphericForcings # Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). function default_nan_checker(model::IceOceanModel) @@ -367,9 +37,4 @@ function default_nan_checker(model::IceOceanModel) return nan_checker end -include("AtmosphericForcings.jl") - -using .AtmosphericForcings - - end # module diff --git a/src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl b/src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl new file mode 100644 index 00000000..f575af67 --- /dev/null +++ b/src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl @@ -0,0 +1,188 @@ + +# If there is no atmosphere, do not compute fluxes! (this model has the ocean component which +# will handle the top boundary_conditions, for example if we want to impose a value BC) +compute_air_sea_flux!(coupled_model::NoAtmosphereModel) = nothing + +function compute_air_sea_flux!(coupled_model) + ocean = coupled_model.ocean + forcing = coupled_model.atmospheric_forcing + + (; T, S) = ocean.model.tracers + (; u, v) = ocean.model.velocities + + grid = ocean.model.grid + clock = ocean.model.clock + fields = prognostic_fields(ocean.model) + + Qˢ = T.boundary_conditions.top.condition + Fˢ = S.boundary_conditions.top.condition + τˣ = u.boundary_conditions.top.condition + τʸ = v.boundary_conditions.top.condition + + ε = coupled_model.ocean_emissivity + ρₒ = coupled_model.ocean_density + cₒ = coupled_model.ocean_heat_capacity + I₀ = coupled_model.solar_insolation + + ice_thickness = coupled_model.ice.model.ice_thickness + + launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, I₀, + grid, clock, fields, forcing, ice_thickness) + + return nothing +end + +function compute_ice_ocean_flux!(coupled_model) + + # probably need to expand this + compute_ice_ocean_salinity_flux!(coupled_model) + ice_ocean_latent_heat!(coupled_model) + + return nothing +end + +function compute_ice_ocean_salinity_flux!(coupled_model) + # Compute salinity increment due to changes in ice thickness + + ice = coupled_model.ice + ocean = coupled_model.ocean + grid = ocean.model.grid + arch = architecture(grid) + Qˢ = ocean.model.tracers.S.boundary_conditions.top.condition + Sₒ = ocean.model.tracers.S + Sᵢ = ice.model.ice_salinity + Δt = ocean.Δt + hⁿ = ice.model.ice_thickness + h⁻ = coupled_model.previous_ice_thickness + + launch!(arch, grid, :xy, _compute_ice_ocean_salinity_flux!, + Qˢ, grid, hⁿ, h⁻, Sᵢ, Sₒ, Δt) + + return nothing +end + +@kernel function _compute_ice_ocean_salinity_flux!(ice_ocean_salinity_flux, + grid, + ice_thickness, + previous_ice_thickness, + ice_salinity, + ocean_salinity, + Δt) + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + + hⁿ = ice_thickness + h⁻ = previous_ice_thickness + Qˢ = ice_ocean_salinity_flux + Sᵢ = ice_salinity + Sₒ = ocean_salinity + + @inbounds begin + # Thickness of surface grid cell + Δh = hⁿ[i, j, 1] - h⁻[i, j, 1] + + # Update surface salinity flux. + # Note: the Δt below is the ocean time-step, eg. + # ΔS = ⋯ - ∮ Qˢ dt ≈ ⋯ - Δtₒ * Qˢ + Qˢ[i, j, 1] += Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) + + # Update previous ice thickness + h⁻[i, j, 1] = hⁿ[i, j, 1] + end +end + +function ice_ocean_latent_heat!(coupled_model) + ocean = coupled_model.ocean + ice = coupled_model.ice + ρₒ = coupled_model.ocean_density + cₒ = coupled_model.ocean_heat_capacity + Qₒ = ice.model.external_thermal_fluxes.bottom + Tₒ = ocean.model.tracers.T + Sₒ = ocean.model.tracers.S + Δt = ocean.Δt + hᵢ = ice.model.ice_thickness + + liquidus = ice.model.phase_transitions.liquidus + grid = ocean.model.grid + arch = architecture(grid) + + # What about the latent heat removed from the ocean when ice forms? + # Is it immediately removed from the ocean? Or is it stored in the ice? + launch!(arch, grid, :xy, _compute_ice_ocean_latent_heat!, + Qₒ, grid, hᵢ, Tₒ, Sₒ, liquidus, ρₒ, cₒ, Δt) + + return nothing +end + +@kernel function _compute_ice_ocean_latent_heat!(latent_heat, + grid, + ice_thickness, + ocean_temperature, + ocean_salinity, + liquidus, + ρₒ, cₒ, Δt) + + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + Qₒ = latent_heat + hᵢ = ice_thickness + Tₒ = ocean_temperature + Sₒ = ocean_salinity + + δQ = zero(grid) + icy_cell = @inbounds hᵢ[i, j, 1] > 0 # make ice bath approximation then + + @unroll for k = Nz:-1:1 + @inbounds begin + # Various quantities + Δz = Δzᶜᶜᶜ(i, j, k, grid) + Tᴺ = Tₒ[i, j, k] + Sᴺ = Sₒ[i, j, k] + end + + # Melting / freezing temperature at the surface of the ocean + Tₘ = melting_temperature(liquidus, Sᴺ) + + # Conditions for non-zero ice-ocean flux: + # - the ocean is below the freezing temperature, causing formation of ice. + freezing = Tᴺ < Tₘ + + # - We are at the surface and the cell is covered by ice. + icy_surface_cell = (k == Nz) & icy_cell + + # When there is a non-zero ice-ocean flux, we will instantaneously adjust the + # temperature of the grid cells accordingly. + adjust_temperature = freezing | icy_surface_cell + + # Compute change in ocean thermal energy. + # + # - When Tᴺ < Tₘ, we heat the ocean back to melting temperature by extracting heat from the ice, + # assuming that the heat flux (which is carried by nascent ice crystals called frazil ice) floats + # instantaneously to the surface. + # + # - When Tᴺ > Tₘ and we are in a surface cell covered by ice, we assume equilibrium + # and cool the ocean by injecting excess heat into the ice. + # + δEₒ = adjust_temperature * ρₒ * cₒ * (Tₘ - Tᴺ) + + # Perform temperature adjustment + @inline Tₒ[i, j, k] = ifelse(adjust_temperature, Tₘ, Tᴺ) + + # Compute the heat flux from ocean into ice. + # + # A positive value δQ > 0 implies that the ocean is cooled; ie heat + # is fluxing upwards, into the ice. This occurs when applying the + # ice bath equilibrium condition to cool down a warm ocean (δEₒ < 0). + # + # A negative value δQ < 0 implies that heat is fluxed from the ice into + # the ocean, cooling the ice and heating the ocean (δEₒ > 0). This occurs when + # frazil ice is formed within the ocean. + + δQ -= δEₒ * Δz / Δt + end + + # Store ice-ocean flux + @inbounds Qₒ[i, j, 1] = δQ +end diff --git a/src/IceOceanModel/ice_ocean_model.jl b/src/IceOceanModel/ice_ocean_model.jl new file mode 100644 index 00000000..49733d4c --- /dev/null +++ b/src/IceOceanModel/ice_ocean_model.jl @@ -0,0 +1,125 @@ +struct IceOceanModel{FT, I, O, F, C, G, S, PI, PC} <: AbstractModel{Nothing} + clock :: C + grid :: G # TODO: make it so simulation does not require this + ice :: I + previous_ice_thickness :: PI + previous_ice_concentration :: PC + ocean :: O + atmospheric_forcing :: F + solar_insolation :: S + ocean_density :: FT + ocean_heat_capacity :: FT + ocean_emissivity :: FT + reference_temperature :: FT +end + +Base.summary(::IOM) = "IceOceanModel" +prettytime(model::IOM) = prettytime(model.clock.time) +iteration(model::IOM) = model.clock.iteration +timestepper(::IOM) = nothing +reset!(::IOM) = nothing +initialize!(::IOM) = nothing +default_included_properties(::IOM) = tuple() +update_state!(::IOM) = nothing +prognostic_fields(cm::IOM) = nothing +fields(::IOM) = NamedTuple() + + +default_clock(FT) = Clock{FT}(0, 0, 1) + +const IOM = IceOceanModel + +# "Ocean only" +const OceanOnlyModel = IceOceanModel{<:Any, Nothing} +const NoAtmosphereModel = IceOceanModel{<:Any, <:Any, Nothing} + +OceanOnlyModel(ocean; atmospheric_forcing = nothing, clock = default_clock(eltype(ocean.model))) = + IceOceanModel(nothing, ocean; atmospheric_forcing, clock) + +function IceOceanModel(ice, ocean; + atmospheric_forcing = nothing, + clock = default_clock(eltype(ocean.model))) + + previous_ice_thickness = deepcopy(ice.model.ice_thickness) + previous_ice_concentration = deepcopy(ice.model.ice_concentration) + + grid = ocean.model.grid + ice_ocean_thermal_flux = Field{Center, Center, Nothing}(grid) + ice_ocean_salt_flux = Field{Center, Center, Nothing}(grid) + solar_insolation = Field{Center, Center, Nothing}(grid) + + ocean_density = 1024 + ocean_heat_capacity = 3991 + ocean_emissivity = 1 + reference_temperature = 273.15 + + # How would we ensure consistency? + try + if ice.model.external_thermal_fluxes.top isa RadiativeEmission + radiation = ice.model.external_thermal_fluxes.top + else + radiation = filter(flux isa RadiativeEmission, ice.model.external_thermal_fluxes.top) |> first + end + + reference_temperature = radiation.reference_temperature + catch + end + + FT = eltype(ocean.model.grid) + + return IceOceanModel(clock, + ocean.model.grid, + ice, + previous_ice_thickness, + previous_ice_concentration, + ocean, + solar_insolation, + atmospheric_forcing, + convert(FT, ocean_density), + convert(FT, ocean_heat_capacity), + convert(FT, ocean_emissivity), + convert(FT, stefan_boltzmann_constant), + convert(FT, reference_temperature)) +end + +time(coupled_model::IceOceanModel) = coupled_model.clock.time + +function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) + ocean = coupled_model.ocean + ice = coupled_model.ice + ice.Δt = Δt + ocean.Δt = Δt + + fill_halo_regions!(h) + + # Initialization + if coupled_model.clock.iteration == 0 + h⁻ = coupled_model.previous_ice_thickness + hⁿ = coupled_model.ice.model.ice_thickness + parent(h⁻) .= parent(hⁿ) + end + + time_step!(ice) + + # TODO: put this in update_state! + # Air-sea and Air-ice fluxes substitute the previous values + # while ice-ocean fluxes are additive + compute_air_sea_flux!(coupled_model) + compute_ice_ocean_flux!(coupled_model) + #compute_solar_insolation!(coupled_model) + + time_step!(ocean) + + # TODO: + # - Store fractional ice-free / ice-covered _time_ for more + # accurate flux computation? + # - Or, input "excess heat flux" into ocean after the ice melts + # - Currently, non-conservative for heat due bc we don't account for excess + + # TODO after ice time-step: + # - Adjust ocean temperature if the ice completely melts? + + tick!(coupled_model.clock, Δt) + + return nothing +end diff --git a/src/IceOceanModel/model_utils.jl b/src/IceOceanModel/model_utils.jl index f67aa4e0..826e6b64 100644 --- a/src/IceOceanModel/model_utils.jl +++ b/src/IceOceanModel/model_utils.jl @@ -6,6 +6,7 @@ import Oceananigans.Grids: launch! launch!(model::AbstractModel, args...; kwargs...) = launch!(architecture(model.grid), model.grid, args...; kwargs...) +@inline getflux(f::Nothing, i::Int, j::Int, grid::AbstractGrid, clock, fields) = nothing @inline getflux(f::Number, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f @inline getflux(f::Function, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f(i, j, grid, clock, fields) @inline getflux(f::AbstractArray{<:Any, 2}, i::Int, j::Int, grid::AbstractGrid, args...) = @inbounds f[i, j] diff --git a/src/IceOceanModel/only_ocean_model.jl b/src/IceOceanModel/only_ocean_model_fluxes.jl similarity index 79% rename from src/IceOceanModel/only_ocean_model.jl rename to src/IceOceanModel/only_ocean_model_fluxes.jl index b67f32dc..b90a7426 100644 --- a/src/IceOceanModel/only_ocean_model.jl +++ b/src/IceOceanModel/only_ocean_model_fluxes.jl @@ -33,9 +33,13 @@ function compute_air_sea_fluxes!(coupled_model::OnlyOceanModel) τˣ = u.boundary_conditions.top.condition τʸ = v.boundary_conditions.top.condition - ε = coupled_model.ocean_emissivity - - launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ε, grid, clock, fields, forcing, nothing) + ε = coupled_model.ocean_emissivity + ρₒ = coupled_model.ocean_density + cₒ = coupled_model.ocean_heat_capacity + I₀ = coupled_model.solar_insolation + + launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, Iₒ, + grid, clock, fields, forcing, nothing) return nothing end \ No newline at end of file From 8c468260e3c5716808ab021e4ffec8a89ea9db48 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:44:05 -0400 Subject: [PATCH 015/182] air_ice fluxes? --- src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl | 3 +++ src/IceOceanModel/ice_ocean_model.jl | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl b/src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl index f575af67..8c22b866 100644 --- a/src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl +++ b/src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl @@ -3,6 +3,9 @@ # will handle the top boundary_conditions, for example if we want to impose a value BC) compute_air_sea_flux!(coupled_model::NoAtmosphereModel) = nothing +# Is this taken care of inside the ice model? Probably not because it is better to couple here than inside +compute_air_ice_flux!(coupled_model) = nothing + function compute_air_sea_flux!(coupled_model) ocean = coupled_model.ocean forcing = coupled_model.atmospheric_forcing diff --git a/src/IceOceanModel/ice_ocean_model.jl b/src/IceOceanModel/ice_ocean_model.jl index 49733d4c..1669b85c 100644 --- a/src/IceOceanModel/ice_ocean_model.jl +++ b/src/IceOceanModel/ice_ocean_model.jl @@ -105,8 +105,8 @@ function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) # Air-sea and Air-ice fluxes substitute the previous values # while ice-ocean fluxes are additive compute_air_sea_flux!(coupled_model) + compute_air_ice_flux!(coupled_model) # TODO: we need to implement this, not sure how compute_ice_ocean_flux!(coupled_model) - #compute_solar_insolation!(coupled_model) time_step!(ocean) From 1250d9122e1019eca3a8b624f1060e5546f30b7a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:45:11 -0400 Subject: [PATCH 016/182] comment --- src/IceOceanModel/AtmosphericForcings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IceOceanModel/AtmosphericForcings.jl b/src/IceOceanModel/AtmosphericForcings.jl index 7b96c144..3653209c 100644 --- a/src/IceOceanModel/AtmosphericForcings.jl +++ b/src/IceOceanModel/AtmosphericForcings.jl @@ -99,7 +99,7 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = @inline clausius_clapeyron(FT, Tₛ) = convert(FT, 611.2) * exp(convert(FT, 17.67) * Tₛ / (Tₛ + convert(FT, 243.5))) -# Follows MITgcm +# Follows MITgcm, this is kind of a Placeholder for now. I ll check the literature for a correct parameterization @kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, ρₒ, cₒ, grid, clock, fields, ice_thickness, f::PrescribedAtmosphere) hᵀ = f.atmosphere_state_height From 473d73cc85c3ed47504ae7aee3ae346c16582d99 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 17:58:02 -0400 Subject: [PATCH 017/182] comment --- src/IceOceanModel/AtmosphericForcings.jl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/IceOceanModel/AtmosphericForcings.jl b/src/IceOceanModel/AtmosphericForcings.jl index 3653209c..c3eb2dbb 100644 --- a/src/IceOceanModel/AtmosphericForcings.jl +++ b/src/IceOceanModel/AtmosphericForcings.jl @@ -60,7 +60,7 @@ struct PrescribedAtmosphere{R, H, P, W, T, Q, D, C, G} <: AbstractAtmospericForc gamma_air :: C # - end -# The atmospheric state (T, u, v, q, ρ and p) can all be Values, Arrays, Functions, Fields or FieldTimeSerieses +# The atmospheric state (T, u, v, q, ρ and p) can be composed of Values, Arrays, Functions, Fields or FieldTimeSerieses function PrescribedAtmosphere(; adiabatic_lapse_rate = 0.08, atmosphere_state_height = 10, # m @@ -114,6 +114,8 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = p₀ = getflux(f.surface_pressure, i, j, grid, clock, fields) h = getflux(ice_thickness, i, j, grid, clock, fields) + ice_cell = (h == nothing) | (h > 0) + I₀ = solar_insolation[i, j, 1] s = sqrt(uₐ^2 + vₐ^2) # speed m / s @@ -156,10 +158,10 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = Rₙ = ε * σ * (Tₛ + convert(FT, 273.15))^4 * (1 - f.cloud_cover_feedback) @inbounds begin - Qˢ[i, j, 1] = ifelse(ice_thickness(H + L + Rₙ + I₀ * ε) / (ρₒ * cₒ) + Qˢ[i, j, 1] = ifelse(ice_cell, zero(grid), (H + L + Rₙ + I₀ * ε) / (ρₒ * cₒ)) # Fˢ[i, j, 1] = L / ℒ - τˣ[i, j, 1] = ρₐ * uₛ * Cᵁ * uₐ / ρₒ - τʸ[i, j, 1] = ρₐ * uₛ * Cᵁ * vₐ / ρₒ + τˣ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * uₛ * Cᵁ * uₐ / ρₒ) + τʸ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * uₛ * Cᵁ * vₐ / ρₒ) end return nothing From 8f7e13d69a34c39bc8ea5c839a878af7e38ec855 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 18:04:00 -0400 Subject: [PATCH 018/182] small change --- src/IceOceanModel/AtmosphericForcings.jl | 28 +++++++++++------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/IceOceanModel/AtmosphericForcings.jl b/src/IceOceanModel/AtmosphericForcings.jl index c3eb2dbb..206a3a4e 100644 --- a/src/IceOceanModel/AtmosphericForcings.jl +++ b/src/IceOceanModel/AtmosphericForcings.jl @@ -116,19 +116,16 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = h = getflux(ice_thickness, i, j, grid, clock, fields) ice_cell = (h == nothing) | (h > 0) - I₀ = solar_insolation[i, j, 1] + @inbounds I₀ = solar_insolation[i, j, 1] + + FT = eltype(grid) - s = sqrt(uₐ^2 + vₐ^2) # speed m / s + speed = sqrt(uₐ^2 + vₐ^2) # speed m / s γ = f.gamma_air # Physical constants σ = convert(FT, σᴮ) # W/m²/K⁴ Stefan-Boltzmann constant ℒ = convert(FT, ℒₑ) # J/kg Latent heat of evaporation - - FT = eltype(grid) - - # latent heat of evaporation - ℒ = convert(FT, ℒₑ) Tₛ = fields.T[i, j, grid.Nz] T₀ = Tₐ*(1 - γ * qₐ) @@ -149,10 +146,10 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = Cᵀ, Cᵁ, Cq = turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) # sensible heat flux (W/m²) - H = ρₐ * uₛ * Cᵀ * Cᵁ * ΔT + H = ρₐ * speed * Cᵀ * Cᵁ * ΔT # latent heat flux (W/m²) - L = ρₐ * uₛ * Cq * Cᵁ * Δq * ℒ + L = ρₐ * speed * Cq * Cᵁ * Δq * ℒ # net longwave radiation (W/m²) Rₙ = ε * σ * (Tₛ + convert(FT, 273.15))^4 * (1 - f.cloud_cover_feedback) @@ -160,20 +157,21 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = @inbounds begin Qˢ[i, j, 1] = ifelse(ice_cell, zero(grid), (H + L + Rₙ + I₀ * ε) / (ρₒ * cₒ)) # Fˢ[i, j, 1] = L / ℒ - τˣ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * uₛ * Cᵁ * uₐ / ρₒ) - τʸ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * uₛ * Cᵁ * vₐ / ρₒ) + τˣ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * speed * Cᵁ * uₐ / ρₒ) + τʸ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * speed * Cᵁ * vₐ / ρₒ) end return nothing end -# Follows MITgcm +# Follows MITgcm (https://mitgcm.readthedocs.io/en/latest/phys_pkgs/bulk_force.html) @inline function turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) hᵀ = f.atmosphere_state_height zᴿ = f.reference_height λ = log(hᵀ / zᴿ) + κ = convert(FT, 0.4) # von Karman constant - Cᵀ = Cᵁ = Cq = convert(FT, 0.41) / log(zᴿ * 2) + Cᵀ = Cᵁ = Cq = κ / log(zᴿ * 2) u★ = Cᵁ * uₛ T★ = Cᵀ * ΔT q★ = Cq * Δq @@ -185,8 +183,8 @@ end ψˢ = ifelse(G > 0, -5G, 2 * log((1 + χ^2) / 2)) ψᵐ = ifelse(G > 0, -5G, 2 * log((1 + χ) / 2) + ψˢ / 2 - 2 * atan(χ) + convert(FT, π/2)) - Cᵁ = Cᵁ / (1 + Cᵁ * (λ - ψᵐ) / convert(FT, 0.41)) - Cᵀ = Cᵀ / (1 + Cᵀ * (λ - ψˢ) / convert(FT, 0.41)) + Cᵁ = Cᵁ / (1 + Cᵁ * (λ - ψᵐ) / κ) + Cᵀ = Cᵀ / (1 + Cᵀ * (λ - ψˢ) / κ) u★ = Cᵁ * uₛ T★ = Cᵀ * ΔT q★ = Cq * Δq From 262ca98e70bf9e43ee8f190bd002a87817361366 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 18:04:55 -0400 Subject: [PATCH 019/182] placeholder --- src/IceOceanModel/AtmosphericForcings.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/IceOceanModel/AtmosphericForcings.jl b/src/IceOceanModel/AtmosphericForcings.jl index 206a3a4e..ead79916 100644 --- a/src/IceOceanModel/AtmosphericForcings.jl +++ b/src/IceOceanModel/AtmosphericForcings.jl @@ -164,6 +164,9 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = return nothing end +@inline turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) = (1e-3, 1e-3, 1e-3) + +#= # Follows MITgcm (https://mitgcm.readthedocs.io/en/latest/phys_pkgs/bulk_force.html) @inline function turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) hᵀ = f.atmosphere_state_height @@ -192,6 +195,7 @@ end return Cᵀ, Cᵁ, Cq end +=# @inline Γ(FT, u★, T★, q★, T₀, qₐ, f) = convert(FT, 0.41) * convert(FT, 9.80655) * f.reference_height / u★^2 * (T★ / T₀ - q★ / (1/f.gamma_air - qₐ)) From baada0aab7d41cb85008df3073edfeb0b440501f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 6 Oct 2023 18:21:40 -0400 Subject: [PATCH 020/182] update field time series --- src/IceOceanModel/ice_ocean_model.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/IceOceanModel/ice_ocean_model.jl b/src/IceOceanModel/ice_ocean_model.jl index 1669b85c..1527691c 100644 --- a/src/IceOceanModel/ice_ocean_model.jl +++ b/src/IceOceanModel/ice_ocean_model.jl @@ -1,3 +1,5 @@ +using Oceananigans.OutputReaders: update_model_field_time_series! + struct IceOceanModel{FT, I, O, F, C, G, S, PI, PC} <: AbstractModel{Nothing} clock :: C grid :: G # TODO: make it so simulation does not require this @@ -104,6 +106,7 @@ function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) # TODO: put this in update_state! # Air-sea and Air-ice fluxes substitute the previous values # while ice-ocean fluxes are additive + update_model_field_time_series!(coupled_model.atmospheric_forcing) compute_air_sea_flux!(coupled_model) compute_air_ice_flux!(coupled_model) # TODO: we need to implement this, not sure how compute_ice_ocean_flux!(coupled_model) From d80a9f98435ec532637aebed47c88727895a9050 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 11 Oct 2023 09:09:53 -0600 Subject: [PATCH 021/182] Change IceOcean to OceanSeaIce --- src/ClimaOcean.jl | 2 +- .../AtmosphericForcings.jl | 2 +- .../OceanSeaIceModel.jl} | 10 +++++----- src/{IceOceanModel => OceanSeaIceModel}/model_utils.jl | 0 .../ocean_only_model_fluxes.jl} | 2 +- .../ocean_sea_ice_atmosphere_fluxes.jl} | 0 .../ocean_sea_ice_model.jl} | 0 7 files changed, 8 insertions(+), 8 deletions(-) rename src/{IceOceanModel => OceanSeaIceModel}/AtmosphericForcings.jl (99%) rename src/{IceOceanModel/IceOceanModel.jl => OceanSeaIceModel/OceanSeaIceModel.jl} (85%) rename src/{IceOceanModel => OceanSeaIceModel}/model_utils.jl (100%) rename src/{IceOceanModel/only_ocean_model_fluxes.jl => OceanSeaIceModel/ocean_only_model_fluxes.jl} (99%) rename src/{IceOceanModel/ice_ocean_atmosphere_fluxes.jl => OceanSeaIceModel/ocean_sea_ice_atmosphere_fluxes.jl} (100%) rename src/{IceOceanModel/ice_ocean_model.jl => OceanSeaIceModel/ocean_sea_ice_model.jl} (100%) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 903436ab..8a03b222 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -105,6 +105,6 @@ include("DataWrangling.jl") include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") include("IdealizedSimulations/IdealizedSimulations.jl") -include("IceOceanModel/IceOceanModel.jl") +include("OceanSeaIceModel/OceanSeaIceModel.jl") end # module diff --git a/src/IceOceanModel/AtmosphericForcings.jl b/src/OceanSeaIceModel/AtmosphericForcings.jl similarity index 99% rename from src/IceOceanModel/AtmosphericForcings.jl rename to src/OceanSeaIceModel/AtmosphericForcings.jl index ead79916..158baeba 100644 --- a/src/IceOceanModel/AtmosphericForcings.jl +++ b/src/OceanSeaIceModel/AtmosphericForcings.jl @@ -200,4 +200,4 @@ end @inline Γ(FT, u★, T★, q★, T₀, qₐ, f) = convert(FT, 0.41) * convert(FT, 9.80655) * f.reference_height / u★^2 * (T★ / T₀ - q★ / (1/f.gamma_air - qₐ)) -end \ No newline at end of file +end diff --git a/src/IceOceanModel/IceOceanModel.jl b/src/OceanSeaIceModel/OceanSeaIceModel.jl similarity index 85% rename from src/IceOceanModel/IceOceanModel.jl rename to src/OceanSeaIceModel/OceanSeaIceModel.jl index 21c20bd7..0daead91 100644 --- a/src/IceOceanModel/IceOceanModel.jl +++ b/src/OceanSeaIceModel/OceanSeaIceModel.jl @@ -1,4 +1,4 @@ -module IceOceanModel +module OceanSeaIceModel using Oceananigans.Operators @@ -23,15 +23,15 @@ import Oceananigans.Utils: prettytime const ℒₑ = 2.5e6 # J/kg Latent heat of evaporation const σᴮ = 5.67e-8 # W/m²/K⁴ Stefan-Boltzmann constant -include("ice_ocean_model.jl") -include("ice_ocean_atmosphere_fluxes.jl") -include("only_ocean_model_fluxes.jl") +include("ocean_sea_ice_model.jl") +include("ocean_sea_ice_atmosphere_fluxes.jl") +include("ocean_only_model_fluxes.jl") include("AtmosphericForcings.jl") using .AtmosphericForcings # Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). -function default_nan_checker(model::IceOceanModel) +function default_nan_checker(model::OceanSeaIceModel) u_ocean = model.ocean.model.velocities.u nan_checker = NaNChecker((; u_ocean)) return nan_checker diff --git a/src/IceOceanModel/model_utils.jl b/src/OceanSeaIceModel/model_utils.jl similarity index 100% rename from src/IceOceanModel/model_utils.jl rename to src/OceanSeaIceModel/model_utils.jl diff --git a/src/IceOceanModel/only_ocean_model_fluxes.jl b/src/OceanSeaIceModel/ocean_only_model_fluxes.jl similarity index 99% rename from src/IceOceanModel/only_ocean_model_fluxes.jl rename to src/OceanSeaIceModel/ocean_only_model_fluxes.jl index b90a7426..10a98535 100644 --- a/src/IceOceanModel/only_ocean_model_fluxes.jl +++ b/src/OceanSeaIceModel/ocean_only_model_fluxes.jl @@ -42,4 +42,4 @@ function compute_air_sea_fluxes!(coupled_model::OnlyOceanModel) grid, clock, fields, forcing, nothing) return nothing -end \ No newline at end of file +end diff --git a/src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl b/src/OceanSeaIceModel/ocean_sea_ice_atmosphere_fluxes.jl similarity index 100% rename from src/IceOceanModel/ice_ocean_atmosphere_fluxes.jl rename to src/OceanSeaIceModel/ocean_sea_ice_atmosphere_fluxes.jl diff --git a/src/IceOceanModel/ice_ocean_model.jl b/src/OceanSeaIceModel/ocean_sea_ice_model.jl similarity index 100% rename from src/IceOceanModel/ice_ocean_model.jl rename to src/OceanSeaIceModel/ocean_sea_ice_model.jl From 9a32e41574ef46d28a2346a262dcc10a3aa7831e Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 13 Oct 2023 16:38:11 -0600 Subject: [PATCH 022/182] Build up OMIP simulation and shuffle files --- docs/Manifest.toml | 1396 +++++++++++- docs/Project.toml | 1 + .../run_neverworld_simulation.jl | 141 -- .../prototype_omip_simulation/Manifest.toml | 1965 +++++++++++++++++ .../prototype_omip_simulation/Project.toml | 6 + .../omip_simulation.jl | 100 + .../run_neverworld_simulation.jl | 135 -- 7 files changed, 3467 insertions(+), 277 deletions(-) delete mode 100644 experiments/catke_partial_cells/run_neverworld_simulation.jl create mode 100644 experiments/prototype_omip_simulation/Manifest.toml create mode 100644 experiments/prototype_omip_simulation/Project.toml create mode 100644 experiments/prototype_omip_simulation/omip_simulation.jl delete mode 100644 experiments/ri_based_partial_cells/run_neverworld_simulation.jl diff --git a/docs/Manifest.toml b/docs/Manifest.toml index e12d995c..e02283cd 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -2,16 +2,97 @@ julia_version = "1.9.2" manifest_format = "2.0" -project_hash = "c8b9437d4b095fc9a3fcf7a39d8c1fad8f05210e" +project_hash = "c17176d00ba2b8c3e38a54d717165bc946d88851" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" version = "0.0.1" +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "f35684b7349da49fcc8a9e520e30e45dbb077166" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.2.1" + +[[deps.AbstractTrees]] +git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.4" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "76289dc51920fdc6e0013c872ba9551d54961c24" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "3.6.2" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "f83ec24f76d4c8f525099b2ac475fc098138ec31" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.4.11" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + 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" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +[[deps.Automa]] +deps = ["TranscodingStreams"] +git-tree-sha1 = "ef9997b3d5547c48b41c7bd8899e812a917b409d" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "0.8.4" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.0.1" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" @@ -20,28 +101,208 @@ git-tree-sha1 = "43b1a4a8f797c1cddadf60499a8a077d4af2cd2d" uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" version = "0.1.7" +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+0" + +[[deps.CEnum]] +git-tree-sha1 = "eb4cb44a499229b3b8426dcfb5dd85333951ff90" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.4.2" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm]] +deps = ["CRlibm_jll"] +git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "1.0.1" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.Cairo]] +deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] +git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b" +uuid = "159f3aea-2a34-519c-b102-8c37f9878175" +version = "1.0.5" + +[[deps.CairoMakie]] +deps = ["Base64", "Cairo", "Colors", "FFTW", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools", "SHA"] +git-tree-sha1 = "74384dc4aba2b377e22703e849154252930c434d" +uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +version = "0.10.11" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.16.1+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "b66b8f8e3db5d7835fb8cbe2589ffd1cd456e491" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.17.0" + [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "9c209fb7536406834aa938fb149964b985de6c83" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" version = "0.7.1" +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"] +git-tree-sha1 = "600cc5508d66b78aae350f7accdb58763ac18589" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.9.10" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["UUIDs"] +git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.10.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.0.5+0" + [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] git-tree-sha1 = "5372dbbf8f0bdb8c700db5367132925c0771ef7e" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" version = "2.2.1" +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.4" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.2" + +[[deps.DataAPI]] +git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.15.0" + [[deps.DataDeps]] deps = ["HTTP", "Libdl", "Reexport", "SHA", "p7zip_jll"] git-tree-sha1 = "6e8d74545d34528c30ccd3fa0f3c00f8ed49584c" uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" version = "0.7.11" +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.15" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + [[deps.Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "bea7984f7e09aeb28a3b071c420a0186cb4fabad" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.8" + +[[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.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "Test"] +git-tree-sha1 = "3d5873f811f582873bb9871fc9c451784d5dc8c7" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.102" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + [[deps.DocStringExtensions]] deps = ["LibGit2"] git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" @@ -54,33 +315,358 @@ git-tree-sha1 = "39fd748a73dce4c05a9655475e437170d8fb1b67" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" version = "0.27.25" +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.ErrorfreeArithmetic]] +git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.5.2" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] +git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.5" + [[deps.ExceptionUnwrapping]] deps = ["Test"] git-tree-sha1 = "e90caa41f5a86296e014e148ee061bd6c3edec96" uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" version = "0.1.9" +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.Extents]] +git-tree-sha1 = "5e1e4c53fa39afe63a7d356e30452249365fba99" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.1" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "4.4.4+1" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "b4fbdd20c889804969571cc589900803edda16b7" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.7.1" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + +[[deps.FastRounding]] +deps = ["ErrorfreeArithmetic", "LinearAlgebra"] +git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.3.1" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "299dc33549f68299137e51e6d49a13b5b1da9673" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.1" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra", "Random"] +git-tree-sha1 = "a20eaa3ad64254c61eeb5f230d9306e937405434" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.6.1" +weakdeps = ["SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "c6e4a1fbe73b31a3dea94b1da449503b8830c306" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.21.1" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Formatting]] +deps = ["Printf"] +git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8" +uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" +version = "0.4.2" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "50351f83f95282cf903e968d7c6e8d44a5f83d0b" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.0" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "38a92e40157100e796690421e34a11c107205c86" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "2d6ca471a6c7b536127afccfa7564b5b39227fe0" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.5" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "d53480c0793b13341c40199190f92c611aa2e93c" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.2" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "424a5a6ce7c5d97cca7bcc4eac551b97294c54af" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.9" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "e94c92c7bf4819685eb80186d51c43e71d4afa17" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.76.5+0" + [[deps.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" version = "1.3.1" +[[deps.Graphics]] +deps = ["Colors", "LinearAlgebra", "NaNMath"] +git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "1.1.2" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.9.2" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] git-tree-sha1 = "cb56ccdd481c0dd7f975ad2b3b62d9eda088f7e2" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" version = "1.9.14" +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + [[deps.IOCapture]] deps = ["Logging", "Random"] git-tree-sha1 = "d75853a0bdbfb1ac815478bacd89cd27b550ace6" uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" version = "0.2.3" +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "b51bb8cae22c66d0f6357e3bcb6363145ef20835" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.5" + +[[deps.ImageCore]] +deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"] +git-tree-sha1 = "acf614720ef026d38400b3817614c45882d75500" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.9.4" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ad37c091f7d7daf900963171600d7c1c5c3ede32" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2023.2.0+0" + [[deps.InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "721ec2cf720536ad005cb38f50dbba7b02419a15" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.14.7" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] +git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.20.9" + +[[deps.IntervalSets]] +deps = ["Dates", "Random"] +git-tree-sha1 = "8e59ea773deee525c99a8018409f64f19fb719e6" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.7" +weakdeps = ["Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsStatisticsExt = "Statistics" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "4ced6667f9974fc5c5943fa5e2ef1ca43ea9e450" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.8.0" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + [[deps.JLLWrappers]] deps = ["Preferences"] git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1" @@ -93,19 +679,158 @@ git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" version = "0.21.4" +[[deps.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "d65930fa2bc96b07d7691c652d701dcbe7d9cf0b" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6f2675ef130a300a112286de91973805fcc5ffbc" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "2.1.91+0" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "90442c50e202a5cdf21a7899c66b240fdef14035" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.7" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f689897ccbe049adb19a065c495e75f372ecd42b" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.4+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "f2355693d6778a178ade15952b7ac47a4ff97996" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.0" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.3" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "7.84.0+0" + [[deps.LibGit2]] deps = ["Base64", "NetworkOptions", "Printf", "SHA"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.10.2+0" + [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.35.0+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.36.0+0" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "e129d9391168c677cd4800f5c0abb1ed8cb3794f" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.0" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Permutations", "Primes", "SimplePolynomials"] +git-tree-sha1 = "558a338f1eeabe933f9c2d4052aa7c2c707c3d52" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.1.12" + [[deps.Literate]] deps = ["Base64", "IOCapture", "JSON", "REPL"] git-tree-sha1 = "1c4418beaa6664041e0f9b48f0710f57bff2fcbe" uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" version = "2.14.0" +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.26" + + [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" @@ -115,10 +840,50 @@ git-tree-sha1 = "cedb76b37bc5a6c702ade66be44f831fa23c681e" uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" version = "1.0.0" +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "eb006abbd7041c28e0d16260e50a24f8f9104913" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2023.2.0+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "9ee1618cbf5240e6d4e0371d6f24065083f60c48" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.11" + +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "1d16d20279a145119899b4205258332f0fbeaa94" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.19.11" + +[[deps.MakieCore]] +deps = ["Observables", "REPL"] +git-tree-sha1 = "a94bf3fef9c690a2a4ac1d09d86a59ab89c7f8e4" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.6.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.Match]] +git-tree-sha1 = "1d9bc5c1a6e7ee24effb93f175c9342f9154d97f" +uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf" +version = "1.2.0" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "Test", "UnicodeFun"] +git-tree-sha1 = "8f52dbaa1351ce4cb847d95568cb29e62a307d93" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.6" + [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "Random", "Sockets"] git-tree-sha1 = "03a9b9718f5682ecb107ac9f7308991db4ce395b" @@ -130,17 +895,96 @@ deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" version = "2.28.2+0" +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" +[[deps.Mods]] +git-tree-sha1 = "61be59e4daffff43a8cec04b5e0dc773cbb5db3a" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "1.3.3" + +[[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 = "2022.10.11" +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" +[[deps.Observables]] +git-tree-sha1 = "6862738f9796b3edc1c09d0890afce4eca9e7e93" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.4" + +[[deps.OffsetArrays]] +deps = ["Adapt"] +git-tree-sha1 = "2ac17d29c523ce1cd38e27785a7d23024853a4bb" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.12.10" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.21+4" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+0" + [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" @@ -153,12 +997,134 @@ git-tree-sha1 = "cae3153c7f6cf3f069a853883fd1919a6e5bab5b" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" version = "3.0.9+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.Optim]] +deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.7.8" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.2" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+0" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "3d8af7d689bd228a3a6c2298a4e6d5f5944accb8" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.26" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "9b02b27ac477cad98114584ff964e3052f656a0f" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.0" + +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4745216e94f71cb768d58330b059c9b76f32cb66" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.50.14+0" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] git-tree-sha1 = "4b2e829ee66d4218e0cef22c0a64ee37cf258c29" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.7.1" +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "25e2bb0973689836bf164ecb960762f1bb8794dd" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.17" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.9.2" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "f92e1315dadf8c46561fb9396e525f7200cdc227" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.3.5" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "ea78a2764f31715093de7ab495e12c0187f231d1" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.4" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + [[deps.PrecompileTools]] deps = ["Preferences"] git-tree-sha1 = "9673d39decc5feece56ef3940e5dafba15ba0f81" @@ -171,10 +1137,34 @@ git-tree-sha1 = "7eb1686b4f04b82f96ed7a4ea5890a4f0c7a09f1" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.0" +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "4c9f306e5d6603ae203c2000dd460d81a5251489" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.4" + [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.9.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9ebcd48c498668c7fa0e97a9cae873fbee7bfee1" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.1" + [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" @@ -183,41 +1173,304 @@ uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" deps = ["SHA", "Serialization"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + [[deps.Reexport]] git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" uuid = "189a3867-3050-52da-a836-e630ba90ab69" version = "1.2.2" +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "30449ee12237627992a99d5e30ae63e4d78cd24a" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.0" + [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +[[deps.SetRounding]] +git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.1" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "db0219befe4507878b1a90e07820fed3e62c289d" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.4.0" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + [[deps.SimpleBufferStream]] git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" version = "1.1.0" +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "b608903049d11cc557c45e03b3a53e9260579c19" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.4" + +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "dcc02923a53f316ab97da8ef3136e80b4543dbf1" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.0" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "d537c31cf9995236166e3e9afc424a5a1c59ff9d" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.14" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "c60ec5c62180f27efea3ba2908480f8055e17cee" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.1.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableHashTraits]] +deps = ["Compat", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "19df33ca14f24a3ad2df9e89124bd5f5cc8467a2" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.0.1" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "Random", "StaticArraysCore"] +git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.6.5" +weakdeps = ["Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.9.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.2" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StructArrays]] +deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] +git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.16" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "5.10.1+6" + [[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 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.0" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + [[deps.Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.8" + [[deps.TranscodingStreams]] deps = ["Random", "Test"] git-tree-sha1 = "9a6ae7ed916312b41236fcef7e0af564ef934769" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" version = "0.9.13" +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + +[[deps.TupleTools]] +git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.4.3" + [[deps.URIs]] git-tree-sha1 = "074f993b0ca030848b897beff716d93aca60f06a" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" @@ -227,15 +1480,156 @@ version = "1.4.2" deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + [[deps.Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.5.5" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "24b81b59bd35b3c42ab84fa589086e19be919916" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.11.5+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" version = "1.2.13+0" +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.38+0" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.48.0+0" + [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+0" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" diff --git a/docs/Project.toml b/docs/Project.toml index 377e2b2d..e11571db 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,4 +1,5 @@ [deps] +CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" Glob = "c27321d9-0574-5035-807b-f59d2c89b15c" diff --git a/experiments/catke_partial_cells/run_neverworld_simulation.jl b/experiments/catke_partial_cells/run_neverworld_simulation.jl deleted file mode 100644 index bc1fe488..00000000 --- a/experiments/catke_partial_cells/run_neverworld_simulation.jl +++ /dev/null @@ -1,141 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity -using Oceananigans.ImmersedBoundaries: PartialCellBottom, GridFittedBottom -using ClimaOcean.IdealizedSimulations: neverworld_simulation -using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching -using Printf -using CUDA - -closure = CATKEVerticalDiffusivity(minimum_turbulent_kinetic_energy = 1e-6, - minimum_convective_buoyancy_flux = 1e-11) - -# closure = RiBasedVerticalDiffusivity() - -z = stretched_vertical_faces(surface_layer_Δz = 8, - surface_layer_height = 64, - stretching = PowerLawStretching(1.02), - maximum_Δz = 400.0, - minimum_depth = 4000) - -simulation = neverworld_simulation(GPU(); z, - ImmersedBoundaryType = GridFittedBottom, - #ImmersedBoundaryType = PartialCellBottom, - horizontal_resolution = 1/4, - longitude = (0, 60), - latitude = (-70, 0), - time_step = 10minutes, - stop_time = 1 * 360days, - closure) - -model = simulation.model -grid = model.grid - -@show grid -@show model - -start_time = Ref(time_ns()) -previous_model_time = Ref(time(simulation)) - -_maximum(x) = maximum(parent(x)) -_maximum(f, x) = maximum(f, parent(x)) -_minimum(x) = minimum(parent(x)) - -function progress(sim) - b = sim.model.tracers.b - e = sim.model.tracers.e - u, v, w = sim.model.velocities - - msg = @sprintf("Iter: %d, time: %s, extrema(b): (%6.2e, %6.2e)", - iteration(sim), prettytime(sim), _minimum(b), _maximum(b)) - - msg *= @sprintf(", max(e): %6.2e", _maximum(e)) - - msg *= @sprintf(", max|u|: %6.2e, max|w|: %6.2e", - maximum(_maximum(abs, q) for q in (u, v, w)), _maximum(abs, w)) - - try - κᶜ = sim.model.diffusivity_fields.κᶜ - msg *= @sprintf(", max(κᶜ): %6.2e", _maximum(κᶜ)) - catch - end - - elapsed = 1e-9 * (time_ns() - start_time[]) - elapsed_model_time = time(sim) - previous_model_time[] - SYPD = (elapsed_model_time/360days) / (elapsed/day) - - msg *= @sprintf(", wall time: %s, SYPD: %.1f", prettytime(elapsed), SYPD) - start_time[] = time_ns() - previous_model_time[] = time(sim) - - @info msg - - return nothing -end - -simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -# Set up output -Nx, Ny, Nz = size(grid) -Δt = simulation.Δt -Δt_minutes = round(Int, Δt / minutes) -ib_str = grid.immersed_boundary isa PartialCellBottom ? "partial_cells" : "full_cells" -output_suffix = "$(Nx)_$(Ny)_$(Nz)_dt$(Δt_minutes)_$(ib_str).jld2" -output_dir = "." -fine_output_frequency = 1day - -z = znodes(grid, Face(), with_halos=true) - -K = CUDA.@allowscalar [Nz, - searchsortedfirst(z, -100), - searchsortedfirst(z, -400)] - -I = [round(Int, Nx/10), round(Int, Nx/2)] # index for yz-sliced output - -diffusivity_fields = (; κᶜ = model.diffusivity_fields.κᶜ) -outputs = merge(model.velocities, model.tracers, diffusivity_fields) -zonally_averaged_outputs = NamedTuple(n => Average(outputs[n], dims=1) for n in keys(outputs)) - -for (n, i) in enumerate(I) - name = Symbol(:yz, n) - simulation.output_writers[name] = JLD2OutputWriter(model, outputs; - schedule = TimeInterval(fine_output_frequency), - filename = joinpath(output_dir, "neverworld_yz$(n)_" * output_suffix), - indices = (i, :, :), - with_halos = true, - overwrite_existing = true) -end - -simulation.output_writers[:zonal] = JLD2OutputWriter(model, zonally_averaged_outputs; - schedule = TimeInterval(fine_output_frequency), - filename = joinpath(output_dir, "neverworld_zonal_average_" * output_suffix), - with_halos = true, - overwrite_existing = true) - -for (n, k) in enumerate(K) - name = Symbol(:xy, n) - simulation.output_writers[name] = JLD2OutputWriter(model, outputs; - schedule = TimeInterval(fine_output_frequency), - filename = joinpath(output_dir, "neverworld_xy$(n)_" * output_suffix), - indices = (:, :, Nz), - with_halos = true, - overwrite_existing = true) -end - -simulation.output_writers[:xyz] = JLD2OutputWriter(model, outputs; - schedule = TimeInterval(90days), - filename = joinpath(output_dir, "neverworld_xyz_" * output_suffix), - with_halos = true, - overwrite_existing = true) - -simulation.output_writers[:checkpointer] = Checkpointer(model, - schedule = TimeInterval(360days), - dir = output_dir, - prefix = "neverworld_$(Nx)_$(Ny)_$(Nz)_checkpoint", - cleanup = true) - -@info "Running..." -@show simulation - -run!(simulation) - diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml new file mode 100644 index 00000000..2d5853db --- /dev/null +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -0,0 +1,1965 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.9.2" +manifest_format = "2.0" +project_hash = "380b86e0676891c46b83c0a9eb02cd35b3528a97" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "f35684b7349da49fcc8a9e520e30e45dbb077166" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.2.1" + +[[deps.AbstractTrees]] +git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.4" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "76289dc51920fdc6e0013c872ba9551d54961c24" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "3.6.2" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "f83ec24f76d4c8f525099b2ac475fc098138ec31" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.4.11" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + 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" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.Automa]] +deps = ["TranscodingStreams"] +git-tree-sha1 = "ef9997b3d5547c48b41c7bd8899e812a917b409d" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "0.8.4" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.0.1" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random", "Test"] +git-tree-sha1 = "dbf84058d0a8cbbadee18d25cf606934b22d7c66" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.4.2" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+0" + +[[deps.CEnum]] +git-tree-sha1 = "eb4cb44a499229b3b8426dcfb5dd85333951ff90" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.4.2" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.2" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm]] +deps = ["CRlibm_jll"] +git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "1.0.1" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "Preferences", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "SpecialFunctions", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "968c1365e2992824c3e7a794e30907483f8469a9" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "4.4.1" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "498f45593f6ddc0adff64a9310bb6710e851781b" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.5.0+1" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "bcc4a23cbbd99c8535a5318455dcf0f2546ec536" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.2.2" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "5248d9c45712e51e27ba9b30eebec65658c6ce29" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.6.0+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.16.1+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "e30f2f4e20f7f186dc36529910beaedc60cfa644" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.16.0" + +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"] +git-tree-sha1 = "600cc5508d66b78aae350f7accdb58763ac18589" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.9.10" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf"] +git-tree-sha1 = "7f5717cbb2c1ce650cfd454451f282df33103596" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.2.5" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["UUIDs"] +git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.10.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.0.5+0" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.4" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.2" + +[[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 = "131498c78453d02b4821d8b93f6e44595399f19f" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.2.3" + +[[deps.DataAPI]] +git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.15.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.15" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "bea7984f7e09aeb28a3b071c420a0186cb4fabad" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.8" + +[[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.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.10" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "Test"] +git-tree-sha1 = "3d5873f811f582873bb9871fc9c451784d5dc8c7" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.102" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.Elliptic]] +git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" +uuid = "b305315f-e792-5b7a-8f41-49f472929428" +version = "1.0.1" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.ErrorfreeArithmetic]] +git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.5.2" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] +git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.5" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.Extents]] +git-tree-sha1 = "5e1e4c53fa39afe63a7d356e30452249365fba99" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.1" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "4.4.4+1" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "b4fbdd20c889804969571cc589900803edda16b7" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.7.1" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + +[[deps.FastRounding]] +deps = ["ErrorfreeArithmetic", "LinearAlgebra"] +git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.3.1" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "299dc33549f68299137e51e6d49a13b5b1da9673" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.1" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra", "Random"] +git-tree-sha1 = "a20eaa3ad64254c61eeb5f230d9306e937405434" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.6.1" +weakdeps = ["SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "c6e4a1fbe73b31a3dea94b1da449503b8830c306" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.21.1" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Formatting]] +deps = ["Printf"] +git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8" +uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" +version = "0.4.2" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "50351f83f95282cf903e968d7c6e8d44a5f83d0b" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.0" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "38a92e40157100e796690421e34a11c107205c86" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GLFW]] +deps = ["GLFW_jll"] +git-tree-sha1 = "35dbc482f0967d8dceaa7ce007d16f9064072166" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "3.4.1" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "d972031d28c8c8d9d7b41a536ad7bb0c2579caca" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.3.8+0" + +[[deps.GLMakie]] +deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] +git-tree-sha1 = "b46b637cf3e1945354e77c016f867198b829d2f6" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.8.11" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] +git-tree-sha1 = "2e57b4a4f9cc15e85a24d603256fe08e527f48d1" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "8.8.1" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "2d6ca471a6c7b536127afccfa7564b5b39227fe0" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.5" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "72b2e3c2ba583d1a7aa35129e56cf92e07c083e3" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.21.4" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "d53480c0793b13341c40199190f92c611aa2e93c" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.2" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "424a5a6ce7c5d97cca7bcc4eac551b97294c54af" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.9" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "e94c92c7bf4819685eb80186d51c43e71d4afa17" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.76.5+0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.Graphics]] +deps = ["Colors", "LinearAlgebra", "NaNMath"] +git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "1.1.2" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.9.2" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "38c8874692d48d5440d5752d6c74b0c6b0b60739" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.2+1" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "b51bb8cae22c66d0f6357e3bcb6363145ef20835" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.5" + +[[deps.ImageCore]] +deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"] +git-tree-sha1 = "acf614720ef026d38400b3817614c45882d75500" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.9.4" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IncompleteLU]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" +uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" +version = "0.2.1" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ad37c091f7d7daf900963171600d7c1c5c3ede32" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2023.2.0+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "721ec2cf720536ad005cb38f50dbba7b02419a15" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.14.7" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] +git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.20.9" + +[[deps.IntervalSets]] +deps = ["Dates", "Random"] +git-tree-sha1 = "8e59ea773deee525c99a8018409f64f19fb719e6" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.7" +weakdeps = ["Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsStatisticsExt = "Statistics" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "4ced6667f9974fc5c5943fa5e2ef1ca43ea9e450" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.8.0" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "1169632f425f79429f245113b775a0e3d121457c" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.2" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] +git-tree-sha1 = "c11d691a0dc8e90acfa4740d293ade57f68bfdbb" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.35" + +[[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.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "d65930fa2bc96b07d7691c652d701dcbe7d9cf0b" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6f2675ef130a300a112286de91973805fcc5ffbc" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "2.1.91+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "4c5875e4c228247e1c2b087669846941fb6e0118" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.8" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "90442c50e202a5cdf21a7899c66b240fdef14035" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.7" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Printf", "Unicode"] +git-tree-sha1 = "4ea2928a96acfcf8589e6cd1429eff2a3a82c366" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "6.3.0" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "e7c01b69bcbcb93fd4cbc3d0fea7d229541e18d2" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.26+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f689897ccbe049adb19a065c495e75f372ecd42b" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.4+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "f2355693d6778a178ade15952b7ac47a4ff97996" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.0" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.3" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "7.84.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.10.2+0" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.6.0+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.35.0+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.36.0+0" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "e129d9391168c677cd4800f5c0abb1ed8cb3794f" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.0" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Permutations", "Primes", "SimplePolynomials"] +git-tree-sha1 = "558a338f1eeabe933f9c2d4052aa7c2c707c3d52" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.1.12" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.26" + + [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.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "eb006abbd7041c28e0d16260e50a24f8f9104913" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2023.2.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", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "8a5b4d2220377d1ece13f49438d71ad20cf1ba83" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.1.2+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "781916a2ebf2841467cda03b6f1af43e23839d85" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.9" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "6979eccb6a9edbbb62681e158443e79ecc0d056a" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.3.1+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "9ee1618cbf5240e6d4e0371d6f24065083f60c48" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.11" + +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "1d16d20279a145119899b4205258332f0fbeaa94" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.19.11" + +[[deps.MakieCore]] +deps = ["Observables", "REPL"] +git-tree-sha1 = "a94bf3fef9c690a2a4ac1d09d86a59ab89c7f8e4" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.6.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.Match]] +git-tree-sha1 = "1d9bc5c1a6e7ee24effb93f175c9342f9154d97f" +uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf" +version = "1.2.0" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "Test", "UnicodeFun"] +git-tree-sha1 = "8f52dbaa1351ce4cb847d95568cb29e62a307d93" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.6" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+0" + +[[deps.MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] +git-tree-sha1 = "8be09d84a2d597c7c0c34d7d604c039c9763e48c" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.4.10" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "a7023883872e52bc29bcaac74f19adf39347d2d5" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+0" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "b76ea40b5c0f45790ae09492712dd326208c28b2" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.1.7" + +[[deps.Mods]] +git-tree-sha1 = "61be59e4daffff43a8cec04b5e0dc773cbb5db3a" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "1.3.3" + +[[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 = "2022.10.11" + +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "4263c4220f22e20729329838bf7e94a49d1ac32f" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.12.17" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "XML2_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "10c612c81eaffdd6b7c28a45a554cdd9d2f40ff1" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "400.902.208+0" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Observables]] +git-tree-sha1 = "6862738f9796b3edc1c09d0890afce4eca9e7e93" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.4" + +[[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 = "e8caa94d03ec34434abc0fb036d43d34d1903411" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.89.2" + +[[deps.OffsetArrays]] +deps = ["Adapt"] +git-tree-sha1 = "2ac17d29c523ce1cd38e27785a7d23024853a4bb" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.12.10" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.21+4" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+0" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "e25c1778a98e34219a00455d6e4384e017ea9762" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "4.1.6+0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ceeda72c9fd6bbebc4f4f598560789145a8b6c4c" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.11+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.Optim]] +deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.7.8" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.2" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+0" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "fcf8fd477bd7f33cb8dbb1243653fb0d415c256c" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.25" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "9b02b27ac477cad98114584ff964e3052f656a0f" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.0" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.7.2" + +[[deps.PencilArrays]] +deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] +git-tree-sha1 = "1a473d028436947e08436275ff3fcc2f3e9c5b06" +uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" +version = "0.19.2" + + [deps.PencilArrays.extensions] + PencilArraysDiffEqExt = ["DiffEqBase"] + PencilArraysHDF5Ext = ["HDF5"] + + [deps.PencilArrays.weakdeps] + DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" + HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" + +[[deps.PencilFFTs]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" +uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" +version = "0.15.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "25e2bb0973689836bf164ecb960762f1bb8794dd" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.17" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.9.2" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "f92e1315dadf8c46561fb9396e525f7200cdc227" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.3.5" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "ea78a2764f31715093de7ab495e12c0187f231d1" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.4" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.0" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.1" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "4c9f306e5d6603ae203c2000dd460d81a5251489" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.4" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.ProgressBars]] +deps = ["Printf"] +git-tree-sha1 = "b437cdb0385ed38312d91d9c00c20f3798b30256" +uuid = "49802e3a-d2f1-5c88-81d8-b72133a6f568" +version = "1.5.1" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.9.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9ebcd48c498668c7fa0e97a9cae873fbee7bfee1" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.1" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "da095158bdc8eaccb7890f9884048555ab771019" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.4" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA", "Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Random123]] +deps = ["Random", "RandomNumbers"] +git-tree-sha1 = "552f30e847641591ba3f39fd1bed559b9deb0ef3" +uuid = "74087812-796a-5b5d-8853-05524746bad3" +version = "1.6.1" + +[[deps.RandomNumbers]] +deps = ["Random", "Requires"] +git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111" +uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" +version = "1.5.3" + +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "0783924e4a332493f72490253ba4e668aeba1d73" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.6.0" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "30449ee12237627992a99d5e30ae63e4d78cd24a" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.0" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "958ba75b90c7c8a117d041d33184134201cf8c0f" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.2" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SetRounding]] +git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.1" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "db0219befe4507878b1a90e07820fed3e62c289d" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.4.0" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "b608903049d11cc557c45e03b3a53e9260579c19" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.4" + +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "dcc02923a53f316ab97da8ef3136e80b4543dbf1" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.0" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "d537c31cf9995236166e3e9afc424a5a1c59ff9d" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.14" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "c60ec5c62180f27efea3ba2908480f8055e17cee" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.1.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableHashTraits]] +deps = ["Compat", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "19df33ca14f24a3ad2df9e89124bd5f5cc8467a2" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.0.1" + +[[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 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "0.8.8" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "03fec6800a986d191f64f5c0996b59ed526eda25" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.4.1" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "Random", "StaticArraysCore"] +git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.6.5" +weakdeps = ["Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.StaticPermutations]] +git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" +uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" +version = "0.3.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.9.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.2" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Strided]] +deps = ["LinearAlgebra", "StridedViews", "TupleTools"] +git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "2.0.4" + +[[deps.StridedViews]] +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "cf857ff7de76f39e5daef6d032e8a74279ddff6a" +uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" +version = "0.2.1" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" + +[[deps.StructArrays]] +deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] +git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.16" + +[[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", "Pkg", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "5.10.1+6" + +[[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 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.0" + +[[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 = "50718b4fc1ce20cecf28d85215028c78b4d875c2" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.15.2" +weakdeps = ["IntervalArithmetic"] + + [deps.TaylorSeries.extensions] + TaylorSeriesIAExt = "IntervalArithmetic" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.8" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.23" + +[[deps.TranscodingStreams]] +deps = ["Random", "Test"] +git-tree-sha1 = "9a6ae7ed916312b41236fcef7e0af564ef934769" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.9.13" + +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + +[[deps.TupleTools]] +git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.4.3" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.2.1" + +[[deps.UnsafeAtomicsLLVM]] +deps = ["LLVM", "UnsafeAtomics"] +git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.3" + +[[deps.VersionParsing]] +git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.3.0" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "0.5.5" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "24b81b59bd35b3c42ab84fa589086e19be919916" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.11.5+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.0+4" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "5.0.3+4" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.7.10+4" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] +git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.4+4" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.2+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+0" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.5+0" + +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eddd19a8dea6b139ea97bdc8a0e2667d4b661720" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.0.6+1" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.38+0" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.48.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+0" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml new file mode 100644 index 00000000..d9eea3af --- /dev/null +++ b/experiments/prototype_omip_simulation/Project.toml @@ -0,0 +1,6 @@ +[deps] +Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl new file mode 100644 index 00000000..514385b5 --- /dev/null +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -0,0 +1,100 @@ +using Oceananigans +using Oceananigans.Units +using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity +using NCDatasets +using GLMakie +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + +using Downloads: download + +temperature_filename = "THETA.1440x720x50.19920102.nc" +salinity_filename = "SALT.1440x720x50.19920102.nc" + +# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N + +temperature_url = "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * + "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0" + +salinity_url = "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * + "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0" + +isfile(temperature_filename) || download(temperature_url, temperature_filename) +isfile(salinity_filename) || download(salinity_url, salinity_filename) + +temperature_ds = Dataset(temperature_filename) +salinity_ds = Dataset(salinity_filename) + +# Construct vertical coordinate +depth = temperature_ds["DEPTH_T"][:] +zc = -reverse(depth) + +# Interface depths from cell center depths +zf = (zc[1:end-1] .+ zc[2:end]) ./ 2 +push!(zf, 0) + +Δz = zc[2] - zc[1] +pushfirst!(zf, zf[1] - Δz) + +T = temperature_ds["THETA"][:, :, :, 1] +S = salinity_ds["SALT"][:, :, :, 1] + +T = convert(Array{Float32, 3}, T) +S = convert(Array{Float32, 3}, S) + +T = reverse(T, dims=3) +S = reverse(S, dims=3) + +missing_value = Float32(-9.9e22) + +# Construct bottom_height depth by analyzing T +Nx, Ny′, Nz = size(T) +bottom_height = ones(Nx, Ny′) .* (zf[1] - Δz) + +for i = 1:Nx, j = 1:Ny′ + @inbounds for k = Nz:-1:1 + if T[i, j, k] < -10 + bottom_height[i, j] = zf[k+1] + break + end + end +end + +# Grid construction +arch = CPU() +southern_limit = -80 +northern_limit = 80 +j₁ = 4 * (90 + southern_limit) +j₂ = 720 - 4 * (90 - northern_limit) + 1 +Ny = j₂ - j₁ + 1 + +T = T[:, j₁:j₂, :] +S = S[:, j₁:j₂, :] +bottom_height = bottom_height[:, j₁:j₂] + +grid = LatitudeLongitudeGrid(arch, + size = (Nx, Ny, Nz), + longitude = (0, 360), + latitude = (southern_limit, northern_limit), + z = zf, + topology = (Periodic, Bounded, Bounded)) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + +using Oceananigans.Grids: φnodes, λnodes + +λ = λnodes(grid, Center()) +φ = φnodes(grid, Center()) + +fig = Figure() +ax = Axis(fig[1, 1]) +heatmap!(ax, λ, φ, bottom_height) + +# Model construction +teos10 = TEOS10EquationOfState() +buoyancy = SeawaterBuoyancy(equation_of_state=teos10) + +model = HydrostaticFreeSurfaceModel(; grid, buoyancy, + tracers = (:T, :S, :e), + coriolis = HydrostaticSphericalCoriolis(), + closure = CATKEVerticalDiffusivity()) + diff --git a/experiments/ri_based_partial_cells/run_neverworld_simulation.jl b/experiments/ri_based_partial_cells/run_neverworld_simulation.jl deleted file mode 100644 index 49441745..00000000 --- a/experiments/ri_based_partial_cells/run_neverworld_simulation.jl +++ /dev/null @@ -1,135 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity -using Oceananigans.ImmersedBoundaries: PartialCellBottom, GridFittedBottom -using ClimaOcean.IdealizedSimulations: neverworld_simulation -using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching -using Printf -using CUDA - -# closure = CATKEVerticalDiffusivity(minimum_turbulent_kinetic_energy = 1e-6, -# minimum_convective_buoyancy_flux = 1e-11) - -closure = RiBasedVerticalDiffusivity() - -z = stretched_vertical_faces(surface_layer_Δz = 8, - surface_layer_height = 64, - stretching = PowerLawStretching(1.02), - maximum_Δz = 400.0, - minimum_depth = 4000) - -simulation = neverworld_simulation(GPU(); z, - #ImmersedBoundaryType = GridFittedBottom, - ImmersedBoundaryType = PartialCellBottom, - horizontal_resolution = 1/8, - longitude = (0, 60), - latitude = (-70, 0), - time_step = 10minutes, - stop_time = 4 * 360days, - closure) - -model = simulation.model -grid = model.grid - -@show grid -@show model - -start_time = Ref(time_ns()) -previous_model_time = Ref(time(simulation)) - -function progress(sim) - b = sim.model.tracers.b - e = sim.model.tracers.e - u, v, w = sim.model.velocities - - msg = @sprintf("Iter: %d, time: %s, extrema(b): (%6.2e, %6.2e)", - iteration(sim), prettytime(sim), minimum(b), maximum(b)) - - msg *= @sprintf(", max(e): %6.2e", maximum(e)) - - msg *= @sprintf(", max|u|: %6.2e, max|w|: %6.2e", - maximum(maximum(abs, q) for q in (u, v, w)), maximum(abs, w)) - - try - κᶜ = sim.model.diffusivity_fields.κᶜ - msg *= @sprintf(", max(κᶜ): %6.2e", maximum(κᶜ)) - catch - end - - elapsed = 1e-9 * (time_ns() - start_time[]) - elapsed_model_time = time(sim) - previous_model_time[] - SYPD = (elapsed_model_time/360days) / (elapsed/day) - - msg *= @sprintf(", wall time: %s, SYPD: %.1f", prettytime(elapsed), SYPD) - start_time[] = time_ns() - previous_model_time[] = time(sim) - - @info msg - - return nothing -end - -simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -# Set up output -Nx, Ny, Nz = size(grid) -Δt = simulation.Δt -Δt_minutes = round(Int, Δt / minutes) -ib_str = grid.immersed_boundary isa PartialCellBottom ? "partial_cells" : "full_cells" -output_suffix = "$(Nx)_$(Ny)_$(Nz)_dt$(Δt_minutes)_$(ib_str).jld2" -output_dir = "." #/nobackup1/glwagner/" -fine_output_frequency = 1day -i = round(Int, Nx/10) # index for yz-sliced output - -z = znodes(grid, Face(), with_halos=true) - -K = CUDA.@allowscalar [Nz, - searchsortedfirst(z, -100), - searchsortedfirst(z, -400)] - -i = round(Int, Nx/10) # index for yz-sliced output - -diffusivity_fields = (; κᶜ = model.diffusivity_fields.κᶜ) -outputs = merge(model.velocities, model.tracers, diffusivity_fields) -zonally_averaged_outputs = NamedTuple(n => Average(outputs[n], dims=1) for n in keys(outputs)) - -simulation.output_writers[:yz] = JLD2OutputWriter(model, outputs; - schedule = TimeInterval(fine_output_frequency), - filename = joinpath(output_dir, "neverworld_yz_" * output_suffix), - indices = (i, :, :), - with_halos = true, - overwrite_existing = true) - -simulation.output_writers[:zonal] = JLD2OutputWriter(model, zonally_averaged_outputs; - schedule = TimeInterval(fine_output_frequency), - filename = joinpath(output_dir, "neverworld_zonal_average_" * output_suffix), - with_halos = true, - overwrite_existing = true) - -for (n, k) in enumerate(K) - name = Symbol(:xy, n) - simulation.output_writers[name] = JLD2OutputWriter(model, outputs; - schedule = TimeInterval(fine_output_frequency), - filename = joinpath(output_dir, "neverworld_xy$(n)_" * output_suffix), - indices = (:, :, Nz), - with_halos = true, - overwrite_existing = true) -end - -simulation.output_writers[:xyz] = JLD2OutputWriter(model, outputs; - schedule = TimeInterval(90days), - filename = joinpath(output_dir, "neverworld_xyz_" * output_suffix), - with_halos = true, - overwrite_existing = true) - -simulation.output_writers[:checkpointer] = Checkpointer(model, - schedule = TimeInterval(360days), - dir = output_dir, - prefix = "neverworld_$(Nx)_$(Ny)_$(Nz)_checkpoint", - cleanup = true) - -@info "Running..." -@show simulation - -run!(simulation) - From ab42a3004a7a2679f2d822823ade7ff7f97853f5 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 13 Oct 2023 16:42:12 -0600 Subject: [PATCH 023/182] Updates to omip setup --- .../omip_simulation.jl | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 514385b5..330bb304 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -35,24 +35,24 @@ push!(zf, 0) Δz = zc[2] - zc[1] pushfirst!(zf, zf[1] - Δz) -T = temperature_ds["THETA"][:, :, :, 1] -S = salinity_ds["SALT"][:, :, :, 1] +Tᵢ = temperature_ds["THETA"][:, :, :, 1] +Sᵢ = salinity_ds["SALT"][:, :, :, 1] -T = convert(Array{Float32, 3}, T) -S = convert(Array{Float32, 3}, S) +Tᵢ = convert(Array{Float32, 3}, Tᵢ) +Sᵢ = convert(Array{Float32, 3}, Sᵢ) -T = reverse(T, dims=3) -S = reverse(S, dims=3) +Tᵢ = reverse(Tᵢ, dims=3) +Sᵢ = reverse(Sᵢ, dims=3) missing_value = Float32(-9.9e22) # Construct bottom_height depth by analyzing T -Nx, Ny′, Nz = size(T) +Nx, Ny′, Nz = size(Tᵢ) bottom_height = ones(Nx, Ny′) .* (zf[1] - Δz) for i = 1:Nx, j = 1:Ny′ @inbounds for k = Nz:-1:1 - if T[i, j, k] < -10 + if Tᵢ[i, j, k] < -10 bottom_height[i, j] = zf[k+1] break end @@ -67,8 +67,8 @@ j₁ = 4 * (90 + southern_limit) j₂ = 720 - 4 * (90 - northern_limit) + 1 Ny = j₂ - j₁ + 1 -T = T[:, j₁:j₂, :] -S = S[:, j₁:j₂, :] +Tᵢ = Tᵢ[:, j₁:j₂, :] +Sᵢ = Sᵢ[:, j₁:j₂, :] bottom_height = bottom_height[:, j₁:j₂] grid = LatitudeLongitudeGrid(arch, @@ -98,3 +98,22 @@ model = HydrostaticFreeSurfaceModel(; grid, buoyancy, coriolis = HydrostaticSphericalCoriolis(), closure = CATKEVerticalDiffusivity()) +set!(model, T=Tᵢ, S=Sᵢ) + +simulation = Simulation(model, Δt=5minutes, stop_iteration=10) + +run!(simulation) + +T, S, e = model.tracers +Tn = interior(T, :, :, Nz) +Sn = interior(S, :, :, Nz) + +fig = Figure() +axT = Axis(fig[1, 1]) +axS = Axis(fig[2, 1]) + +heatmap!(axT, λ, φ, Tn) +heatmap!(axS, λ, φ, Sn) + +display(fig) + From 322b642236debc560a00a9545b5b994fe38c0290 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sat, 14 Oct 2023 17:21:56 -0400 Subject: [PATCH 024/182] It runs --- .../omip_simulation.jl | 100 +++++++++++++++--- 1 file changed, 83 insertions(+), 17 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 330bb304..f5be8f55 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -4,11 +4,13 @@ using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity using NCDatasets using GLMakie using SeawaterPolynomials.TEOS10: TEOS10EquationOfState +using Printf using Downloads: download temperature_filename = "THETA.1440x720x50.19920102.nc" salinity_filename = "SALT.1440x720x50.19920102.nc" +ice_thickness_filename = "SIheff.1440x720.19920102.nc" # Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N @@ -18,11 +20,16 @@ temperature_url = "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * salinity_url = "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0" -isfile(temperature_filename) || download(temperature_url, temperature_filename) -isfile(salinity_filename) || download(salinity_url, salinity_filename) +ice_thickness_url = "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/" * + "SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am&dl=0" + +isfile(temperature_filename) || download(temperature_url, temperature_filename) +isfile(salinity_filename) || download(salinity_url, salinity_filename) +isfile(ice_thickness_filename) || download(ice_thickness_url, ice_thickness_filename) temperature_ds = Dataset(temperature_filename) salinity_ds = Dataset(salinity_filename) +ice_thickness_ds = Dataset(ice_thickness_filename) # Construct vertical coordinate depth = temperature_ds["DEPTH_T"][:] @@ -37,6 +44,7 @@ pushfirst!(zf, zf[1] - Δz) Tᵢ = temperature_ds["THETA"][:, :, :, 1] Sᵢ = salinity_ds["SALT"][:, :, :, 1] +hᵢ = ice_thickness_ds["SIheff"][:, :, 1] Tᵢ = convert(Array{Float32, 3}, Tᵢ) Sᵢ = convert(Array{Float32, 3}, Sᵢ) @@ -60,9 +68,9 @@ for i = 1:Nx, j = 1:Ny′ end # Grid construction -arch = CPU() -southern_limit = -80 -northern_limit = 80 +arch = GPU() +southern_limit = -79 +northern_limit = -50 j₁ = 4 * (90 + southern_limit) j₂ = 720 - 4 * (90 - northern_limit) + 1 Ny = j₂ - j₁ + 1 @@ -74,6 +82,7 @@ bottom_height = bottom_height[:, j₁:j₂] grid = LatitudeLongitudeGrid(arch, size = (Nx, Ny, Nz), longitude = (0, 360), + halo = (7, 7, 7), latitude = (southern_limit, northern_limit), z = zf, topology = (Periodic, Bounded, Bounded)) @@ -93,27 +102,84 @@ heatmap!(ax, λ, φ, bottom_height) teos10 = TEOS10EquationOfState() buoyancy = SeawaterBuoyancy(equation_of_state=teos10) -model = HydrostaticFreeSurfaceModel(; grid, buoyancy, +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: MixingLength +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: TurbulentKineticEnergyEquation + +mixing_length = MixingLength(Cᵇ=0.1) +turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) +closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) + +tracer_advection = WENO() +momentum_advection = VectorInvariant(vorticity_scheme = WENO(), + divergence_scheme = WENO(), + vertical_scheme = WENO()) + +model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, + tracer_advection, momentum_advection, tracers = (:T, :S, :e), - coriolis = HydrostaticSphericalCoriolis(), - closure = CATKEVerticalDiffusivity()) + free_surface = SplitExplicitFreeSurface(cfl=0.2; grid), + coriolis = HydrostaticSphericalCoriolis()) set!(model, T=Tᵢ, S=Sᵢ) -simulation = Simulation(model, Δt=5minutes, stop_iteration=10) +simulation = Simulation(model, Δt=5minutes, stop_time=10days) + +wall_clock = Ref(time_ns()) + +function progress(sim) + + msg1 = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg2 = string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.velocities + msg3 = @sprintf(", max|u|: (%.2e, %.2e, %.2e)", + maximum(abs, u), + maximum(abs, v), + maximum(abs, w)) + + @info msg1 * msg2 * msg3 +end + +simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +using Oceananigans.Operators: ζ₃ᶠᶠᶜ +u, v, w = model.velocities +ζ = KernelFunctionOperation{Face, Face, Center}(ζ₃ᶠᶠᶜ, grid, u, v) + +outputs = merge(model.velocities, model.tracers, (; ζ)) +filename = "omip_surface_fields.jld2" + +simulation.output_writers[:surface] = JLD2OutputWriter(model, outputs; filename, + schedule = TimeInterval(12hour), + indices = (:, :, Nz), + overwrite_existing = true) run!(simulation) -T, S, e = model.tracers -Tn = interior(T, :, :, Nz) -Sn = interior(S, :, :, Nz) +#Tt = FieldTimeSeries(filename, "T") +#St = FieldTimeSeries(filename, "S") +et = FieldTimeSeries(filename, "e") +ζt = FieldTimeSeries(filename, "ζ") +times = et.times +Nt = length(times) -fig = Figure() -axT = Axis(fig[1, 1]) -axS = Axis(fig[2, 1]) +fig = Figure(resolution=(1800, 1200)) + +axe = Axis(fig[1, 1]) +axZ = Axis(fig[2, 1]) +slider = Slider(fig[3, 1], range=1:Nt, startvalue=1) +n = slider.value + +en = @lift interior(et[$n], :, :, 1) +ζn = @lift interior(ζt[$n], :, :, 1) -heatmap!(axT, λ, φ, Tn) -heatmap!(axS, λ, φ, Sn) +#heatmap!(axT, λ, φ, Tn, colorrange=(-1, 25), colormap=:thermal) +#heatmap!(axS, λ, φ, Sn, colorrange=(28, 35), colormap=:haline) +heatmap!(axe, λ, φ, en, colorrange=(0, 1e-4), colormap=:solar) +heatmap!(axZ, λ, φ, ζn, colorrange=(-2e-5, 2e-5), colormap=:redblue) display(fig) From e100e7af4e1da5eaf3c1adb745d9a324f81afdcb Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 16 Oct 2023 17:46:37 -0400 Subject: [PATCH 025/182] Update --- experiments/prototype_omip_simulation/omip_simulation.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index f5be8f55..2c06ce01 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -70,7 +70,7 @@ end # Grid construction arch = GPU() southern_limit = -79 -northern_limit = -50 +northern_limit = 85 j₁ = 4 * (90 + southern_limit) j₂ = 720 - 4 * (90 - northern_limit) + 1 Ny = j₂ - j₁ + 1 @@ -105,7 +105,7 @@ buoyancy = SeawaterBuoyancy(equation_of_state=teos10) using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: MixingLength using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: TurbulentKineticEnergyEquation -mixing_length = MixingLength(Cᵇ=0.1) +mixing_length = MixingLength(Cᵇ=0.01) turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) @@ -122,7 +122,7 @@ model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, set!(model, T=Tᵢ, S=Sᵢ) -simulation = Simulation(model, Δt=5minutes, stop_time=10days) +simulation = Simulation(model, Δt=5minutes, stop_time=360days) wall_clock = Ref(time_ns()) From f9f3dc37e09086d7228502b79cba608258482bc7 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 16 Oct 2023 17:53:22 -0400 Subject: [PATCH 026/182] Update Oceananigans compat --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 7159e1a8..5d2e7bf5 100644 --- a/Project.toml +++ b/Project.toml @@ -22,7 +22,7 @@ CUDA = "4, 5" CubicSplines = "0.2" DataDeps = "0.7" JLD2 = "0.4" -Oceananigans = "0.85" +Oceananigans = "0.89" SeawaterPolynomials = "0.3" KernelAbstractions = "0.9" NCDatasets = "0.12" From 4e0edd2fe256754f45e22ca9054235c70c520739 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 16 Oct 2023 18:52:32 -0400 Subject: [PATCH 027/182] Change Model to Models --- src/ClimaOcean.jl | 2 +- src/OceanSeaIceModels/AtmosphericForcings.jl | 203 ++++++++++++++++++ src/OceanSeaIceModels/OceanSeaIceModels.jl | 40 ++++ src/OceanSeaIceModels/model_utils.jl | 20 ++ .../ocean_only_model_fluxes.jl | 45 ++++ .../ocean_sea_ice_atmosphere_fluxes.jl | 191 ++++++++++++++++ src/OceanSeaIceModels/ocean_sea_ice_model.jl | 126 +++++++++++ 7 files changed, 626 insertions(+), 1 deletion(-) create mode 100644 src/OceanSeaIceModels/AtmosphericForcings.jl create mode 100644 src/OceanSeaIceModels/OceanSeaIceModels.jl create mode 100644 src/OceanSeaIceModels/model_utils.jl create mode 100644 src/OceanSeaIceModels/ocean_only_model_fluxes.jl create mode 100644 src/OceanSeaIceModels/ocean_sea_ice_atmosphere_fluxes.jl create mode 100644 src/OceanSeaIceModels/ocean_sea_ice_model.jl diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 2e7c146d..278be7f0 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -107,6 +107,6 @@ include("InitialConditions.jl") include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") include("IdealizedSimulations/IdealizedSimulations.jl") -include("OceanSeaIceModel/OceanSeaIceModel.jl") +include("OceanSeaIceModels/OceanSeaIceModels.jl") end # module diff --git a/src/OceanSeaIceModels/AtmosphericForcings.jl b/src/OceanSeaIceModels/AtmosphericForcings.jl new file mode 100644 index 00000000..158baeba --- /dev/null +++ b/src/OceanSeaIceModels/AtmosphericForcings.jl @@ -0,0 +1,203 @@ +module AtmosphericForcings + +export PrescribedAtmosphere, PrescribedFluxes + +using Adapt +using Oceananigans +using Oceananigans.Utils +using Oceananigans.BoundaryConditions: getbc +using KernelAbstractions: @kernel, @index + +import IceOceanModel: compute_air_sea_fluxes! + +abstract type AbstractAtmospericForcing end + +# We generally have 2 types of atmospheric forcing: Prescribed fluxes and +# Prescribed atmospheric state (to treat with bulk formulae) +# This implementation also allows to have in future a prognostic atmospheric model + +# Prescribed fluxes can be arrays, fields, of functions. +# When functions, the signature should be +# `f(i, j, grid, clock, fields)` where `fields` are the ocean model's prognostic fields +# in case of OnyOceanModel and the coupled model's prognostic fields in case of an `IceOceanModel` +# Parameters can be implemented using callable structs that subtype `Function` +struct PrescribedFluxes{T, S, U, V} <: AbstractAtmospericForcing + heat_flux :: T # heat flux + freshwater_flux :: S # freshwater flux + zonal_stress :: U # zonal stress + meriodional_stress :: V # meriodional stress +end + +Adapt.adapt_structure(to, f::PrescribedFluxes) = + PrescribedFluxes(Adapt.adapt(to, f.heat_flux), + Adapt.adapt(to, f.freshwater_flux), + Adapt.adapt(to, f.zonal_stress), + Adapt.adapt(to, f.meriodional_stress)) + +# Here we leverage a `getflux` function similar to the `getbc` from Oceananigans.jl to extract the fluxes, +# In this way we allow prescribed fluxes as well as relaxation fluxes +@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, grid, clock, fields, ice_thickness, solar_insolation, f::PrescribedFluxes) + i, j = @index(Global, NTuple) + @inbounds begin + I₀ = solar_insolation[i, j, 1] + Qˢ[i, j] = getflux(ice_thickness, f.heat_flux, i, j, grid, clock, fields) + ε * I₀ / (ρₒ * cₒ) + Fˢ[i, j] = getflux(ice_thickness, f.freshwater_fluxes, i, j, grid, clock, fields) + τˣ[i, j] = getflux(ice_thickness, f.zonal_stress, i, j, grid, clock, fields) + τʸ[i, j] = getflux(ice_thickness, f.meriodional_stress, i, j, grid, clock, fields) + end +end + +struct PrescribedAtmosphere{R, H, P, W, T, Q, D, C, G} <: AbstractAtmospericForcing + adiabatic_lapse_rate :: R # - + atmosphere_state_height :: H # m + reference_height :: H # m + surface_pressure :: P # Pa + atmosphere_velocities :: W # (m/s, m/s) + air_temperature :: T # deg ᵒC + air_humidity :: Q # kg/m³ + air_density :: D # kg/m³ + cloud_cover_feedback :: C # - + gamma_air :: C # - +end + +# The atmospheric state (T, u, v, q, ρ and p) can be composed of Values, Arrays, Functions, Fields or FieldTimeSerieses +function PrescribedAtmosphere(; + adiabatic_lapse_rate = 0.08, + atmosphere_state_height = 10, # m + reference_height = 10, # m + surface_pressure = 1e5, # Pa + atmosphere_velocities, # (m/s, m/s) + air_temperature, # deg ᵒC + air_humidity = 0.01, # kg/m³ + air_density = 1.25, # kg/m³ + cloud_cover_coeff = 0.8, + gamma_air = 0.01) + + return PrescribedAtmosphere(adiabatic_lapse_rate, + atmosphere_state_height, + reference_height, + surface_pressure, + atmosphere_velocities, + air_temperature, + air_humidity, + air_density, + cloud_cover_coeff, + gamma_air) +end + +Adapt.adapt_structure(to, f::PrescribedAtmosphere) = + PrescribedAtmosphere(Adapt.adapt(to, f.adiabatic_lapse_rate), + Adapt.adapt(to, f.atmosphere_state_height), + Adapt.adapt(to, f.reference_height), + Adapt.adapt(to, f.surface_pressure), + Adapt.adapt(to, f.atmosphere_velocities), + Adapt.adapt(to, f.air_temperature), + Adapt.adapt(to, f.air_humidity), + Adapt.adapt(to, f.air_density), + Adapt.adapt(to, f.cloud_cover_feedback), + Adapt.adapt(to, f.gamma_air)) + +@inline clausius_clapeyron(FT, Tₛ) = convert(FT, 611.2) * exp(convert(FT, 17.67) * Tₛ / (Tₛ + convert(FT, 243.5))) + +# Follows MITgcm, this is kind of a Placeholder for now. I ll check the literature for a correct parameterization +@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, ρₒ, cₒ, grid, clock, fields, ice_thickness, f::PrescribedAtmosphere) + + hᵀ = f.atmosphere_state_height + α = f.adiabatic_lapse_rate + uˢ, vˢ = f.atmosphere_velocities + + Tₐ = getflux(f.air_temperature, i, j, grid, clock, fields) + uₐ = getflux(uˢ, i, j, grid, clock, fields) + vₐ = getflux(vˢ, i, j, grid, clock, fields) + qₐ = getflux(f.air_humidity, i, j, grid, clock, fields) + ρₐ = getflux(f.air_density, i, j, grid, clock, fields) + p₀ = getflux(f.surface_pressure, i, j, grid, clock, fields) + + h = getflux(ice_thickness, i, j, grid, clock, fields) + ice_cell = (h == nothing) | (h > 0) + + @inbounds I₀ = solar_insolation[i, j, 1] + + FT = eltype(grid) + + speed = sqrt(uₐ^2 + vₐ^2) # speed m / s + γ = f.gamma_air + + # Physical constants + σ = convert(FT, σᴮ) # W/m²/K⁴ Stefan-Boltzmann constant + ℒ = convert(FT, ℒₑ) # J/kg Latent heat of evaporation + + Tₛ = fields.T[i, j, grid.Nz] + T₀ = Tₐ*(1 - γ * qₐ) + + # sea-air temperature difference + ΔT = T₀ - Tₛ + α*hᵀ + + # saturation vapour pressure (Pa) + eₛ = clausius_clapeyron(FT, Tₛ) + + # saturation air humidity (kg/m³) + qₛ = convert(FT, 0.622) * eₛ / (p₀ - eₛ) + + # air excess humidity + Δq = qₐ - qₛ + + # Turbulent heat transfer coefficients + Cᵀ, Cᵁ, Cq = turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) + + # sensible heat flux (W/m²) + H = ρₐ * speed * Cᵀ * Cᵁ * ΔT + + # latent heat flux (W/m²) + L = ρₐ * speed * Cq * Cᵁ * Δq * ℒ + + # net longwave radiation (W/m²) + Rₙ = ε * σ * (Tₛ + convert(FT, 273.15))^4 * (1 - f.cloud_cover_feedback) + + @inbounds begin + Qˢ[i, j, 1] = ifelse(ice_cell, zero(grid), (H + L + Rₙ + I₀ * ε) / (ρₒ * cₒ)) + # Fˢ[i, j, 1] = L / ℒ + τˣ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * speed * Cᵁ * uₐ / ρₒ) + τʸ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * speed * Cᵁ * vₐ / ρₒ) + end + + return nothing +end + +@inline turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) = (1e-3, 1e-3, 1e-3) + +#= +# Follows MITgcm (https://mitgcm.readthedocs.io/en/latest/phys_pkgs/bulk_force.html) +@inline function turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) + hᵀ = f.atmosphere_state_height + zᴿ = f.reference_height + λ = log(hᵀ / zᴿ) + κ = convert(FT, 0.4) # von Karman constant + + Cᵀ = Cᵁ = Cq = κ / log(zᴿ * 2) + u★ = Cᵁ * uₛ + T★ = Cᵀ * ΔT + q★ = Cq * Δq + + @unroll for iter in 1:5 + G = Γ(FT, u★, T★, q★, T₀, qₐ, f) + χ = sqrt(1 - 16 * G) + + ψˢ = ifelse(G > 0, -5G, 2 * log((1 + χ^2) / 2)) + ψᵐ = ifelse(G > 0, -5G, 2 * log((1 + χ) / 2) + ψˢ / 2 - 2 * atan(χ) + convert(FT, π/2)) + + Cᵁ = Cᵁ / (1 + Cᵁ * (λ - ψᵐ) / κ) + Cᵀ = Cᵀ / (1 + Cᵀ * (λ - ψˢ) / κ) + u★ = Cᵁ * uₛ + T★ = Cᵀ * ΔT + q★ = Cq * Δq + end + + return Cᵀ, Cᵁ, Cq +end +=# + +@inline Γ(FT, u★, T★, q★, T₀, qₐ, f) = convert(FT, 0.41) * convert(FT, 9.80655) * f.reference_height / u★^2 * + (T★ / T₀ - q★ / (1/f.gamma_air - qₐ)) + +end diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl new file mode 100644 index 00000000..c82fb906 --- /dev/null +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -0,0 +1,40 @@ +module OceanSeaIceModels + +using Oceananigans.Operators + +using Oceananigans.Architectures: architecture +using Oceananigans.BoundaryConditions: fill_halo_regions! +using Oceananigans.Models: AbstractModel +using Oceananigans.TimeSteppers: tick! +using Oceananigans.Utils: launch! + +using KernelAbstractions: @kernel, @index +using KernelAbstractions.Extras.LoopInfo: @unroll + +# Simulations interface +import Oceananigans: fields, prognostic_fields +import Oceananigans.Fields: set! +import Oceananigans.Models: timestepper, NaNChecker, default_nan_checker +import Oceananigans.OutputWriters: default_included_properties +import Oceananigans.Simulations: reset!, initialize!, iteration +import Oceananigans.TimeSteppers: time_step!, update_state!, time +import Oceananigans.Utils: prettytime + +const ℒₑ = 2.5e6 # J/kg Latent heat of evaporation +const σᴮ = 5.67e-8 # W/m²/K⁴ Stefan-Boltzmann constant + +include("ocean_sea_ice_model.jl") +include("ocean_sea_ice_atmosphere_fluxes.jl") +include("ocean_only_model_fluxes.jl") +include("AtmosphericForcings.jl") + +using .AtmosphericForcings + +# Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). +function default_nan_checker(model::OceanSeaIceModel) + u_ocean = model.ocean.model.velocities.u + nan_checker = NaNChecker((; u_ocean)) + return nan_checker +end + +end # module diff --git a/src/OceanSeaIceModels/model_utils.jl b/src/OceanSeaIceModels/model_utils.jl new file mode 100644 index 00000000..826e6b64 --- /dev/null +++ b/src/OceanSeaIceModels/model_utils.jl @@ -0,0 +1,20 @@ +using Oceananigans +using Oceananigans.Utils: Time +using Oceananigans.Grids: architecture +using Oceananigans.Models: AbstractModel +import Oceananigans.Grids: launch! + +launch!(model::AbstractModel, args...; kwargs...) = launch!(architecture(model.grid), model.grid, args...; kwargs...) + +@inline getflux(f::Nothing, i::Int, j::Int, grid::AbstractGrid, clock, fields) = nothing +@inline getflux(f::Number, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f +@inline getflux(f::Function, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f(i, j, grid, clock, fields) +@inline getflux(f::AbstractArray{<:Any, 2}, i::Int, j::Int, grid::AbstractGrid, args...) = @inbounds f[i, j] +@inline getflux(f::AbstractField, i::Int, j::Int, grid::AbstractGrid, args...) = @inbounds f[i, j, 1] +@inline getflux(f::FieldTimeSeries, i::Int, j::Int, grid::AbstractGrid, clock, args...) = @inbounds f[i, j, Time(clock.time)] + +# If we have ice, do not compute fluxes! +@inline function get_flux(ice_thickness, f, i::Int, j::Int, grid::AbstractGrid, args...) + h = @inbounds ice_thickness[i, j, 1] + return ifelse(h > 0, getflux(f, i, j, grid,args...), 0) +end \ No newline at end of file diff --git a/src/OceanSeaIceModels/ocean_only_model_fluxes.jl b/src/OceanSeaIceModels/ocean_only_model_fluxes.jl new file mode 100644 index 00000000..10a98535 --- /dev/null +++ b/src/OceanSeaIceModels/ocean_only_model_fluxes.jl @@ -0,0 +1,45 @@ + +##### +##### No ice-ocean fluxes in this model!! +##### + +compute_ice_ocean_salinity_flux!(::OnlyOceanModel) = nothing +ice_ocean_latent_heat!(::OnlyOceanModel) = nothing + +##### +##### Air-sea fluxes +##### + +function time_step!(coupled_model::OnlyOceanModel, Δt; callbacks=nothing) + compute_air_sea_flux!(coupled_model) + time_step!(ocean) + tick!(coupled_model.clock, Δt) + return nothing +end + +function compute_air_sea_fluxes!(coupled_model::OnlyOceanModel) + ocean = coupled_model.ocean + forcing = coupled_model.atmospheric_forcing + + (; T, S) = ocean.model.tracers + (; u, v) = ocean.model.velocities + + grid = ocean.model.grid + clock = ocean.model.clock + fields = prognostic_fields(ocean.model) + + Qˢ = T.boundary_conditions.top.condition + Fˢ = S.boundary_conditions.top.condition + τˣ = u.boundary_conditions.top.condition + τʸ = v.boundary_conditions.top.condition + + ε = coupled_model.ocean_emissivity + ρₒ = coupled_model.ocean_density + cₒ = coupled_model.ocean_heat_capacity + I₀ = coupled_model.solar_insolation + + launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, Iₒ, + grid, clock, fields, forcing, nothing) + + return nothing +end diff --git a/src/OceanSeaIceModels/ocean_sea_ice_atmosphere_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_atmosphere_fluxes.jl new file mode 100644 index 00000000..8c22b866 --- /dev/null +++ b/src/OceanSeaIceModels/ocean_sea_ice_atmosphere_fluxes.jl @@ -0,0 +1,191 @@ + +# If there is no atmosphere, do not compute fluxes! (this model has the ocean component which +# will handle the top boundary_conditions, for example if we want to impose a value BC) +compute_air_sea_flux!(coupled_model::NoAtmosphereModel) = nothing + +# Is this taken care of inside the ice model? Probably not because it is better to couple here than inside +compute_air_ice_flux!(coupled_model) = nothing + +function compute_air_sea_flux!(coupled_model) + ocean = coupled_model.ocean + forcing = coupled_model.atmospheric_forcing + + (; T, S) = ocean.model.tracers + (; u, v) = ocean.model.velocities + + grid = ocean.model.grid + clock = ocean.model.clock + fields = prognostic_fields(ocean.model) + + Qˢ = T.boundary_conditions.top.condition + Fˢ = S.boundary_conditions.top.condition + τˣ = u.boundary_conditions.top.condition + τʸ = v.boundary_conditions.top.condition + + ε = coupled_model.ocean_emissivity + ρₒ = coupled_model.ocean_density + cₒ = coupled_model.ocean_heat_capacity + I₀ = coupled_model.solar_insolation + + ice_thickness = coupled_model.ice.model.ice_thickness + + launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, I₀, + grid, clock, fields, forcing, ice_thickness) + + return nothing +end + +function compute_ice_ocean_flux!(coupled_model) + + # probably need to expand this + compute_ice_ocean_salinity_flux!(coupled_model) + ice_ocean_latent_heat!(coupled_model) + + return nothing +end + +function compute_ice_ocean_salinity_flux!(coupled_model) + # Compute salinity increment due to changes in ice thickness + + ice = coupled_model.ice + ocean = coupled_model.ocean + grid = ocean.model.grid + arch = architecture(grid) + Qˢ = ocean.model.tracers.S.boundary_conditions.top.condition + Sₒ = ocean.model.tracers.S + Sᵢ = ice.model.ice_salinity + Δt = ocean.Δt + hⁿ = ice.model.ice_thickness + h⁻ = coupled_model.previous_ice_thickness + + launch!(arch, grid, :xy, _compute_ice_ocean_salinity_flux!, + Qˢ, grid, hⁿ, h⁻, Sᵢ, Sₒ, Δt) + + return nothing +end + +@kernel function _compute_ice_ocean_salinity_flux!(ice_ocean_salinity_flux, + grid, + ice_thickness, + previous_ice_thickness, + ice_salinity, + ocean_salinity, + Δt) + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + + hⁿ = ice_thickness + h⁻ = previous_ice_thickness + Qˢ = ice_ocean_salinity_flux + Sᵢ = ice_salinity + Sₒ = ocean_salinity + + @inbounds begin + # Thickness of surface grid cell + Δh = hⁿ[i, j, 1] - h⁻[i, j, 1] + + # Update surface salinity flux. + # Note: the Δt below is the ocean time-step, eg. + # ΔS = ⋯ - ∮ Qˢ dt ≈ ⋯ - Δtₒ * Qˢ + Qˢ[i, j, 1] += Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) + + # Update previous ice thickness + h⁻[i, j, 1] = hⁿ[i, j, 1] + end +end + +function ice_ocean_latent_heat!(coupled_model) + ocean = coupled_model.ocean + ice = coupled_model.ice + ρₒ = coupled_model.ocean_density + cₒ = coupled_model.ocean_heat_capacity + Qₒ = ice.model.external_thermal_fluxes.bottom + Tₒ = ocean.model.tracers.T + Sₒ = ocean.model.tracers.S + Δt = ocean.Δt + hᵢ = ice.model.ice_thickness + + liquidus = ice.model.phase_transitions.liquidus + grid = ocean.model.grid + arch = architecture(grid) + + # What about the latent heat removed from the ocean when ice forms? + # Is it immediately removed from the ocean? Or is it stored in the ice? + launch!(arch, grid, :xy, _compute_ice_ocean_latent_heat!, + Qₒ, grid, hᵢ, Tₒ, Sₒ, liquidus, ρₒ, cₒ, Δt) + + return nothing +end + +@kernel function _compute_ice_ocean_latent_heat!(latent_heat, + grid, + ice_thickness, + ocean_temperature, + ocean_salinity, + liquidus, + ρₒ, cₒ, Δt) + + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + Qₒ = latent_heat + hᵢ = ice_thickness + Tₒ = ocean_temperature + Sₒ = ocean_salinity + + δQ = zero(grid) + icy_cell = @inbounds hᵢ[i, j, 1] > 0 # make ice bath approximation then + + @unroll for k = Nz:-1:1 + @inbounds begin + # Various quantities + Δz = Δzᶜᶜᶜ(i, j, k, grid) + Tᴺ = Tₒ[i, j, k] + Sᴺ = Sₒ[i, j, k] + end + + # Melting / freezing temperature at the surface of the ocean + Tₘ = melting_temperature(liquidus, Sᴺ) + + # Conditions for non-zero ice-ocean flux: + # - the ocean is below the freezing temperature, causing formation of ice. + freezing = Tᴺ < Tₘ + + # - We are at the surface and the cell is covered by ice. + icy_surface_cell = (k == Nz) & icy_cell + + # When there is a non-zero ice-ocean flux, we will instantaneously adjust the + # temperature of the grid cells accordingly. + adjust_temperature = freezing | icy_surface_cell + + # Compute change in ocean thermal energy. + # + # - When Tᴺ < Tₘ, we heat the ocean back to melting temperature by extracting heat from the ice, + # assuming that the heat flux (which is carried by nascent ice crystals called frazil ice) floats + # instantaneously to the surface. + # + # - When Tᴺ > Tₘ and we are in a surface cell covered by ice, we assume equilibrium + # and cool the ocean by injecting excess heat into the ice. + # + δEₒ = adjust_temperature * ρₒ * cₒ * (Tₘ - Tᴺ) + + # Perform temperature adjustment + @inline Tₒ[i, j, k] = ifelse(adjust_temperature, Tₘ, Tᴺ) + + # Compute the heat flux from ocean into ice. + # + # A positive value δQ > 0 implies that the ocean is cooled; ie heat + # is fluxing upwards, into the ice. This occurs when applying the + # ice bath equilibrium condition to cool down a warm ocean (δEₒ < 0). + # + # A negative value δQ < 0 implies that heat is fluxed from the ice into + # the ocean, cooling the ice and heating the ocean (δEₒ > 0). This occurs when + # frazil ice is formed within the ocean. + + δQ -= δEₒ * Δz / Δt + end + + # Store ice-ocean flux + @inbounds Qₒ[i, j, 1] = δQ +end diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl new file mode 100644 index 00000000..6d10d4b3 --- /dev/null +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -0,0 +1,126 @@ +using Oceananigans.Models: update_model_field_time_series! + +struct OceanSeaIceModel{FT, I, O, F, C, G, S, PI, PC} <: AbstractModel{Nothing} + clock :: C + grid :: G # TODO: make it so simulation does not require this + ice :: I + previous_ice_thickness :: PI + previous_ice_concentration :: PC + ocean :: O + atmospheric_forcing :: F + solar_insolation :: S + ocean_density :: FT + ocean_heat_capacity :: FT + ocean_emissivity :: FT + reference_temperature :: FT +end + +const OSIM = OceanSeaIceModel + +Base.summary(::OSIM) = "OceanSeaIceModel" +prettytime(model::OSIM) = prettytime(model.clock.time) +iteration(model::OSIM) = model.clock.iteration +timestepper(::OSIM) = nothing +reset!(::OSIM) = nothing +initialize!(::OSIM) = nothing +default_included_properties(::OSIM) = tuple() +update_state!(::OSIM) = nothing +prognostic_fields(cm::OSIM) = nothing +fields(::OSIM) = NamedTuple() +default_clock(TT) = Clock{TT}(0, 0, 1) + +# "Ocean only" +const OceanOnlyModel = OceanSeaIceModel{<:Any, Nothing} +const NoAtmosphereModel = OceanSeaIceModel{<:Any, <:Any, Nothing} + +OceanOnlyModel(ocean; atmospheric_forcing = nothing, clock = default_clock(eltype(ocean.model))) = + OceanSeaIceModel(nothing, ocean; atmospheric_forcing, clock) + +function OceanSeaIceModel(ice, ocean; + atmospheric_forcing = nothing, + clock = default_clock(eltype(ocean.model))) + + previous_ice_thickness = deepcopy(ice.model.ice_thickness) + previous_ice_concentration = deepcopy(ice.model.ice_concentration) + + grid = ocean.model.grid + ice_ocean_thermal_flux = Field{Center, Center, Nothing}(grid) + ice_ocean_salt_flux = Field{Center, Center, Nothing}(grid) + solar_insolation = Field{Center, Center, Nothing}(grid) + + ocean_density = 1024 + ocean_heat_capacity = 3991 + ocean_emissivity = 1 + reference_temperature = 273.15 + + # How would we ensure consistency? + try + if ice.model.external_thermal_fluxes.top isa RadiativeEmission + radiation = ice.model.external_thermal_fluxes.top + else + radiation = filter(flux isa RadiativeEmission, ice.model.external_thermal_fluxes.top) |> first + end + + reference_temperature = radiation.reference_temperature + catch + end + + FT = eltype(ocean.model.grid) + + return OceanSeaIceModel(clock, + ocean.model.grid, + ice, + previous_ice_thickness, + previous_ice_concentration, + ocean, + solar_insolation, + atmospheric_forcing, + convert(FT, ocean_density), + convert(FT, ocean_heat_capacity), + convert(FT, ocean_emissivity), + convert(FT, stefan_boltzmann_constant), + convert(FT, reference_temperature)) +end + +time(coupled_model::OceanSeaIceModel) = coupled_model.clock.time + +function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=nothing) + ocean = coupled_model.ocean + ice = coupled_model.ice + ice.Δt = Δt + ocean.Δt = Δt + + fill_halo_regions!(h) + + # Initialization + if coupled_model.clock.iteration == 0 + h⁻ = coupled_model.previous_ice_thickness + hⁿ = coupled_model.ice.model.ice_thickness + parent(h⁻) .= parent(hⁿ) + end + + time_step!(ice) + + # TODO: put this in update_state! + # Air-sea and Air-ice fluxes substitute the previous values + # while ice-ocean fluxes are additive + update_model_field_time_series!(coupled_model.atmospheric_forcing) + compute_air_sea_flux!(coupled_model) + compute_air_ice_flux!(coupled_model) # TODO: we need to implement this, not sure how + compute_ice_ocean_flux!(coupled_model) + + time_step!(ocean) + + # TODO: + # - Store fractional ice-free / ice-covered _time_ for more + # accurate flux computation? + # - Or, input "excess heat flux" into ocean after the ice melts + # - Currently, non-conservative for heat due bc we don't account for excess + + # TODO after ice time-step: + # - Adjust ocean temperature if the ice completely melts? + + tick!(coupled_model.clock, Δt) + + return nothing +end From bdfcf4f39b6645ac9fa518bbcbbe7c085b9178e3 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 16 Oct 2023 18:53:33 -0400 Subject: [PATCH 028/182] Fix name error --- src/OceanSeaIceModels/ocean_only_model_fluxes.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/ocean_only_model_fluxes.jl b/src/OceanSeaIceModels/ocean_only_model_fluxes.jl index 10a98535..40aa50a9 100644 --- a/src/OceanSeaIceModels/ocean_only_model_fluxes.jl +++ b/src/OceanSeaIceModels/ocean_only_model_fluxes.jl @@ -3,21 +3,21 @@ ##### No ice-ocean fluxes in this model!! ##### -compute_ice_ocean_salinity_flux!(::OnlyOceanModel) = nothing -ice_ocean_latent_heat!(::OnlyOceanModel) = nothing +compute_ice_ocean_salinity_flux!(::OceanOnlyModel) = nothing +ice_ocean_latent_heat!(::OceanOnlyModel) = nothing ##### ##### Air-sea fluxes ##### -function time_step!(coupled_model::OnlyOceanModel, Δt; callbacks=nothing) +function time_step!(coupled_model::OceanOnlyModel, Δt; callbacks=nothing) compute_air_sea_flux!(coupled_model) time_step!(ocean) tick!(coupled_model.clock, Δt) return nothing end -function compute_air_sea_fluxes!(coupled_model::OnlyOceanModel) +function compute_air_sea_fluxes!(coupled_model::OceanOnlyModel) ocean = coupled_model.ocean forcing = coupled_model.atmospheric_forcing From c37012dd8a294c15b4d62ac5b4c8f87ef31d81d8 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 16 Oct 2023 19:05:49 -0400 Subject: [PATCH 029/182] Comment out AtmosphericForcings for now --- src/OceanSeaIceModels/OceanSeaIceModels.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index c82fb906..cc8ee135 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -26,9 +26,8 @@ const σᴮ = 5.67e-8 # W/m²/K⁴ Stefan-Boltzmann constant include("ocean_sea_ice_model.jl") include("ocean_sea_ice_atmosphere_fluxes.jl") include("ocean_only_model_fluxes.jl") -include("AtmosphericForcings.jl") - -using .AtmosphericForcings +# include("AtmosphericForcings.jl") +# using .AtmosphericForcings # Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). function default_nan_checker(model::OceanSeaIceModel) From 87230762d1ccf9eac21bdf8060787bb7339f83ec Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 16 Oct 2023 19:16:53 -0400 Subject: [PATCH 030/182] Small updates --- src/OceanSeaIceModels/AtmosphericForcings.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/AtmosphericForcings.jl b/src/OceanSeaIceModels/AtmosphericForcings.jl index 158baeba..301cc2c1 100644 --- a/src/OceanSeaIceModels/AtmosphericForcings.jl +++ b/src/OceanSeaIceModels/AtmosphericForcings.jl @@ -36,7 +36,8 @@ Adapt.adapt_structure(to, f::PrescribedFluxes) = # Here we leverage a `getflux` function similar to the `getbc` from Oceananigans.jl to extract the fluxes, # In this way we allow prescribed fluxes as well as relaxation fluxes -@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, grid, clock, fields, ice_thickness, solar_insolation, f::PrescribedFluxes) +@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, + grid, clock, fields, ice_thickness, solar_insolation, f::PrescribedFluxes) i, j = @index(Global, NTuple) @inbounds begin I₀ = solar_insolation[i, j, 1] @@ -100,7 +101,8 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = @inline clausius_clapeyron(FT, Tₛ) = convert(FT, 611.2) * exp(convert(FT, 17.67) * Tₛ / (Tₛ + convert(FT, 243.5))) # Follows MITgcm, this is kind of a Placeholder for now. I ll check the literature for a correct parameterization -@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, ρₒ, cₒ, grid, clock, fields, ice_thickness, f::PrescribedAtmosphere) +@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, ρₒ, cₒ, + grid, clock, fields, ice_thickness, f::PrescribedAtmosphere) hᵀ = f.atmosphere_state_height α = f.adiabatic_lapse_rate @@ -128,7 +130,7 @@ Adapt.adapt_structure(to, f::PrescribedAtmosphere) = ℒ = convert(FT, ℒₑ) # J/kg Latent heat of evaporation Tₛ = fields.T[i, j, grid.Nz] - T₀ = Tₐ*(1 - γ * qₐ) + T₀ = Tₐ * (1 - γ * qₐ) # sea-air temperature difference ΔT = T₀ - Tₛ + α*hᵀ From 600dfed06d2e25a1a7b017d98bd4552b0602cafa Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 16 Oct 2023 19:17:02 -0400 Subject: [PATCH 031/182] Updates --- Manifest.toml | 283 ++++++++++-------- Project.toml | 7 +- .../prototype_omip_simulation/Manifest.toml | 166 ++++++++-- .../prototype_omip_simulation/Project.toml | 2 + .../omip_simulation.jl | 95 ++++-- src/OceanSeaIceModel/AtmosphericForcings.jl | 203 ------------- src/OceanSeaIceModel/OceanSeaIceModel.jl | 40 --- src/OceanSeaIceModel/model_utils.jl | 20 -- .../ocean_only_model_fluxes.jl | 45 --- .../ocean_sea_ice_atmosphere_fluxes.jl | 191 ------------ src/OceanSeaIceModel/ocean_sea_ice_model.jl | 128 -------- 11 files changed, 389 insertions(+), 791 deletions(-) delete mode 100644 src/OceanSeaIceModel/AtmosphericForcings.jl delete mode 100644 src/OceanSeaIceModel/OceanSeaIceModel.jl delete mode 100644 src/OceanSeaIceModel/model_utils.jl delete mode 100644 src/OceanSeaIceModel/ocean_only_model_fluxes.jl delete mode 100644 src/OceanSeaIceModel/ocean_sea_ice_atmosphere_fluxes.jl delete mode 100644 src/OceanSeaIceModel/ocean_sea_ice_model.jl diff --git a/Manifest.toml b/Manifest.toml index 57c93cca..1ee26247 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,19 +2,21 @@ julia_version = "1.9.2" manifest_format = "2.0" -project_hash = "fa00248e6adcad05196663f50c055df92ac20d71" +project_hash = "202c5bb7ddf918132608706362c09c6aa9ed5d99" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] -git-tree-sha1 = "cad4c758c0038eea30394b1b671526921ca85b21" +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.4.0" +version = "1.5.0" [deps.AbstractFFTs.extensions] AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" [deps.AbstractFFTs.weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] @@ -94,9 +96,9 @@ version = "0.1.2" [[deps.CUDA]] deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "Preferences", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "SpecialFunctions", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "35160ef0f03b14768abfd68b830f8e3940e8e0dc" +git-tree-sha1 = "968c1365e2992824c3e7a794e30907483f8469a9" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "4.4.0" +version = "4.4.1" [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] @@ -118,21 +120,21 @@ version = "0.6.0+0" [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "9c209fb7536406834aa938fb149964b985de6c83" +git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.1" +version = "0.7.3" [[deps.CommonDataModel]] deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf"] -git-tree-sha1 = "2678b3fc170d582655a14d22867b031b6e43c2d4" +git-tree-sha1 = "7f5717cbb2c1ce650cfd454451f282df33103596" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.2.4" +version = "0.2.5" [[deps.Compat]] deps = ["UUIDs"] -git-tree-sha1 = "4e88377ae7ebeaf29a047aa1ee40826e0b708a5d" +git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.7.0" +version = "4.10.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -149,6 +151,20 @@ git-tree-sha1 = "5372dbbf8f0bdb8c700db5367132925c0771ef7e" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" version = "2.2.1" +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.4" + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + + [deps.ConstructionBase.weakdeps] + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + [[deps.Crayons]] git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" @@ -156,9 +172,9 @@ version = "4.1.1" [[deps.CubedSphere]] deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] -git-tree-sha1 = "131498c78453d02b4821d8b93f6e44595399f19f" +git-tree-sha1 = "253193dfb0384646936c5ff3230b27a20d91261e" uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.2.3" +version = "0.2.4" [[deps.CubicSplines]] deps = ["Random", "Test"] @@ -179,9 +195,9 @@ version = "0.7.11" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "cf25ccb972fec4e4817764d01c82386ae94f77b4" +git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.14" +version = "0.18.15" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -192,6 +208,20 @@ version = "1.0.0" deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.10" + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + + [deps.Distances.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + [[deps.Distributed]] deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" @@ -219,9 +249,9 @@ uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" version = "0.1.9" [[deps.ExprTools]] -git-tree-sha1 = "c1d06d129da9f55715c6c212866f5b1bddc5fa00" +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.9" +version = "0.1.10" [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] @@ -269,15 +299,15 @@ version = "1.3.1" [[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 = "3b20c3ce9c14aedd0adca2bc8c882927844bd53d" +git-tree-sha1 = "38c8874692d48d5440d5752d6c74b0c6b0b60739" uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" -version = "1.14.0+0" +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 = "cb56ccdd481c0dd7f975ad2b3b62d9eda088f7e2" +git-tree-sha1 = "5eab648309e2e060198b45820af1a37182de3cce" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.9.14" +version = "1.10.0" [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" @@ -292,9 +322,9 @@ version = "0.2.1" [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "0cb9352ef2e01574eeebdb102948a58740dcaf83" +git-tree-sha1 = "ad37c091f7d7daf900963171600d7c1c5c3ede32" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2023.1.0+0" +version = "2023.2.0+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -318,27 +348,27 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "5df8278ad24772c0c6dbbeb97b162ccf29ced2a9" +git-tree-sha1 = "572d024660119ee626938419c14db0db5f3f3283" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.32" +version = "0.4.36" [[deps.JLLWrappers]] -deps = ["Preferences"] -git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1" +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.4.1" +version = "1.5.0" [[deps.JSON3]] deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] -git-tree-sha1 = "5b62d93f2582b09e469b3099d839c2d2ebf5066d" +git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -version = "1.13.1" +version = "1.13.2" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "6d08ca80b621635fed9cdfeb9a4280a574020bf3" +git-tree-sha1 = "5f1ecfddb6abde48563d08b2cc7e5116ebcd6c27" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.7" +version = "0.9.10" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -348,15 +378,15 @@ version = "0.9.7" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Printf", "Unicode"] -git-tree-sha1 = "8695a49bfe05a2dc0feeefd06b4ca6361a018729" +git-tree-sha1 = "4ea2928a96acfcf8589e6cd1429eff2a3a82c366" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.1.0" +version = "6.3.0" [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "c35203c1e1002747da220ffc3c0762ce7754b08c" +git-tree-sha1 = "e7c01b69bcbcb93fd4cbc3d0fea7d229541e18d2" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.23+0" +version = "0.0.26+0" [[deps.LLVMOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -391,10 +421,10 @@ version = "1.10.2+0" uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" [[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c7cb1f5d892775ba13767a87c7ada0b980ea0a71" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.16.1+2" +version = "1.17.0+0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -402,9 +432,9 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "c3ce8e7420b3a6e071e0fe4745f5d4300e37b13f" +git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.24" +version = "0.3.26" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -421,21 +451,21 @@ uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" [[deps.LoggingExtras]] deps = ["Dates", "Logging"] -git-tree-sha1 = "cedb76b37bc5a6c702ade66be44f831fa23c681e" +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.0.0" +version = "1.0.3" [[deps.MKL_jll]] deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "154d7aaa82d24db6d8f7e4ffcfe596f40bff214b" +git-tree-sha1 = "eb006abbd7041c28e0d16260e50a24f8f9104913" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2023.1.0+0" +version = "2023.2.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 = "98fc280a56d3b5cc218435f82df60e05771fefa6" +git-tree-sha1 = "b4d8707e42b693720b54f0b3434abee6dd4d947a" uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" -version = "0.20.12" +version = "0.20.16" [deps.MPI.extensions] AMDGPUExt = "AMDGPU" @@ -453,9 +483,9 @@ version = "4.1.2+0" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] -git-tree-sha1 = "d86a788b336e8ae96429c0c42740ccd60ac0dfcc" +git-tree-sha1 = "781916a2ebf2841467cda03b6f1af43e23839d85" uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.8" +version = "0.1.9" [[deps.MPItrampoline_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] @@ -465,9 +495,9 @@ version = "5.3.1+0" [[deps.MacroTools]] deps = ["Markdown", "Random"] -git-tree-sha1 = "42324d08725e200c23d4dfb549e0d5d89dede2d2" +git-tree-sha1 = "9ee1618cbf5240e6d4e0371d6f24065083f60c48" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.10" +version = "0.5.11" [[deps.Markdown]] deps = ["Base64"] @@ -486,9 +516,9 @@ version = "2.28.2+0" [[deps.MicrosoftMPI_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "a8027af3d1743b3bfae34e54872359fdebb31422" +git-tree-sha1 = "a7023883872e52bc29bcaac74f19adf39347d2d5" uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" -version = "10.1.3+4" +version = "10.1.4+0" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" @@ -514,12 +544,18 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.Oceananigans]] -deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "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 = "21653109691956b252ded2aaf0d6e1a8710abc36" -repo-rev = "glw/catke-parameter-refactor" +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 = "64809ab91971fdd59be66efcaa438ff5499b100d" +repo-rev = "main" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.85.0" +version = "0.89.2" + + [deps.Oceananigans.extensions] + OceananigansEnzymeCoreExt = "EnzymeCore" + + [deps.Oceananigans.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" [[deps.OffsetArrays]] deps = ["Adapt"] @@ -539,9 +575,9 @@ version = "0.8.1+0" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "f3080f4212a8ba2ceb10a34b938601b862094314" +git-tree-sha1 = "e25c1778a98e34219a00455d6e4384e017ea9762" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "4.1.5+0" +version = "4.1.6+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] @@ -551,9 +587,9 @@ version = "1.4.1" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cae3153c7f6cf3f069a853883fd1919a6e5bab5b" +git-tree-sha1 = "ceeda72c9fd6bbebc4f4f598560789145a8b6c4c" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.9+0" +version = "3.0.11+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -562,21 +598,27 @@ uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.5+0" [[deps.OrderedCollections]] -git-tree-sha1 = "d321bf2de576bf25ec4d3e4360faca399afca282" +git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.0" +version = "1.6.2" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "4b2e829ee66d4218e0cef22c0a64ee37cf258c29" +git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.7.1" +version = "2.7.2" [[deps.PencilArrays]] deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] -git-tree-sha1 = "c1d2b659ce423897de45e998f49f77e789e1859d" +git-tree-sha1 = "1a473d028436947e08436275ff3fcc2f3e9c5b06" uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.18.1" +version = "0.19.2" [deps.PencilArrays.extensions] PencilArraysDiffEqExt = ["DiffEqBase"] @@ -588,9 +630,9 @@ version = "0.18.1" [[deps.PencilFFTs]] deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] -git-tree-sha1 = "af200cef52069f3428127b237919d7c69eb6b10d" +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" -version = "0.15.0" +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"] @@ -599,21 +641,21 @@ version = "1.9.2" [[deps.PkgVersion]] deps = ["Pkg"] -git-tree-sha1 = "f6cf8e7944e50901594838951729a1861e668cb8" +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.2" +version = "0.3.3" [[deps.PrecompileTools]] deps = ["Preferences"] -git-tree-sha1 = "9673d39decc5feece56ef3940e5dafba15ba0f81" +git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.1.2" +version = "1.2.0" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "7eb1686b4f04b82f96ed7a4ea5890a4f0c7a09f1" +git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.0" +version = "1.4.1" [[deps.Printf]] deps = ["Unicode"] @@ -621,9 +663,9 @@ uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" [[deps.ProgressBars]] deps = ["Printf"] -git-tree-sha1 = "9d84c8646109eb8bc7a006d59b157c64d5155c81" +git-tree-sha1 = "b437cdb0385ed38312d91d9c00c20f3798b30256" uuid = "49802e3a-d2f1-5c88-81d8-b72133a6f568" -version = "1.5.0" +version = "1.5.1" [[deps.Quaternions]] deps = ["LinearAlgebra", "Random", "RealDot"] @@ -676,9 +718,9 @@ version = "1.3.0" [[deps.Rotations]] deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "54ccb4dbab4b1f69beb255a2c0ca5f65a9c82f08" +git-tree-sha1 = "0783924e4a332493f72490253ba4e668aeba1d73" uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.5.1" +version = "1.6.0" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" @@ -703,12 +745,6 @@ git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" version = "1.1.0" -[[deps.SnoopPrecompile]] -deps = ["Preferences"] -git-tree-sha1 = "e760a70afdcd461cf01a575947738d359234665c" -uuid = "66db9d55-30c0-4569-8b51-7e840670fc0c" -version = "1.0.3" - [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" @@ -718,9 +754,9 @@ uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "7beb031cf8145577fbccacd94b8a8f4ce78428d3" +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.0" +version = "2.3.1" [deps.SpecialFunctions.extensions] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -730,15 +766,15 @@ version = "2.3.0" [[deps.Static]] deps = ["IfElse"] -git-tree-sha1 = "dbde6766fc677423598138a5951269432b0fcc90" +git-tree-sha1 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "0.8.7" +version = "0.8.8" [[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "Requires", "SnoopPrecompile", "SparseArrays", "Static", "SuiteSparse"] -git-tree-sha1 = "33040351d2403b84afce74dae2e22d3f5b18edcb" +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "03fec6800a986d191f64f5c0996b59ed526eda25" uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.4.0" +version = "1.4.1" weakdeps = ["OffsetArrays", "StaticArrays"] [deps.StaticArrayInterface.extensions] @@ -747,18 +783,18 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "Random", "StaticArraysCore"] -git-tree-sha1 = "0da7e6b70d1bb40b1ace3b576da9ea2992f76318" +git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.6.0" +version = "1.6.5" weakdeps = ["Statistics"] [deps.StaticArrays.extensions] StaticArraysStatisticsExt = "Statistics" [[deps.StaticArraysCore]] -git-tree-sha1 = "1d5708d926c76a505052d0d24a846d5da08bc3a4" +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.1" +version = "1.4.2" [[deps.StaticPermutations]] git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" @@ -770,23 +806,33 @@ deps = ["LinearAlgebra", "SparseArrays"] uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" version = "1.9.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 = "b32eadf6ac726a790567fdc872b63117712e16a8" +git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" -version = "2.0.1" +version = "2.0.4" [[deps.StridedViews]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "59cc024139c20d1ed8400c419c6fe608637d583d" +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "cf857ff7de76f39e5daef6d032e8a74279ddff6a" uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" -version = "0.1.2" +version = "0.2.1" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" [[deps.StructArrays]] -deps = ["Adapt", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "521a0e828e98bb69042fec1809c1b5a680eb7389" +deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] +git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.15" +version = "0.6.16" [[deps.StructTypes]] deps = ["Dates", "UUIDs"] @@ -815,10 +861,10 @@ uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" version = "1.0.1" [[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"] -git-tree-sha1 = "1544b926975372da01227b382066ab70e574a3ec" +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.10.1" +version = "1.11.0" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -848,20 +894,23 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.23" [[deps.TranscodingStreams]] -deps = ["Random", "Test"] -git-tree-sha1 = "9a6ae7ed916312b41236fcef7e0af564ef934769" +git-tree-sha1 = "7c9196c8c83802d7b8ca7a6551a0236edd3bf731" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.9.13" +version = "0.10.0" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] [[deps.TupleTools]] -git-tree-sha1 = "3c712976c47707ff893cf6ba4354aa14db1d8938" +git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" -version = "1.3.0" +version = "1.4.3" [[deps.URIs]] -git-tree-sha1 = "074f993b0ca030848b897beff716d93aca60f06a" +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.4.2" +version = "1.5.1" [[deps.UUIDs]] deps = ["Random", "SHA"] @@ -887,10 +936,10 @@ uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" version = "1.3.0" [[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "93c41695bc1c08c46c5899f4fe06d6ead504bb73" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "24b81b59bd35b3c42ab84fa589086e19be919916" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.10.3+0" +version = "2.11.5+0" [[deps.Zlib_jll]] deps = ["Libdl"] diff --git a/Project.toml b/Project.toml index 5d2e7bf5..57fb9c94 100644 --- a/Project.toml +++ b/Project.toml @@ -5,6 +5,7 @@ authors = ["Climate Modeling Alliance and contributors"] version = "0.1.0" [deps] +Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" CubicSplines = "9c784101-8907-5a6d-9be6-98f00873c89b" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" @@ -21,12 +22,12 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" CUDA = "4, 5" CubicSplines = "0.2" DataDeps = "0.7" +Downloads = "1.6" JLD2 = "0.4" -Oceananigans = "0.89" -SeawaterPolynomials = "0.3" KernelAbstractions = "0.9" NCDatasets = "0.12" -Downloads = "1.6" +Oceananigans = "0.89" +SeawaterPolynomials = "0.3" Statistics = "1.9" julia = "1.8" diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 2d5853db..29178e23 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.9.2" manifest_format = "2.0" -project_hash = "380b86e0676891c46b83c0a9eb02cd35b3528a97" +project_hash = "883b87502c4a6df1ec75ae2bd27194c9ff4c7796" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -103,6 +103,11 @@ version = "0.4.2" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +[[deps.BitFlags]] +git-tree-sha1 = "43b1a4a8f797c1cddadf60499a8a077d4af2cd2d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.7" + [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" @@ -177,6 +182,26 @@ git-tree-sha1 = "e30f2f4e20f7f186dc36529910beaedc60cfa644" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" version = "1.16.0" +[[deps.ClimaOcean]] +deps = ["CUDA", "CubicSplines", "DataDeps", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "Statistics"] +path = "/home/greg/Projects/ClimaOcean.jl" +uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +version = "0.1.0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "1da46ce8a2a68abf692e16d414722fe628bd1c16" +repo-rev = "main" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.1.0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "02aa26a4cf76381be7f66e020a3eddeb27b0a092" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.2" + [[deps.ColorBrewer]] deps = ["Colors", "JSON", "Test"] git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" @@ -214,9 +239,14 @@ version = "1.0.2" [[deps.CommonDataModel]] deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf"] -git-tree-sha1 = "7f5717cbb2c1ce650cfd454451f282df33103596" +git-tree-sha1 = "2678b3fc170d582655a14d22867b031b6e43c2d4" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.2.5" +version = "0.2.4" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" [[deps.CommonSubexpressions]] deps = ["MacroTools", "Test"] @@ -239,6 +269,12 @@ deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.0.5+0" +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "5372dbbf8f0bdb8c700db5367132925c0771ef7e" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.2.1" + [[deps.ConstructionBase]] deps = ["LinearAlgebra"] git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" @@ -266,11 +302,23 @@ git-tree-sha1 = "131498c78453d02b4821d8b93f6e44595399f19f" uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" version = "0.2.3" +[[deps.CubicSplines]] +deps = ["Random", "Test"] +git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" +uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" +version = "0.2.1" + [[deps.DataAPI]] git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" version = "1.15.0" +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "p7zip_jll"] +git-tree-sha1 = "6e8d74545d34528c30ccd3fa0f3c00f8ed49584c" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.11" + [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" @@ -377,6 +425,12 @@ git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" version = "2.2.5" +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "e90caa41f5a86296e014e148ee061bd6c3edec96" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.9" + [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" @@ -523,9 +577,9 @@ version = "3.3.8+0" [[deps.GLMakie]] deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "b46b637cf3e1945354e77c016f867198b829d2f6" +git-tree-sha1 = "d7fe46f077c850f221c1f5b7b746a63c7e82b6b3" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.8.11" +version = "0.8.10" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] @@ -603,6 +657,12 @@ 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 = "5eab648309e2e060198b45820af1a37182de3cce" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.0" + [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" @@ -668,9 +728,9 @@ uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" version = "1.0.0" [[deps.Inflate]] -git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +git-tree-sha1 = "5cd07aab533df5170988219191dfad0519391428" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.4" +version = "0.1.3" [[deps.IntegerMathUtils]] git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" @@ -939,6 +999,12 @@ version = "0.3.26" [[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.MKL_jll]] deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] git-tree-sha1 = "eb006abbd7041c28e0d16260e50a24f8f9104913" @@ -985,15 +1051,15 @@ version = "0.5.11" [[deps.Makie]] deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "1d16d20279a145119899b4205258332f0fbeaa94" +git-tree-sha1 = "cf10f4b9d09da50f124ab7bcb530e57f700328f0" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.19.11" +version = "0.19.10" [[deps.MakieCore]] -deps = ["Observables", "REPL"] -git-tree-sha1 = "a94bf3fef9c690a2a4ac1d09d86a59ab89c7f8e4" +deps = ["Observables"] +git-tree-sha1 = "17d51182db2667962bc7e1d18b74881d0d0adbe6" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.6.8" +version = "0.6.7" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -1015,6 +1081,12 @@ git-tree-sha1 = "8f52dbaa1351ce4cb847d95568cb29e62a307d93" uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" version = "0.5.6" +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "Random", "Sockets"] +git-tree-sha1 = "03a9b9718f5682ecb107ac9f7308991db4ce395b" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.7" + [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" @@ -1108,10 +1180,18 @@ version = "0.5.4" [[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 = "e8caa94d03ec34434abc0fb036d43d34d1903411" +git-tree-sha1 = "64809ab91971fdd59be66efcaa438ff5499b100d" +repo-rev = "main" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.89.2" + [deps.Oceananigans.extensions] + OceananigansEnzymeCoreExt = "EnzymeCore" + + [deps.Oceananigans.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + [[deps.OffsetArrays]] deps = ["Adapt"] git-tree-sha1 = "2ac17d29c523ce1cd38e27785a7d23024853a4bb" @@ -1152,6 +1232,12 @@ git-tree-sha1 = "e25c1778a98e34219a00455d6e4384e017ea9762" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" version = "4.1.6+0" +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.1" + [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "ceeda72c9fd6bbebc4f4f598560789145a8b6c4c" @@ -1166,9 +1252,9 @@ version = "0.5.5+0" [[deps.Optim]] deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" +git-tree-sha1 = "963b004d15216f8129f6c0f7d187efa136570be0" uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.7.8" +version = "1.7.7" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1188,9 +1274,9 @@ version = "10.42.0+0" [[deps.PDMats]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "fcf8fd477bd7f33cb8dbb1243653fb0d415c256c" +git-tree-sha1 = "528664265c9c36b3ecdb6d721d47aaab52ddf267" uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.25" +version = "0.11.24" [[deps.PNGFiles]] deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] @@ -1230,9 +1316,9 @@ version = "2.7.2" [[deps.PencilArrays]] deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] -git-tree-sha1 = "1a473d028436947e08436275ff3fcc2f3e9c5b06" +git-tree-sha1 = "c1d2b659ce423897de45e998f49f77e789e1859d" uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.2" +version = "0.18.1" [deps.PencilArrays.extensions] PencilArraysDiffEqExt = ["DiffEqBase"] @@ -1412,9 +1498,9 @@ version = "1.2.2" [[deps.RelocatableFolders]] deps = ["SHA", "Scratch"] -git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +git-tree-sha1 = "90bc7a7c96410424509e4263e277e43250c05691" uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.1" +version = "1.0.0" [[deps.Requires]] deps = ["UUIDs"] @@ -1440,6 +1526,30 @@ git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" version = "0.4.0+0" +[[deps.RootSolvers]] +deps = ["ForwardDiff"] +git-tree-sha1 = "833d9914e748ca9329b762a82ec912897975f8d8" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.1" + +[[deps.Roots]] +deps = ["ChainRulesCore", "CommonSolve", "Printf", "Setfield"] +git-tree-sha1 = "06b5ac80ff1b88bd82df92c1c1875eea3954cd6e" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.0.20" + + [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 = "0783924e4a332493f72490253ba4e668aeba1d73" @@ -1502,6 +1612,11 @@ git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" version = "0.4.0" +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + [[deps.SimpleGraphs]] deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] git-tree-sha1 = "b608903049d11cc557c45e03b3a53e9260579c19" @@ -1722,9 +1837,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] -git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +git-tree-sha1 = "7fd97bd1c5b1ff53a291cbd351d1d3d6ff4da5a5" uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.6.8" +version = "0.6.7" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] @@ -1748,6 +1863,11 @@ git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" version = "1.4.3" +[[deps.URIs]] +git-tree-sha1 = "b7a5e99f24892b6824a954199a45e9ffcc1c70f0" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.0" + [[deps.UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml index d9eea3af..8a6e0746 100644 --- a/experiments/prototype_omip_simulation/Project.toml +++ b/experiments/prototype_omip_simulation/Project.toml @@ -1,4 +1,6 @@ [deps] +ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 2c06ce01..89de2928 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -1,9 +1,11 @@ using Oceananigans using Oceananigans.Units using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity +using ClimaOcean +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + using NCDatasets using GLMakie -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState using Printf using Downloads: download @@ -67,7 +69,10 @@ for i = 1:Nx, j = 1:Ny′ end end -# Grid construction +##### +##### Construct the grid +##### + arch = GPU() southern_limit = -79 northern_limit = 85 @@ -79,6 +84,7 @@ Tᵢ = Tᵢ[:, j₁:j₂, :] Sᵢ = Sᵢ[:, j₁:j₂, :] bottom_height = bottom_height[:, j₁:j₂] + grid = LatitudeLongitudeGrid(arch, size = (Nx, Ny, Nz), longitude = (0, 360), @@ -89,6 +95,18 @@ grid = LatitudeLongitudeGrid(arch, grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) +##### +##### Setup ice model +##### + +ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) +top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) +top_salt_flux = Qˢ = Field{Center, Center, Nothing}(grid) + +ocean_boundary_conditions = (T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Qˢ))) + +#= using Oceananigans.Grids: φnodes, λnodes λ = λnodes(grid, Center()) @@ -97,6 +115,7 @@ using Oceananigans.Grids: φnodes, λnodes fig = Figure() ax = Axis(fig[1, 1]) heatmap!(ax, λ, φ, bottom_height) +=# # Model construction teos10 = TEOS10EquationOfState() @@ -114,15 +133,47 @@ momentum_advection = VectorInvariant(vorticity_scheme = WENO(), divergence_scheme = WENO(), vertical_scheme = WENO()) -model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, - tracer_advection, momentum_advection, - tracers = (:T, :S, :e), - free_surface = SplitExplicitFreeSurface(cfl=0.2; grid), - coriolis = HydrostaticSphericalCoriolis()) - -set!(model, T=Tᵢ, S=Sᵢ) - -simulation = Simulation(model, Δt=5minutes, stop_time=360days) +ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, + tracer_advection, momentum_advection, + tracers = (:T, :S, :e), + free_surface = SplitExplicitFreeSurface(cfl=0.2; grid), + boundary_conditions = ocean_boundary_conditions, + coriolis = HydrostaticSphericalCoriolis()) + +set!(ocean_model, T=Tᵢ, S=Sᵢ) + +##### +##### Setup ice model +##### + +Nz = size(grid, 3) +So = ocean_model.tracers.S +ocean_surface_salinity = view(So, :, :, Nz) +bottom_bc = IceWaterThermalEquilibrium(ConstantField(30)) #ocean_surface_salinity) + +u, v, w = ocean_model.velocities +ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), + v = view(v, :, :, Nz), #interior(v, :, :, Nz), + w = ZeroField()) + +ice_model = SlabSeaIceModel(ice_grid; + velocities = ocean_surface_velocities, + advection = WENO(), + ice_consolidation_thickness = 0.05, + ice_salinity = 4, + internal_thermal_flux = ConductiveFlux(conductivity=2), + top_thermal_flux = ConstantField(0), # W m⁻² + top_thermal_boundary_condition = PrescribedTemperature(-2), + bottom_thermal_boundary_condition = bottom_bc, + bottom_thermal_flux = ice_ocean_heat_flux) + +set!(ice_model, h=hᵢ) + +#simulation = Simulation(model, Δt=5minutes, stop_time=360days) +ocean_simulation = Simulation(ocean_model; Δt=5minutes, verbose=false) +ice_simulation = Simulation(ice_model, Δt=5minutes, verbose=false) +coupled_model = IceOceanModel(ice_simulation, ocean_simulation) +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=5days) wall_clock = Ref(time_ns()) @@ -134,7 +185,7 @@ function progress(sim) msg2 = string(", wall time: ", prettytime(elapsed)) wall_clock[] = time_ns() - u, v, w = sim.model.velocities + u, v, w = sim.model.ocean.model.velocities msg3 = @sprintf(", max|u|: (%.2e, %.2e, %.2e)", maximum(abs, u), maximum(abs, v), @@ -146,21 +197,23 @@ end simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) using Oceananigans.Operators: ζ₃ᶠᶠᶜ -u, v, w = model.velocities +u, v, w = ocean_model.velocities ζ = KernelFunctionOperation{Face, Face, Center}(ζ₃ᶠᶠᶜ, grid, u, v) -outputs = merge(model.velocities, model.tracers, (; ζ)) +outputs = merge(ocean_model.velocities, ocean_model.tracers, (; ζ)) filename = "omip_surface_fields.jld2" -simulation.output_writers[:surface] = JLD2OutputWriter(model, outputs; filename, - schedule = TimeInterval(12hour), - indices = (:, :, Nz), - overwrite_existing = true) +ocean_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outputs; filename, + schedule = TimeInterval(12hour), + indices = (:, :, Nz), + overwrite_existing = true) + +run!(coupled_simulation) -run!(simulation) +##### +##### Visualize +##### -#Tt = FieldTimeSeries(filename, "T") -#St = FieldTimeSeries(filename, "S") et = FieldTimeSeries(filename, "e") ζt = FieldTimeSeries(filename, "ζ") times = et.times diff --git a/src/OceanSeaIceModel/AtmosphericForcings.jl b/src/OceanSeaIceModel/AtmosphericForcings.jl deleted file mode 100644 index 158baeba..00000000 --- a/src/OceanSeaIceModel/AtmosphericForcings.jl +++ /dev/null @@ -1,203 +0,0 @@ -module AtmosphericForcings - -export PrescribedAtmosphere, PrescribedFluxes - -using Adapt -using Oceananigans -using Oceananigans.Utils -using Oceananigans.BoundaryConditions: getbc -using KernelAbstractions: @kernel, @index - -import IceOceanModel: compute_air_sea_fluxes! - -abstract type AbstractAtmospericForcing end - -# We generally have 2 types of atmospheric forcing: Prescribed fluxes and -# Prescribed atmospheric state (to treat with bulk formulae) -# This implementation also allows to have in future a prognostic atmospheric model - -# Prescribed fluxes can be arrays, fields, of functions. -# When functions, the signature should be -# `f(i, j, grid, clock, fields)` where `fields` are the ocean model's prognostic fields -# in case of OnyOceanModel and the coupled model's prognostic fields in case of an `IceOceanModel` -# Parameters can be implemented using callable structs that subtype `Function` -struct PrescribedFluxes{T, S, U, V} <: AbstractAtmospericForcing - heat_flux :: T # heat flux - freshwater_flux :: S # freshwater flux - zonal_stress :: U # zonal stress - meriodional_stress :: V # meriodional stress -end - -Adapt.adapt_structure(to, f::PrescribedFluxes) = - PrescribedFluxes(Adapt.adapt(to, f.heat_flux), - Adapt.adapt(to, f.freshwater_flux), - Adapt.adapt(to, f.zonal_stress), - Adapt.adapt(to, f.meriodional_stress)) - -# Here we leverage a `getflux` function similar to the `getbc` from Oceananigans.jl to extract the fluxes, -# In this way we allow prescribed fluxes as well as relaxation fluxes -@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, grid, clock, fields, ice_thickness, solar_insolation, f::PrescribedFluxes) - i, j = @index(Global, NTuple) - @inbounds begin - I₀ = solar_insolation[i, j, 1] - Qˢ[i, j] = getflux(ice_thickness, f.heat_flux, i, j, grid, clock, fields) + ε * I₀ / (ρₒ * cₒ) - Fˢ[i, j] = getflux(ice_thickness, f.freshwater_fluxes, i, j, grid, clock, fields) - τˣ[i, j] = getflux(ice_thickness, f.zonal_stress, i, j, grid, clock, fields) - τʸ[i, j] = getflux(ice_thickness, f.meriodional_stress, i, j, grid, clock, fields) - end -end - -struct PrescribedAtmosphere{R, H, P, W, T, Q, D, C, G} <: AbstractAtmospericForcing - adiabatic_lapse_rate :: R # - - atmosphere_state_height :: H # m - reference_height :: H # m - surface_pressure :: P # Pa - atmosphere_velocities :: W # (m/s, m/s) - air_temperature :: T # deg ᵒC - air_humidity :: Q # kg/m³ - air_density :: D # kg/m³ - cloud_cover_feedback :: C # - - gamma_air :: C # - -end - -# The atmospheric state (T, u, v, q, ρ and p) can be composed of Values, Arrays, Functions, Fields or FieldTimeSerieses -function PrescribedAtmosphere(; - adiabatic_lapse_rate = 0.08, - atmosphere_state_height = 10, # m - reference_height = 10, # m - surface_pressure = 1e5, # Pa - atmosphere_velocities, # (m/s, m/s) - air_temperature, # deg ᵒC - air_humidity = 0.01, # kg/m³ - air_density = 1.25, # kg/m³ - cloud_cover_coeff = 0.8, - gamma_air = 0.01) - - return PrescribedAtmosphere(adiabatic_lapse_rate, - atmosphere_state_height, - reference_height, - surface_pressure, - atmosphere_velocities, - air_temperature, - air_humidity, - air_density, - cloud_cover_coeff, - gamma_air) -end - -Adapt.adapt_structure(to, f::PrescribedAtmosphere) = - PrescribedAtmosphere(Adapt.adapt(to, f.adiabatic_lapse_rate), - Adapt.adapt(to, f.atmosphere_state_height), - Adapt.adapt(to, f.reference_height), - Adapt.adapt(to, f.surface_pressure), - Adapt.adapt(to, f.atmosphere_velocities), - Adapt.adapt(to, f.air_temperature), - Adapt.adapt(to, f.air_humidity), - Adapt.adapt(to, f.air_density), - Adapt.adapt(to, f.cloud_cover_feedback), - Adapt.adapt(to, f.gamma_air)) - -@inline clausius_clapeyron(FT, Tₛ) = convert(FT, 611.2) * exp(convert(FT, 17.67) * Tₛ / (Tₛ + convert(FT, 243.5))) - -# Follows MITgcm, this is kind of a Placeholder for now. I ll check the literature for a correct parameterization -@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, ρₒ, cₒ, grid, clock, fields, ice_thickness, f::PrescribedAtmosphere) - - hᵀ = f.atmosphere_state_height - α = f.adiabatic_lapse_rate - uˢ, vˢ = f.atmosphere_velocities - - Tₐ = getflux(f.air_temperature, i, j, grid, clock, fields) - uₐ = getflux(uˢ, i, j, grid, clock, fields) - vₐ = getflux(vˢ, i, j, grid, clock, fields) - qₐ = getflux(f.air_humidity, i, j, grid, clock, fields) - ρₐ = getflux(f.air_density, i, j, grid, clock, fields) - p₀ = getflux(f.surface_pressure, i, j, grid, clock, fields) - - h = getflux(ice_thickness, i, j, grid, clock, fields) - ice_cell = (h == nothing) | (h > 0) - - @inbounds I₀ = solar_insolation[i, j, 1] - - FT = eltype(grid) - - speed = sqrt(uₐ^2 + vₐ^2) # speed m / s - γ = f.gamma_air - - # Physical constants - σ = convert(FT, σᴮ) # W/m²/K⁴ Stefan-Boltzmann constant - ℒ = convert(FT, ℒₑ) # J/kg Latent heat of evaporation - - Tₛ = fields.T[i, j, grid.Nz] - T₀ = Tₐ*(1 - γ * qₐ) - - # sea-air temperature difference - ΔT = T₀ - Tₛ + α*hᵀ - - # saturation vapour pressure (Pa) - eₛ = clausius_clapeyron(FT, Tₛ) - - # saturation air humidity (kg/m³) - qₛ = convert(FT, 0.622) * eₛ / (p₀ - eₛ) - - # air excess humidity - Δq = qₐ - qₛ - - # Turbulent heat transfer coefficients - Cᵀ, Cᵁ, Cq = turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) - - # sensible heat flux (W/m²) - H = ρₐ * speed * Cᵀ * Cᵁ * ΔT - - # latent heat flux (W/m²) - L = ρₐ * speed * Cq * Cᵁ * Δq * ℒ - - # net longwave radiation (W/m²) - Rₙ = ε * σ * (Tₛ + convert(FT, 273.15))^4 * (1 - f.cloud_cover_feedback) - - @inbounds begin - Qˢ[i, j, 1] = ifelse(ice_cell, zero(grid), (H + L + Rₙ + I₀ * ε) / (ρₒ * cₒ)) - # Fˢ[i, j, 1] = L / ℒ - τˣ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * speed * Cᵁ * uₐ / ρₒ) - τʸ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * speed * Cᵁ * vₐ / ρₒ) - end - - return nothing -end - -@inline turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) = (1e-3, 1e-3, 1e-3) - -#= -# Follows MITgcm (https://mitgcm.readthedocs.io/en/latest/phys_pkgs/bulk_force.html) -@inline function turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) - hᵀ = f.atmosphere_state_height - zᴿ = f.reference_height - λ = log(hᵀ / zᴿ) - κ = convert(FT, 0.4) # von Karman constant - - Cᵀ = Cᵁ = Cq = κ / log(zᴿ * 2) - u★ = Cᵁ * uₛ - T★ = Cᵀ * ΔT - q★ = Cq * Δq - - @unroll for iter in 1:5 - G = Γ(FT, u★, T★, q★, T₀, qₐ, f) - χ = sqrt(1 - 16 * G) - - ψˢ = ifelse(G > 0, -5G, 2 * log((1 + χ^2) / 2)) - ψᵐ = ifelse(G > 0, -5G, 2 * log((1 + χ) / 2) + ψˢ / 2 - 2 * atan(χ) + convert(FT, π/2)) - - Cᵁ = Cᵁ / (1 + Cᵁ * (λ - ψᵐ) / κ) - Cᵀ = Cᵀ / (1 + Cᵀ * (λ - ψˢ) / κ) - u★ = Cᵁ * uₛ - T★ = Cᵀ * ΔT - q★ = Cq * Δq - end - - return Cᵀ, Cᵁ, Cq -end -=# - -@inline Γ(FT, u★, T★, q★, T₀, qₐ, f) = convert(FT, 0.41) * convert(FT, 9.80655) * f.reference_height / u★^2 * - (T★ / T₀ - q★ / (1/f.gamma_air - qₐ)) - -end diff --git a/src/OceanSeaIceModel/OceanSeaIceModel.jl b/src/OceanSeaIceModel/OceanSeaIceModel.jl deleted file mode 100644 index 0daead91..00000000 --- a/src/OceanSeaIceModel/OceanSeaIceModel.jl +++ /dev/null @@ -1,40 +0,0 @@ -module OceanSeaIceModel - -using Oceananigans.Operators - -using Oceananigans.Architectures: architecture -using Oceananigans.BoundaryConditions: fill_halo_regions! -using Oceananigans.Models: AbstractModel -using Oceananigans.TimeSteppers: tick! -using Oceananigans.Utils: launch! - -using KernelAbstractions: @kernel, @index -using KernelAbstractions.Extras.LoopInfo: @unroll - -# Simulations interface -import Oceananigans: fields, prognostic_fields -import Oceananigans.Fields: set! -import Oceananigans.Models: timestepper, NaNChecker, default_nan_checker -import Oceananigans.OutputWriters: default_included_properties -import Oceananigans.Simulations: reset!, initialize!, iteration -import Oceananigans.TimeSteppers: time_step!, update_state!, time -import Oceananigans.Utils: prettytime - -const ℒₑ = 2.5e6 # J/kg Latent heat of evaporation -const σᴮ = 5.67e-8 # W/m²/K⁴ Stefan-Boltzmann constant - -include("ocean_sea_ice_model.jl") -include("ocean_sea_ice_atmosphere_fluxes.jl") -include("ocean_only_model_fluxes.jl") -include("AtmosphericForcings.jl") - -using .AtmosphericForcings - -# Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). -function default_nan_checker(model::OceanSeaIceModel) - u_ocean = model.ocean.model.velocities.u - nan_checker = NaNChecker((; u_ocean)) - return nan_checker -end - -end # module diff --git a/src/OceanSeaIceModel/model_utils.jl b/src/OceanSeaIceModel/model_utils.jl deleted file mode 100644 index 826e6b64..00000000 --- a/src/OceanSeaIceModel/model_utils.jl +++ /dev/null @@ -1,20 +0,0 @@ -using Oceananigans -using Oceananigans.Utils: Time -using Oceananigans.Grids: architecture -using Oceananigans.Models: AbstractModel -import Oceananigans.Grids: launch! - -launch!(model::AbstractModel, args...; kwargs...) = launch!(architecture(model.grid), model.grid, args...; kwargs...) - -@inline getflux(f::Nothing, i::Int, j::Int, grid::AbstractGrid, clock, fields) = nothing -@inline getflux(f::Number, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f -@inline getflux(f::Function, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f(i, j, grid, clock, fields) -@inline getflux(f::AbstractArray{<:Any, 2}, i::Int, j::Int, grid::AbstractGrid, args...) = @inbounds f[i, j] -@inline getflux(f::AbstractField, i::Int, j::Int, grid::AbstractGrid, args...) = @inbounds f[i, j, 1] -@inline getflux(f::FieldTimeSeries, i::Int, j::Int, grid::AbstractGrid, clock, args...) = @inbounds f[i, j, Time(clock.time)] - -# If we have ice, do not compute fluxes! -@inline function get_flux(ice_thickness, f, i::Int, j::Int, grid::AbstractGrid, args...) - h = @inbounds ice_thickness[i, j, 1] - return ifelse(h > 0, getflux(f, i, j, grid,args...), 0) -end \ No newline at end of file diff --git a/src/OceanSeaIceModel/ocean_only_model_fluxes.jl b/src/OceanSeaIceModel/ocean_only_model_fluxes.jl deleted file mode 100644 index 10a98535..00000000 --- a/src/OceanSeaIceModel/ocean_only_model_fluxes.jl +++ /dev/null @@ -1,45 +0,0 @@ - -##### -##### No ice-ocean fluxes in this model!! -##### - -compute_ice_ocean_salinity_flux!(::OnlyOceanModel) = nothing -ice_ocean_latent_heat!(::OnlyOceanModel) = nothing - -##### -##### Air-sea fluxes -##### - -function time_step!(coupled_model::OnlyOceanModel, Δt; callbacks=nothing) - compute_air_sea_flux!(coupled_model) - time_step!(ocean) - tick!(coupled_model.clock, Δt) - return nothing -end - -function compute_air_sea_fluxes!(coupled_model::OnlyOceanModel) - ocean = coupled_model.ocean - forcing = coupled_model.atmospheric_forcing - - (; T, S) = ocean.model.tracers - (; u, v) = ocean.model.velocities - - grid = ocean.model.grid - clock = ocean.model.clock - fields = prognostic_fields(ocean.model) - - Qˢ = T.boundary_conditions.top.condition - Fˢ = S.boundary_conditions.top.condition - τˣ = u.boundary_conditions.top.condition - τʸ = v.boundary_conditions.top.condition - - ε = coupled_model.ocean_emissivity - ρₒ = coupled_model.ocean_density - cₒ = coupled_model.ocean_heat_capacity - I₀ = coupled_model.solar_insolation - - launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, Iₒ, - grid, clock, fields, forcing, nothing) - - return nothing -end diff --git a/src/OceanSeaIceModel/ocean_sea_ice_atmosphere_fluxes.jl b/src/OceanSeaIceModel/ocean_sea_ice_atmosphere_fluxes.jl deleted file mode 100644 index 8c22b866..00000000 --- a/src/OceanSeaIceModel/ocean_sea_ice_atmosphere_fluxes.jl +++ /dev/null @@ -1,191 +0,0 @@ - -# If there is no atmosphere, do not compute fluxes! (this model has the ocean component which -# will handle the top boundary_conditions, for example if we want to impose a value BC) -compute_air_sea_flux!(coupled_model::NoAtmosphereModel) = nothing - -# Is this taken care of inside the ice model? Probably not because it is better to couple here than inside -compute_air_ice_flux!(coupled_model) = nothing - -function compute_air_sea_flux!(coupled_model) - ocean = coupled_model.ocean - forcing = coupled_model.atmospheric_forcing - - (; T, S) = ocean.model.tracers - (; u, v) = ocean.model.velocities - - grid = ocean.model.grid - clock = ocean.model.clock - fields = prognostic_fields(ocean.model) - - Qˢ = T.boundary_conditions.top.condition - Fˢ = S.boundary_conditions.top.condition - τˣ = u.boundary_conditions.top.condition - τʸ = v.boundary_conditions.top.condition - - ε = coupled_model.ocean_emissivity - ρₒ = coupled_model.ocean_density - cₒ = coupled_model.ocean_heat_capacity - I₀ = coupled_model.solar_insolation - - ice_thickness = coupled_model.ice.model.ice_thickness - - launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, I₀, - grid, clock, fields, forcing, ice_thickness) - - return nothing -end - -function compute_ice_ocean_flux!(coupled_model) - - # probably need to expand this - compute_ice_ocean_salinity_flux!(coupled_model) - ice_ocean_latent_heat!(coupled_model) - - return nothing -end - -function compute_ice_ocean_salinity_flux!(coupled_model) - # Compute salinity increment due to changes in ice thickness - - ice = coupled_model.ice - ocean = coupled_model.ocean - grid = ocean.model.grid - arch = architecture(grid) - Qˢ = ocean.model.tracers.S.boundary_conditions.top.condition - Sₒ = ocean.model.tracers.S - Sᵢ = ice.model.ice_salinity - Δt = ocean.Δt - hⁿ = ice.model.ice_thickness - h⁻ = coupled_model.previous_ice_thickness - - launch!(arch, grid, :xy, _compute_ice_ocean_salinity_flux!, - Qˢ, grid, hⁿ, h⁻, Sᵢ, Sₒ, Δt) - - return nothing -end - -@kernel function _compute_ice_ocean_salinity_flux!(ice_ocean_salinity_flux, - grid, - ice_thickness, - previous_ice_thickness, - ice_salinity, - ocean_salinity, - Δt) - i, j = @index(Global, NTuple) - - Nz = size(grid, 3) - - hⁿ = ice_thickness - h⁻ = previous_ice_thickness - Qˢ = ice_ocean_salinity_flux - Sᵢ = ice_salinity - Sₒ = ocean_salinity - - @inbounds begin - # Thickness of surface grid cell - Δh = hⁿ[i, j, 1] - h⁻[i, j, 1] - - # Update surface salinity flux. - # Note: the Δt below is the ocean time-step, eg. - # ΔS = ⋯ - ∮ Qˢ dt ≈ ⋯ - Δtₒ * Qˢ - Qˢ[i, j, 1] += Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) - - # Update previous ice thickness - h⁻[i, j, 1] = hⁿ[i, j, 1] - end -end - -function ice_ocean_latent_heat!(coupled_model) - ocean = coupled_model.ocean - ice = coupled_model.ice - ρₒ = coupled_model.ocean_density - cₒ = coupled_model.ocean_heat_capacity - Qₒ = ice.model.external_thermal_fluxes.bottom - Tₒ = ocean.model.tracers.T - Sₒ = ocean.model.tracers.S - Δt = ocean.Δt - hᵢ = ice.model.ice_thickness - - liquidus = ice.model.phase_transitions.liquidus - grid = ocean.model.grid - arch = architecture(grid) - - # What about the latent heat removed from the ocean when ice forms? - # Is it immediately removed from the ocean? Or is it stored in the ice? - launch!(arch, grid, :xy, _compute_ice_ocean_latent_heat!, - Qₒ, grid, hᵢ, Tₒ, Sₒ, liquidus, ρₒ, cₒ, Δt) - - return nothing -end - -@kernel function _compute_ice_ocean_latent_heat!(latent_heat, - grid, - ice_thickness, - ocean_temperature, - ocean_salinity, - liquidus, - ρₒ, cₒ, Δt) - - i, j = @index(Global, NTuple) - - Nz = size(grid, 3) - Qₒ = latent_heat - hᵢ = ice_thickness - Tₒ = ocean_temperature - Sₒ = ocean_salinity - - δQ = zero(grid) - icy_cell = @inbounds hᵢ[i, j, 1] > 0 # make ice bath approximation then - - @unroll for k = Nz:-1:1 - @inbounds begin - # Various quantities - Δz = Δzᶜᶜᶜ(i, j, k, grid) - Tᴺ = Tₒ[i, j, k] - Sᴺ = Sₒ[i, j, k] - end - - # Melting / freezing temperature at the surface of the ocean - Tₘ = melting_temperature(liquidus, Sᴺ) - - # Conditions for non-zero ice-ocean flux: - # - the ocean is below the freezing temperature, causing formation of ice. - freezing = Tᴺ < Tₘ - - # - We are at the surface and the cell is covered by ice. - icy_surface_cell = (k == Nz) & icy_cell - - # When there is a non-zero ice-ocean flux, we will instantaneously adjust the - # temperature of the grid cells accordingly. - adjust_temperature = freezing | icy_surface_cell - - # Compute change in ocean thermal energy. - # - # - When Tᴺ < Tₘ, we heat the ocean back to melting temperature by extracting heat from the ice, - # assuming that the heat flux (which is carried by nascent ice crystals called frazil ice) floats - # instantaneously to the surface. - # - # - When Tᴺ > Tₘ and we are in a surface cell covered by ice, we assume equilibrium - # and cool the ocean by injecting excess heat into the ice. - # - δEₒ = adjust_temperature * ρₒ * cₒ * (Tₘ - Tᴺ) - - # Perform temperature adjustment - @inline Tₒ[i, j, k] = ifelse(adjust_temperature, Tₘ, Tᴺ) - - # Compute the heat flux from ocean into ice. - # - # A positive value δQ > 0 implies that the ocean is cooled; ie heat - # is fluxing upwards, into the ice. This occurs when applying the - # ice bath equilibrium condition to cool down a warm ocean (δEₒ < 0). - # - # A negative value δQ < 0 implies that heat is fluxed from the ice into - # the ocean, cooling the ice and heating the ocean (δEₒ > 0). This occurs when - # frazil ice is formed within the ocean. - - δQ -= δEₒ * Δz / Δt - end - - # Store ice-ocean flux - @inbounds Qₒ[i, j, 1] = δQ -end diff --git a/src/OceanSeaIceModel/ocean_sea_ice_model.jl b/src/OceanSeaIceModel/ocean_sea_ice_model.jl deleted file mode 100644 index 1527691c..00000000 --- a/src/OceanSeaIceModel/ocean_sea_ice_model.jl +++ /dev/null @@ -1,128 +0,0 @@ -using Oceananigans.OutputReaders: update_model_field_time_series! - -struct IceOceanModel{FT, I, O, F, C, G, S, PI, PC} <: AbstractModel{Nothing} - clock :: C - grid :: G # TODO: make it so simulation does not require this - ice :: I - previous_ice_thickness :: PI - previous_ice_concentration :: PC - ocean :: O - atmospheric_forcing :: F - solar_insolation :: S - ocean_density :: FT - ocean_heat_capacity :: FT - ocean_emissivity :: FT - reference_temperature :: FT -end - -Base.summary(::IOM) = "IceOceanModel" -prettytime(model::IOM) = prettytime(model.clock.time) -iteration(model::IOM) = model.clock.iteration -timestepper(::IOM) = nothing -reset!(::IOM) = nothing -initialize!(::IOM) = nothing -default_included_properties(::IOM) = tuple() -update_state!(::IOM) = nothing -prognostic_fields(cm::IOM) = nothing -fields(::IOM) = NamedTuple() - - -default_clock(FT) = Clock{FT}(0, 0, 1) - -const IOM = IceOceanModel - -# "Ocean only" -const OceanOnlyModel = IceOceanModel{<:Any, Nothing} -const NoAtmosphereModel = IceOceanModel{<:Any, <:Any, Nothing} - -OceanOnlyModel(ocean; atmospheric_forcing = nothing, clock = default_clock(eltype(ocean.model))) = - IceOceanModel(nothing, ocean; atmospheric_forcing, clock) - -function IceOceanModel(ice, ocean; - atmospheric_forcing = nothing, - clock = default_clock(eltype(ocean.model))) - - previous_ice_thickness = deepcopy(ice.model.ice_thickness) - previous_ice_concentration = deepcopy(ice.model.ice_concentration) - - grid = ocean.model.grid - ice_ocean_thermal_flux = Field{Center, Center, Nothing}(grid) - ice_ocean_salt_flux = Field{Center, Center, Nothing}(grid) - solar_insolation = Field{Center, Center, Nothing}(grid) - - ocean_density = 1024 - ocean_heat_capacity = 3991 - ocean_emissivity = 1 - reference_temperature = 273.15 - - # How would we ensure consistency? - try - if ice.model.external_thermal_fluxes.top isa RadiativeEmission - radiation = ice.model.external_thermal_fluxes.top - else - radiation = filter(flux isa RadiativeEmission, ice.model.external_thermal_fluxes.top) |> first - end - - reference_temperature = radiation.reference_temperature - catch - end - - FT = eltype(ocean.model.grid) - - return IceOceanModel(clock, - ocean.model.grid, - ice, - previous_ice_thickness, - previous_ice_concentration, - ocean, - solar_insolation, - atmospheric_forcing, - convert(FT, ocean_density), - convert(FT, ocean_heat_capacity), - convert(FT, ocean_emissivity), - convert(FT, stefan_boltzmann_constant), - convert(FT, reference_temperature)) -end - -time(coupled_model::IceOceanModel) = coupled_model.clock.time - -function time_step!(coupled_model::IceOceanModel, Δt; callbacks=nothing) - ocean = coupled_model.ocean - ice = coupled_model.ice - ice.Δt = Δt - ocean.Δt = Δt - - fill_halo_regions!(h) - - # Initialization - if coupled_model.clock.iteration == 0 - h⁻ = coupled_model.previous_ice_thickness - hⁿ = coupled_model.ice.model.ice_thickness - parent(h⁻) .= parent(hⁿ) - end - - time_step!(ice) - - # TODO: put this in update_state! - # Air-sea and Air-ice fluxes substitute the previous values - # while ice-ocean fluxes are additive - update_model_field_time_series!(coupled_model.atmospheric_forcing) - compute_air_sea_flux!(coupled_model) - compute_air_ice_flux!(coupled_model) # TODO: we need to implement this, not sure how - compute_ice_ocean_flux!(coupled_model) - - time_step!(ocean) - - # TODO: - # - Store fractional ice-free / ice-covered _time_ for more - # accurate flux computation? - # - Or, input "excess heat flux" into ocean after the ice melts - # - Currently, non-conservative for heat due bc we don't account for excess - - # TODO after ice time-step: - # - Adjust ocean temperature if the ice completely melts? - - tick!(coupled_model.clock, Δt) - - return nothing -end From 49021afb9d0324260239aa1022c478a22e46b254 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 20 Oct 2023 13:44:20 -0400 Subject: [PATCH 032/182] Major updates and cleanup --- Manifest.toml | 107 +++++++- Project.toml | 1 + .../prototype_omip_simulation/Manifest.toml | 233 ++++++++++++------ .../omip_simulation.jl | 155 ++++++++---- src/OceanSeaIceModels/OceanSeaIceModels.jl | 20 +- .../PrescribedAtmospheres.jl} | 0 .../atmosphere_ocean_fluxes.jl | 34 +++ .../atmosphere_sea_ice_fluxes.jl | 3 + .../{model_utils.jl => getflux.jl} | 14 +- ...ly_model_fluxes.jl => ocean_only_model.jl} | 3 + src/OceanSeaIceModels/ocean_sea_ice_model.jl | 95 +++---- ...here_fluxes.jl => sea_ice_ocean_fluxes.jl} | 113 ++++----- 12 files changed, 508 insertions(+), 270 deletions(-) rename src/OceanSeaIceModels/{AtmosphericForcings.jl => PrescribedAtmospheres/PrescribedAtmospheres.jl} (100%) create mode 100644 src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl create mode 100644 src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl rename src/OceanSeaIceModels/{model_utils.jl => getflux.jl} (69%) rename src/OceanSeaIceModels/{ocean_only_model_fluxes.jl => ocean_only_model.jl} (90%) rename src/OceanSeaIceModels/{ocean_sea_ice_atmosphere_fluxes.jl => sea_ice_ocean_fluxes.jl} (56%) diff --git a/Manifest.toml b/Manifest.toml index 1ee26247..c8e3a7e5 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,22 +2,19 @@ julia_version = "1.9.2" manifest_format = "2.0" -project_hash = "202c5bb7ddf918132608706362c09c6aa9ed5d99" +project_hash = "db9e6e46e42e01824b854eb0662da74762108c6b" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] [deps.AbstractFFTs.extensions] AbstractFFTsChainRulesCoreExt = "ChainRulesCore" AbstractFFTsTestExt = "Test" - [deps.AbstractFFTs.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] git-tree-sha1 = "76289dc51920fdc6e0013c872ba9551d54961c24" @@ -118,6 +115,24 @@ git-tree-sha1 = "5248d9c45712e51e27ba9b30eebec65658c6ce29" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" version = "0.6.0+0" +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "e0af648f0692ec1691b5d094b8724ba1346281cf" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.18.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "1da46ce8a2a68abf692e16d414722fe628bd1c16" +repo-rev = "main" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.1.0" + [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" @@ -130,6 +145,17 @@ git-tree-sha1 = "7f5717cbb2c1ce650cfd454451f282df33103596" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" version = "0.2.5" +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + [[deps.Compat]] deps = ["UUIDs"] git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" @@ -208,20 +234,29 @@ version = "1.0.0" deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" version = "0.10.10" +weakdeps = ["ChainRulesCore", "SparseArrays"] [deps.Distances.extensions] DistancesChainRulesCoreExt = "ChainRulesCore" DistancesSparseArraysExt = "SparseArrays" - [deps.Distances.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - [[deps.Distributed]] deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" @@ -274,6 +309,20 @@ version = "1.16.1" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +[[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.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] git-tree-sha1 = "2e57b4a4f9cc15e85a24d603256fe08e527f48d1" @@ -533,6 +582,12 @@ git-tree-sha1 = "4263c4220f22e20729329838bf7e94a49d1ac32f" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" version = "0.12.17" +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + [[deps.NetCDF_jll]] deps = ["Artifacts", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "XML2_jll", "Zlib_jll", "Zstd_jll"] git-tree-sha1 = "10c612c81eaffdd6b7c28a45a554cdd9d2f40ff1" @@ -716,6 +771,30 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" +[[deps.RootSolvers]] +deps = ["ForwardDiff"] +git-tree-sha1 = "833d9914e748ca9329b762a82ec912897975f8d8" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.1" + +[[deps.Roots]] +deps = ["ChainRulesCore", "CommonSolve", "Printf", "Setfield"] +git-tree-sha1 = "06b5ac80ff1b88bd82df92c1c1875eea3954cd6e" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.0.20" + + [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 = "0783924e4a332493f72490253ba4e668aeba1d73" @@ -740,6 +819,12 @@ version = "0.3.2" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + [[deps.SimpleBufferStream]] git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" @@ -757,13 +842,11 @@ deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_j git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" version = "2.3.1" +weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - [deps.SpecialFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - [[deps.Static]] deps = ["IfElse"] git-tree-sha1 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" diff --git a/Project.toml b/Project.toml index 57fb9c94..339eaaf8 100644 --- a/Project.toml +++ b/Project.toml @@ -7,6 +7,7 @@ version = "0.1.0" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" +ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" CubicSplines = "9c784101-8907-5a6d-9be6-98f00873c89b" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 29178e23..4f68fe87 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.9.2" +julia_version = "1.10.0-beta3" manifest_format = "2.0" project_hash = "883b87502c4a6df1ec75ae2bd27194c9ff4c7796" @@ -141,16 +141,20 @@ uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" version = "1.0.1+0" [[deps.CUDA]] -deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "Preferences", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "SpecialFunctions", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "968c1365e2992824c3e7a794e30907483f8469a9" +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "Statistics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "f062a48c26ae027f70c44f48f244862aec47bf99" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "4.4.1" +version = "5.0.0" +weakdeps = ["SpecialFunctions"] + + [deps.CUDA.extensions] + SpecialFunctionsExt = "SpecialFunctions" [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "498f45593f6ddc0adff64a9310bb6710e851781b" +git-tree-sha1 = "2f64185414751a5f878c4ab616c0edd94ade3419" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.5.0+1" +version = "0.6.0+4" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] @@ -160,9 +164,9 @@ version = "0.2.2" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "5248d9c45712e51e27ba9b30eebec65658c6ce29" +git-tree-sha1 = "105eb8cf6ec6e8b93493da42ec789c3f65f7d749" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.6.0+0" +version = "0.9.2+3" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -177,30 +181,32 @@ uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" version = "0.5.1" [[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "e30f2f4e20f7f186dc36529910beaedc60cfa644" +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "e0af648f0692ec1691b5d094b8724ba1346281cf" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.16.0" +version = "1.18.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.ClimaOcean]] -deps = ["CUDA", "CubicSplines", "DataDeps", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "Statistics"] -path = "/home/greg/Projects/ClimaOcean.jl" +deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "Statistics"] +path = "../.." uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" version = "0.1.0" [[deps.ClimaSeaIce]] -deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "1da46ce8a2a68abf692e16d414722fe628bd1c16" -repo-rev = "main" -repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" +deps = ["Adapt", "GLMakie", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +path = "/home/greg/Projects/ClimaSeaIce.jl" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "02aa26a4cf76381be7f66e020a3eddeb27b0a092" +git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.2" +version = "0.7.3" [[deps.ColorBrewer]] deps = ["Colors", "JSON", "Test"] @@ -239,9 +245,9 @@ version = "1.0.2" [[deps.CommonDataModel]] deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf"] -git-tree-sha1 = "2678b3fc170d582655a14d22867b031b6e43c2d4" +git-tree-sha1 = "7f5717cbb2c1ce650cfd454451f282df33103596" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.2.4" +version = "0.2.5" [[deps.CommonSolve]] git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" @@ -267,7 +273,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.5+0" +version = "1.0.5+1" [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] @@ -298,9 +304,9 @@ version = "4.1.1" [[deps.CubedSphere]] deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] -git-tree-sha1 = "131498c78453d02b4821d8b93f6e44595399f19f" +git-tree-sha1 = "253193dfb0384646936c5ff3230b27a20d91261e" uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.2.3" +version = "0.2.4" [[deps.CubicSplines]] deps = ["Random", "Test"] @@ -319,6 +325,12 @@ git-tree-sha1 = "6e8d74545d34528c30ccd3fa0f3c00f8ed49584c" uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" version = "0.7.11" +[[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 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" @@ -443,9 +455,9 @@ uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" version = "0.1.10" [[deps.Extents]] -git-tree-sha1 = "5e1e4c53fa39afe63a7d356e30452249365fba99" +git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.1" +version = "0.1.2" [[deps.FFMPEG_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] @@ -482,9 +494,9 @@ uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FillArrays]] deps = ["LinearAlgebra", "Random"] -git-tree-sha1 = "a20eaa3ad64254c61eeb5f230d9306e937405434" +git-tree-sha1 = "35f0c0f345bff2c6d636f95fdb136323b5a796ef" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.6.1" +version = "1.7.0" weakdeps = ["SparseArrays", "Statistics"] [deps.FillArrays.extensions] @@ -577,15 +589,15 @@ version = "3.3.8+0" [[deps.GLMakie]] deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "d7fe46f077c850f221c1f5b7b746a63c7e82b6b3" +git-tree-sha1 = "b46b637cf3e1945354e77c016f867198b829d2f6" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.8.10" +version = "0.8.11" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "2e57b4a4f9cc15e85a24d603256fe08e527f48d1" +git-tree-sha1 = "8ad8f375ae365aa1eb2f42e2565a40b55a4b69a8" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "8.8.1" +version = "9.0.0" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -595,9 +607,9 @@ version = "0.1.5" [[deps.GPUCompiler]] deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] -git-tree-sha1 = "72b2e3c2ba583d1a7aa35129e56cf92e07c083e3" +git-tree-sha1 = "5e4487558477f191c043166f8301dd0b4be4e2b2" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.21.4" +version = "0.24.5" [[deps.GeoInterface]] deps = ["Extents"] @@ -728,9 +740,15 @@ uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" version = "1.0.0" [[deps.Inflate]] -git-tree-sha1 = "5cd07aab533df5170988219191dfad0519391428" +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.3" +version = "0.1.4" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" [[deps.IntegerMathUtils]] git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" @@ -769,6 +787,11 @@ weakdeps = ["Statistics"] [deps.IntervalSets.extensions] IntervalSetsStatisticsExt = "Statistics" +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + [[deps.IrrationalConstants]] git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" @@ -798,9 +821,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "c11d691a0dc8e90acfa4740d293ade57f68bfdbb" +git-tree-sha1 = "572d024660119ee626938419c14db0db5f3f3283" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.35" +version = "0.4.36" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -832,11 +855,17 @@ git-tree-sha1 = "6f2675ef130a300a112286de91973805fcc5ffbc" uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" version = "2.1.91+0" +[[deps.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "4c5875e4c228247e1c2b087669846941fb6e0118" +git-tree-sha1 = "5f1ecfddb6abde48563d08b2cc7e5116ebcd6c27" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.8" +version = "0.9.10" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -897,21 +926,26 @@ version = "0.3.1" [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.3" +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 = "7.84.0+0" +version = "8.0.1+1" [[deps.LibGit2]] -deps = ["Base64", "NetworkOptions", "Printf", "SHA"] +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.10.2+0" +version = "1.11.0+1" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" @@ -1051,15 +1085,15 @@ version = "0.5.11" [[deps.Makie]] deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "cf10f4b9d09da50f124ab7bcb530e57f700328f0" +git-tree-sha1 = "1d16d20279a145119899b4205258332f0fbeaa94" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.19.10" +version = "0.19.11" [[deps.MakieCore]] -deps = ["Observables"] -git-tree-sha1 = "17d51182db2667962bc7e1d18b74881d0d0adbe6" +deps = ["Observables", "REPL"] +git-tree-sha1 = "a94bf3fef9c690a2a4ac1d09d86a59ab89c7f8e4" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.6.7" +version = "0.6.8" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -1090,7 +1124,7 @@ version = "1.1.7" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+0" +version = "2.28.2+1" [[deps.MeshIO]] deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] @@ -1132,7 +1166,7 @@ version = "0.3.4" [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2022.10.11" +version = "2023.1.10" [[deps.Multisets]] git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" @@ -1151,6 +1185,18 @@ git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" version = "7.8.3" +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "8bc9ce4233be3c63f8dcd78ccaf1b63a9c0baa34" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "0.3.3" + +[[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" @@ -1180,11 +1226,9 @@ version = "0.5.4" [[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 = "64809ab91971fdd59be66efcaa438ff5499b100d" -repo-rev = "main" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +path = "/home/greg/Projects/Oceananigans.jl" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.89.2" +version = "0.89.3" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -1207,7 +1251,7 @@ version = "1.3.5+1" [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.21+4" +version = "0.3.23+2" [[deps.OpenEXR]] deps = ["Colors", "FileIO", "OpenEXR_jll"] @@ -1224,7 +1268,7 @@ version = "3.1.4+0" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+0" +version = "0.8.1+2" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] @@ -1252,9 +1296,9 @@ version = "0.5.5+0" [[deps.Optim]] deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "963b004d15216f8129f6c0f7d187efa136570be0" +git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.7.7" +version = "1.7.8" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1270,19 +1314,19 @@ version = "1.6.2" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.42.0+0" +version = "10.42.0+1" [[deps.PDMats]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "528664265c9c36b3ecdb6d721d47aaab52ddf267" +git-tree-sha1 = "66b2fcd977db5329aa35cac121e5b94dd6472198" uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.24" +version = "0.11.28" [[deps.PNGFiles]] deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] -git-tree-sha1 = "9b02b27ac477cad98114584ff964e3052f656a0f" +git-tree-sha1 = "5ded86ccaf0647349231ed6c0822c10886d4a1ee" uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" -version = "0.4.0" +version = "0.4.1" [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" @@ -1316,9 +1360,9 @@ version = "2.7.2" [[deps.PencilArrays]] deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] -git-tree-sha1 = "c1d2b659ce423897de45e998f49f77e789e1859d" +git-tree-sha1 = "1a473d028436947e08436275ff3fcc2f3e9c5b06" uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.18.1" +version = "0.19.2" [deps.PencilArrays.extensions] PencilArraysDiffEqExt = ["DiffEqBase"] @@ -1349,7 +1393,7 @@ version = "0.42.2+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.9.2" +version = "1.10.0" [[deps.PkgVersion]] deps = ["Pkg"] @@ -1386,6 +1430,12 @@ version = "4.0.4" MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + [[deps.PositiveFactorizations]] deps = ["LinearAlgebra"] git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" @@ -1404,6 +1454,12 @@ git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.1" +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "6842ce83a836fbbc0cfeca0b5a4de1a4dcbdb8d1" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.2.8" + [[deps.Primes]] deps = ["IntegerMathUtils"] git-tree-sha1 = "4c9f306e5d6603ae203c2000dd460d81a5251489" @@ -1449,7 +1505,7 @@ deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" [[deps.Random]] -deps = ["SHA", "Serialization"] +deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[deps.Random123]] @@ -1498,9 +1554,9 @@ version = "1.2.2" [[deps.RelocatableFolders]] deps = ["SHA", "Scratch"] -git-tree-sha1 = "90bc7a7c96410424509e4263e277e43250c05691" +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.0" +version = "1.0.1" [[deps.Requires]] deps = ["UUIDs"] @@ -1576,6 +1632,12 @@ git-tree-sha1 = "958ba75b90c7c8a117d041d33184134201cf8c0f" uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" version = "0.3.2" +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "04bdff0b09c65ff3e06a05e3eb7b120223da3d39" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.0" + [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -1658,13 +1720,14 @@ uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "c60ec5c62180f27efea3ba2908480f8055e17cee" +git-tree-sha1 = "5165dfb9fd131cf0c6957a3a7605dede376e7b63" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.1.1" +version = "1.2.0" [[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"] @@ -1728,7 +1791,7 @@ version = "0.3.0" [[deps.Statistics]] deps = ["LinearAlgebra", "SparseArrays"] uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.9.0" +version = "1.10.0" [[deps.StatsAPI]] deps = ["LinearAlgebra"] @@ -1772,6 +1835,12 @@ 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 = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" @@ -1791,7 +1860,7 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "5.10.1+6" +version = "7.2.0+1" [[deps.TOML]] deps = ["Dates"] @@ -1837,9 +1906,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] -git-tree-sha1 = "7fd97bd1c5b1ff53a291cbd351d1d3d6ff4da5a5" +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.6.7" +version = "0.6.8" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] @@ -1864,9 +1933,9 @@ uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" version = "1.4.3" [[deps.URIs]] -git-tree-sha1 = "b7a5e99f24892b6824a954199a45e9ffcc1c70f0" +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.5.0" +version = "1.5.1" [[deps.UUIDs]] deps = ["Random", "SHA"] @@ -2001,7 +2070,7 @@ version = "1.5.0+0" [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+0" +version = "1.2.13+1" [[deps.Zstd_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -2036,7 +2105,7 @@ version = "0.15.1+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+0" +version = "5.8.0+1" [[deps.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -2065,12 +2134,12 @@ version = "1.3.7+1" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.48.0+0" +version = "1.52.0+1" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+0" +version = "17.4.0+2" [[deps.x264_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 89de2928..a360a3b0 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -1,7 +1,12 @@ using Oceananigans using Oceananigans.Units using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity +using Oceananigans.Fields: ConstantField, ZeroField using ClimaOcean +using ClimaOcean.OceanSeaIceModels: OceanSeaIceModel +using ClimaOcean.OceanSeaIceModels: adjust_ice_covered_ocean_temperature! +using ClimaSeaIce +using ClimaSeaIce: IceWaterThermalEquilibrium using SeawaterPolynomials.TEOS10: TEOS10EquationOfState using NCDatasets @@ -46,10 +51,28 @@ pushfirst!(zf, zf[1] - Δz) Tᵢ = temperature_ds["THETA"][:, :, :, 1] Sᵢ = salinity_ds["SALT"][:, :, :, 1] -hᵢ = ice_thickness_ds["SIheff"][:, :, 1] +ℋᵢ = ice_thickness_ds["SIheff"][:, :, 1] + +Nx, Ny′, Nz = size(Tᵢ) + +##### +##### Construct the grid +##### + +arch = GPU() +southern_limit = -79 +northern_limit = -30 +j₁ = 4 * (90 + southern_limit) +j₂ = 720 - 4 * (90 - northern_limit) + 1 +Ny = j₂ - j₁ + 1 + +Tᵢ = Tᵢ[:, j₁:j₂, :] +Sᵢ = Sᵢ[:, j₁:j₂, :] +ℋᵢ = ℋᵢ[:, j₁:j₂] Tᵢ = convert(Array{Float32, 3}, Tᵢ) Sᵢ = convert(Array{Float32, 3}, Sᵢ) +ℋᵢ = convert(Array{Float32, 2}, ℋᵢ) Tᵢ = reverse(Tᵢ, dims=3) Sᵢ = reverse(Sᵢ, dims=3) @@ -57,10 +80,10 @@ Sᵢ = reverse(Sᵢ, dims=3) missing_value = Float32(-9.9e22) # Construct bottom_height depth by analyzing T -Nx, Ny′, Nz = size(Tᵢ) -bottom_height = ones(Nx, Ny′) .* (zf[1] - Δz) +Nx, Ny, Nz = size(Tᵢ) +bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) -for i = 1:Nx, j = 1:Ny′ +for i = 1:Nx, j = 1:Ny @inbounds for k = Nz:-1:1 if Tᵢ[i, j, k] < -10 bottom_height[i, j] = zf[k+1] @@ -69,22 +92,6 @@ for i = 1:Nx, j = 1:Ny′ end end -##### -##### Construct the grid -##### - -arch = GPU() -southern_limit = -79 -northern_limit = 85 -j₁ = 4 * (90 + southern_limit) -j₂ = 720 - 4 * (90 - northern_limit) + 1 -Ny = j₂ - j₁ + 1 - -Tᵢ = Tᵢ[:, j₁:j₂, :] -Sᵢ = Sᵢ[:, j₁:j₂, :] -bottom_height = bottom_height[:, j₁:j₂] - - grid = LatitudeLongitudeGrid(arch, size = (Nx, Ny, Nz), longitude = (0, 360), @@ -146,10 +153,19 @@ set!(ocean_model, T=Tᵢ, S=Sᵢ) ##### Setup ice model ##### +ice_grid = LatitudeLongitudeGrid(arch, + size = (Nx, Ny), + longitude = (0, 360), + halo = (7, 7), + latitude = (southern_limit, northern_limit), + topology = (Periodic, Bounded, Flat)) + +ice_grid = ImmersedBoundaryGrid(ice_grid, GridFittedBottom(bottom_height)) + Nz = size(grid, 3) So = ocean_model.tracers.S ocean_surface_salinity = view(So, :, :, Nz) -bottom_bc = IceWaterThermalEquilibrium(ConstantField(30)) #ocean_surface_salinity) +bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) u, v, w = ocean_model.velocities ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), @@ -158,22 +174,24 @@ ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), ice_model = SlabSeaIceModel(ice_grid; velocities = ocean_surface_velocities, - advection = WENO(), + advection = nothing, ice_consolidation_thickness = 0.05, ice_salinity = 4, internal_thermal_flux = ConductiveFlux(conductivity=2), top_thermal_flux = ConstantField(0), # W m⁻² - top_thermal_boundary_condition = PrescribedTemperature(-2), + top_thermal_boundary_condition = PrescribedTemperature(0), bottom_thermal_boundary_condition = bottom_bc, bottom_thermal_flux = ice_ocean_heat_flux) -set!(ice_model, h=hᵢ) +set!(ice_model, h=ℋᵢ) -#simulation = Simulation(model, Δt=5minutes, stop_time=360days) ocean_simulation = Simulation(ocean_model; Δt=5minutes, verbose=false) ice_simulation = Simulation(ice_model, Δt=5minutes, verbose=false) -coupled_model = IceOceanModel(ice_simulation, ocean_simulation) -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=5days) + +coupled_model = OceanSeaIceModel(ice_simulation, ocean_simulation) +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=30days) + +adjust_ice_covered_ocean_temperature!(coupled_model) wall_clock = Ref(time_ns()) @@ -194,19 +212,20 @@ function progress(sim) @info msg1 * msg2 * msg3 end -simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) using Oceananigans.Operators: ζ₃ᶠᶠᶜ u, v, w = ocean_model.velocities ζ = KernelFunctionOperation{Face, Face, Center}(ζ₃ᶠᶠᶜ, grid, u, v) +ℋ = ice_model.ice_thickness -outputs = merge(ocean_model.velocities, ocean_model.tracers, (; ζ)) +outputs = merge(ocean_model.velocities, ocean_model.tracers, (; ζ, ℋ)) filename = "omip_surface_fields.jld2" -ocean_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outputs; filename, - schedule = TimeInterval(12hour), - indices = (:, :, Nz), - overwrite_existing = true) +coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outputs; filename, + schedule = TimeInterval(1day), + indices = (:, :, Nz), + overwrite_existing = true) run!(coupled_simulation) @@ -214,25 +233,75 @@ run!(coupled_simulation) ##### Visualize ##### +using Oceananigans +using GLMakie +filename = "omip_surface_fields.jld2" + +Tt = FieldTimeSeries(filename, "T") +St = FieldTimeSeries(filename, "S") et = FieldTimeSeries(filename, "e") +ℋt = FieldTimeSeries(filename, "ℋ") ζt = FieldTimeSeries(filename, "ζ") -times = et.times + +land = interior(Tt[1], :, :, 1) .== 0 +mask = [1 + ℓ * NaN for ℓ in land] + +grid = Tt.grid +λ, φ, z = nodes(Tt) +h = interior(grid.immersed_boundary.bottom_height, :, :, 1) +h .*= mask +times = Tt.times Nt = length(times) -fig = Figure(resolution=(1800, 1200)) +fig = Figure(resolution=(2400, 1200)) + +axT = Axis(fig[1, 2], title="Temperature") +axS = Axis(fig[2, 2], title="Salinity") +axh = Axis(fig[3, 2], title="Bottom height") +axe = Axis(fig[1, 3], title="Turbulent kinetic energy") +axZ = Axis(fig[2, 3], title="Vorticity") +axℋ = Axis(fig[3, 3], title="Ice thickness") -axe = Axis(fig[1, 1]) -axZ = Axis(fig[2, 1]) -slider = Slider(fig[3, 1], range=1:Nt, startvalue=1) +slider = Slider(fig[4, 2:3], range=1:Nt, startvalue=1) n = slider.value -en = @lift interior(et[$n], :, :, 1) +title = @lift string("OMIP simulation ", prettytime(times[$n]), " after Jan 1 1992") +Label(fig[0, 2:3], title) + +Tn = @lift mask .* interior(Tt[$n], :, :, 1) +Sn = @lift mask .* interior(St[$n], :, :, 1) +en = @lift mask .* interior(et[$n], :, :, 1) ζn = @lift interior(ζt[$n], :, :, 1) +ℋn = @lift mask .* interior(ℋt[$n], :, :, 1) +Δℋn = @lift mask .* (interior(ℋt[$n], :, :, 1) .- interior(ℋt[1], :, :, 1)) + +hm = heatmap!(axT, λ, φ, Tn, nan_color=:gray, colorrange=(-1, 25), colormap=:thermal) +Colorbar(fig[1, 1], hm, flipaxis=false) + +hm = heatmap!(axS, λ, φ, Sn, nan_color=:gray, colorrange=(28, 35), colormap=:haline) +Colorbar(fig[2, 1], hm, flipaxis=false) + +hm = heatmap!(axh, λ, φ, h, nan_color=:gray, colormap=:viridis) +Colorbar(fig[3, 1], hm, flipaxis=false) + +hm = heatmap!(axe, λ, φ, en, nan_color=:gray, colorrange=(0, 2e-6), colormap=:solar) +Colorbar(fig[1, 4], hm) -#heatmap!(axT, λ, φ, Tn, colorrange=(-1, 25), colormap=:thermal) -#heatmap!(axS, λ, φ, Sn, colorrange=(28, 35), colormap=:haline) -heatmap!(axe, λ, φ, en, colorrange=(0, 1e-4), colormap=:solar) -heatmap!(axZ, λ, φ, ζn, colorrange=(-2e-5, 2e-5), colormap=:redblue) +hm = heatmap!(axZ, λ, φ, ζn, nan_color=:gray, colorrange=(-2e-5, 2e-5), colormap=:redblue) +Colorbar(fig[2, 4], hm) + +hm = heatmap!(axℋ, λ, φ, ℋn, nan_color=:gray, colorrange=(0, 1), colormap=:blues) +Colorbar(fig[3, 4], hm) + +# hm = heatmap!(axℋ, λ, φ, Δℋn, nan_color=:gray, colorrange=(-0.5, 0.5), colormap=:balance) +# Colorbar(fig[3, 4], hm) display(fig) +#= +record(fig, "omip_simulation.mp4", 1:Nt, framerate=24) do nn + @info "Drawing frame $nn of $Nt..." + n[] = nn +end +=# + diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index cc8ee135..e4b0924d 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -20,14 +20,22 @@ import Oceananigans.Simulations: reset!, initialize!, iteration import Oceananigans.TimeSteppers: time_step!, update_state!, time import Oceananigans.Utils: prettytime -const ℒₑ = 2.5e6 # J/kg Latent heat of evaporation -const σᴮ = 5.67e-8 # W/m²/K⁴ Stefan-Boltzmann constant +# We should not declare these; they need to be settable. +# const ℒₑ = 2.5e6 # J/kg Latent heat of evaporation +# const σᴮ = 5.67e-8 # W/m²/K⁴ Stefan-Boltzmann constant +using Oceananigans +using Oceananigans.Utils: Time +using Oceananigans.Grids: architecture +using Oceananigans.Models: AbstractModel + +include("sea_ice_ocean_fluxes.jl") include("ocean_sea_ice_model.jl") -include("ocean_sea_ice_atmosphere_fluxes.jl") -include("ocean_only_model_fluxes.jl") -# include("AtmosphericForcings.jl") -# using .AtmosphericForcings +include("ocean_only_model.jl") + +# Or "AtmosphereModels" +# include("Atmospheres.jl") +# using .Atmospheres # Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). function default_nan_checker(model::OceanSeaIceModel) diff --git a/src/OceanSeaIceModels/AtmosphericForcings.jl b/src/OceanSeaIceModels/PrescribedAtmospheres/PrescribedAtmospheres.jl similarity index 100% rename from src/OceanSeaIceModels/AtmosphericForcings.jl rename to src/OceanSeaIceModels/PrescribedAtmospheres/PrescribedAtmospheres.jl diff --git a/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl new file mode 100644 index 00000000..2377b499 --- /dev/null +++ b/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl @@ -0,0 +1,34 @@ +# If there is no atmosphere, do not compute fluxes! (this model has the ocean component which +# will handle the top boundary_conditions, for example if we want to impose a value BC) +compute_air_sea_flux!(coupled_model::NoAtmosphereModel) = nothing + +function compute_air_sea_flux!(coupled_model) + ocean = coupled_model.ocean + forcing = coupled_model.atmospheric_forcing + + (; T, S) = ocean.model.tracers + (; u, v) = ocean.model.velocities + + grid = ocean.model.grid + clock = ocean.model.clock + fields = prognostic_fields(ocean.model) + + Qˢ = T.boundary_conditions.top.condition + Fˢ = S.boundary_conditions.top.condition + τˣ = u.boundary_conditions.top.condition + τʸ = v.boundary_conditions.top.condition + + ε = coupled_model.ocean_emissivity + ρₒ = coupled_model.ocean_density + cₒ = coupled_model.ocean_heat_capacity + I₀ = coupled_model.solar_insolation + + ice_thickness = coupled_model.ice.model.ice_thickness + + launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, I₀, + grid, clock, fields, forcing, ice_thickness) + + return nothing +end + + diff --git a/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl new file mode 100644 index 00000000..e450e3ca --- /dev/null +++ b/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl @@ -0,0 +1,3 @@ +# Place holder for now +compute_air_ice_flux!(coupled_model) = nothing + diff --git a/src/OceanSeaIceModels/model_utils.jl b/src/OceanSeaIceModels/getflux.jl similarity index 69% rename from src/OceanSeaIceModels/model_utils.jl rename to src/OceanSeaIceModels/getflux.jl index 826e6b64..cc4f0ccc 100644 --- a/src/OceanSeaIceModels/model_utils.jl +++ b/src/OceanSeaIceModels/getflux.jl @@ -1,11 +1,3 @@ -using Oceananigans -using Oceananigans.Utils: Time -using Oceananigans.Grids: architecture -using Oceananigans.Models: AbstractModel -import Oceananigans.Grids: launch! - -launch!(model::AbstractModel, args...; kwargs...) = launch!(architecture(model.grid), model.grid, args...; kwargs...) - @inline getflux(f::Nothing, i::Int, j::Int, grid::AbstractGrid, clock, fields) = nothing @inline getflux(f::Number, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f @inline getflux(f::Function, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f(i, j, grid, clock, fields) @@ -14,7 +6,9 @@ launch!(model::AbstractModel, args...; kwargs...) = launch!(architecture(model.g @inline getflux(f::FieldTimeSeries, i::Int, j::Int, grid::AbstractGrid, clock, args...) = @inbounds f[i, j, Time(clock.time)] # If we have ice, do not compute fluxes! -@inline function get_flux(ice_thickness, f, i::Int, j::Int, grid::AbstractGrid, args...) +@inline function getflux(ice_thickness, f, i::Int, j::Int, grid::AbstractGrid, args...) h = @inbounds ice_thickness[i, j, 1] return ifelse(h > 0, getflux(f, i, j, grid,args...), 0) -end \ No newline at end of file +end + + diff --git a/src/OceanSeaIceModels/ocean_only_model_fluxes.jl b/src/OceanSeaIceModels/ocean_only_model.jl similarity index 90% rename from src/OceanSeaIceModels/ocean_only_model_fluxes.jl rename to src/OceanSeaIceModels/ocean_only_model.jl index 40aa50a9..8401a180 100644 --- a/src/OceanSeaIceModels/ocean_only_model_fluxes.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -1,3 +1,6 @@ +const OceanOnlyModel = OceanSeaIceModel{<:Any, Nothing} + +OceanOnlyModel(ocean; kw...) = OceanSeaIceModel(nothing, ocean; kw...) ##### ##### No ice-ocean fluxes in this model!! diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 6d10d4b3..7e42ddb5 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -1,18 +1,25 @@ using Oceananigans.Models: update_model_field_time_series! +using Oceananigans.TimeSteppers: Clock +using Oceananigans -struct OceanSeaIceModel{FT, I, O, F, C, G, S, PI, PC} <: AbstractModel{Nothing} +struct Radiation{FT, S} + solar_insolation :: S + ocean_emissivity :: FT + stefan_boltzmann_constant :: FT + reference_temperature :: FT +end + +struct OceanSeaIceModel{FT, I, A, O, C, G, R, PI, PC} <: AbstractModel{Nothing} clock :: C grid :: G # TODO: make it so simulation does not require this - ice :: I + atmosphere :: A + sea_ice :: I + ocean :: O + radiation :: R previous_ice_thickness :: PI previous_ice_concentration :: PC - ocean :: O - atmospheric_forcing :: F - solar_insolation :: S ocean_density :: FT ocean_heat_capacity :: FT - ocean_emissivity :: FT - reference_temperature :: FT end const OSIM = OceanSeaIceModel @@ -24,20 +31,11 @@ timestepper(::OSIM) = nothing reset!(::OSIM) = nothing initialize!(::OSIM) = nothing default_included_properties(::OSIM) = tuple() -update_state!(::OSIM) = nothing prognostic_fields(cm::OSIM) = nothing fields(::OSIM) = NamedTuple() -default_clock(TT) = Clock{TT}(0, 0, 1) +default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) -# "Ocean only" -const OceanOnlyModel = OceanSeaIceModel{<:Any, Nothing} -const NoAtmosphereModel = OceanSeaIceModel{<:Any, <:Any, Nothing} - -OceanOnlyModel(ocean; atmospheric_forcing = nothing, clock = default_clock(eltype(ocean.model))) = - OceanSeaIceModel(nothing, ocean; atmospheric_forcing, clock) - -function OceanSeaIceModel(ice, ocean; - atmospheric_forcing = nothing, +function OceanSeaIceModel(ice, ocean, atmosphere=nothing; clock = default_clock(eltype(ocean.model))) previous_ice_thickness = deepcopy(ice.model.ice_thickness) @@ -50,77 +48,82 @@ function OceanSeaIceModel(ice, ocean; ocean_density = 1024 ocean_heat_capacity = 3991 - ocean_emissivity = 1 reference_temperature = 273.15 # How would we ensure consistency? try if ice.model.external_thermal_fluxes.top isa RadiativeEmission - radiation = ice.model.external_thermal_fluxes.top + ice_radiation = ice.model.external_thermal_fluxes.top else - radiation = filter(flux isa RadiativeEmission, ice.model.external_thermal_fluxes.top) |> first + ice_radiation = filter(flux isa RadiativeEmission, ice.model.external_thermal_fluxes.top) |> first end - reference_temperature = radiation.reference_temperature + reference_temperature = ice_radiation.reference_temperature catch end FT = eltype(ocean.model.grid) + ocean_emissivity = 1 + stefan_boltzmann_constant = 5.67e-8 + + radiation = Radiation(solar_insolation, + convert(FT, ocean_emissivity), + convert(FT, stefan_boltzmann_constant), + convert(FT, reference_temperature)) return OceanSeaIceModel(clock, ocean.model.grid, + atmosphere, ice, + ocean, + radiation, previous_ice_thickness, previous_ice_concentration, - ocean, - solar_insolation, - atmospheric_forcing, convert(FT, ocean_density), - convert(FT, ocean_heat_capacity), - convert(FT, ocean_emissivity), - convert(FT, stefan_boltzmann_constant), - convert(FT, reference_temperature)) + convert(FT, ocean_heat_capacity)) end time(coupled_model::OceanSeaIceModel) = coupled_model.clock.time function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=nothing) ocean = coupled_model.ocean - ice = coupled_model.ice - ice.Δt = Δt - ocean.Δt = Δt + sea_ice = coupled_model.sea_ice + h = sea_ice.model.ice_thickness fill_halo_regions!(h) # Initialization if coupled_model.clock.iteration == 0 + @info "Initializing coupled model ice thickness..." h⁻ = coupled_model.previous_ice_thickness - hⁿ = coupled_model.ice.model.ice_thickness + hⁿ = coupled_model.sea_ice.model.ice_thickness parent(h⁻) .= parent(hⁿ) end - time_step!(ice) + sea_ice.Δt = Δt + ocean.Δt = Δt - # TODO: put this in update_state! - # Air-sea and Air-ice fluxes substitute the previous values - # while ice-ocean fluxes are additive - update_model_field_time_series!(coupled_model.atmospheric_forcing) - compute_air_sea_flux!(coupled_model) - compute_air_ice_flux!(coupled_model) # TODO: we need to implement this, not sure how - compute_ice_ocean_flux!(coupled_model) + time_step!(sea_ice) + + # TODO after ice time-step: + # - Adjust ocean heat flux if the ice completely melts? time_step!(ocean) # TODO: # - Store fractional ice-free / ice-covered _time_ for more # accurate flux computation? - # - Or, input "excess heat flux" into ocean after the ice melts - # - Currently, non-conservative for heat due bc we don't account for excess - - # TODO after ice time-step: - # - Adjust ocean temperature if the ice completely melts? tick!(coupled_model.clock, Δt) return nothing end + +function update_state!(coupled_model::OceanSeaIceModel, callbacks=nothing) + # update_model_field_time_series!(coupled_model.atmosphere.model) + # compute_atmosphere_ocean_fluxes!(coupled_model) + # compute_atmosphere_sea_ice_fluxes!(coupled_model) + compute_sea_ice_ocean_fluxes!(coupled_model) + return nothing +end + diff --git a/src/OceanSeaIceModels/ocean_sea_ice_atmosphere_fluxes.jl b/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl similarity index 56% rename from src/OceanSeaIceModels/ocean_sea_ice_atmosphere_fluxes.jl rename to src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl index 8c22b866..171b86ff 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_atmosphere_fluxes.jl +++ b/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl @@ -1,135 +1,105 @@ +using ClimaSeaIce: melting_temperature -# If there is no atmosphere, do not compute fluxes! (this model has the ocean component which -# will handle the top boundary_conditions, for example if we want to impose a value BC) -compute_air_sea_flux!(coupled_model::NoAtmosphereModel) = nothing - -# Is this taken care of inside the ice model? Probably not because it is better to couple here than inside -compute_air_ice_flux!(coupled_model) = nothing - -function compute_air_sea_flux!(coupled_model) - ocean = coupled_model.ocean - forcing = coupled_model.atmospheric_forcing - - (; T, S) = ocean.model.tracers - (; u, v) = ocean.model.velocities - - grid = ocean.model.grid - clock = ocean.model.clock - fields = prognostic_fields(ocean.model) - - Qˢ = T.boundary_conditions.top.condition - Fˢ = S.boundary_conditions.top.condition - τˣ = u.boundary_conditions.top.condition - τʸ = v.boundary_conditions.top.condition - - ε = coupled_model.ocean_emissivity - ρₒ = coupled_model.ocean_density - cₒ = coupled_model.ocean_heat_capacity - I₀ = coupled_model.solar_insolation - - ice_thickness = coupled_model.ice.model.ice_thickness - - launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, I₀, - grid, clock, fields, forcing, ice_thickness) - - return nothing -end - -function compute_ice_ocean_flux!(coupled_model) - - # probably need to expand this - compute_ice_ocean_salinity_flux!(coupled_model) - ice_ocean_latent_heat!(coupled_model) - +function compute_sea_ice_ocean_fluxes!(coupled_model) + compute_sea_ice_ocean_salinity_flux!(coupled_model) + sea_ice_ocean_latent_heat_flux!(coupled_model) return nothing end -function compute_ice_ocean_salinity_flux!(coupled_model) +function compute_sea_ice_ocean_salinity_flux!(coupled_model) # Compute salinity increment due to changes in ice thickness - ice = coupled_model.ice + sea_ice = coupled_model.sea_ice ocean = coupled_model.ocean grid = ocean.model.grid arch = architecture(grid) Qˢ = ocean.model.tracers.S.boundary_conditions.top.condition Sₒ = ocean.model.tracers.S - Sᵢ = ice.model.ice_salinity + Sᵢ = sea_ice.model.ice_salinity Δt = ocean.Δt - hⁿ = ice.model.ice_thickness + hⁿ = sea_ice.model.ice_thickness h⁻ = coupled_model.previous_ice_thickness - launch!(arch, grid, :xy, _compute_ice_ocean_salinity_flux!, + launch!(arch, grid, :xy, _compute_sea_ice_ocean_salinity_flux!, Qˢ, grid, hⁿ, h⁻, Sᵢ, Sₒ, Δt) return nothing end -@kernel function _compute_ice_ocean_salinity_flux!(ice_ocean_salinity_flux, - grid, - ice_thickness, - previous_ice_thickness, - ice_salinity, - ocean_salinity, - Δt) +@kernel function _compute_sea_ice_ocean_salinity_flux!(sea_ice_ocean_salinity_flux, + grid, + ice_thickness, + previous_ice_thickness, + ice_salinity, + ocean_salinity, + Δt) i, j = @index(Global, NTuple) Nz = size(grid, 3) hⁿ = ice_thickness h⁻ = previous_ice_thickness - Qˢ = ice_ocean_salinity_flux + Qˢ = sea_ice_ocean_salinity_flux Sᵢ = ice_salinity Sₒ = ocean_salinity @inbounds begin - # Thickness of surface grid cell + # Change in thickness Δh = hⁿ[i, j, 1] - h⁻[i, j, 1] # Update surface salinity flux. # Note: the Δt below is the ocean time-step, eg. # ΔS = ⋯ - ∮ Qˢ dt ≈ ⋯ - Δtₒ * Qˢ - Qˢ[i, j, 1] += Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) + Qˢ[i, j, 1] = Δh / Δt * (Sᵢ[i, j, 1] - Sₒ[i, j, Nz]) # Update previous ice thickness h⁻[i, j, 1] = hⁿ[i, j, 1] end end -function ice_ocean_latent_heat!(coupled_model) +function sea_ice_ocean_latent_heat_flux!(coupled_model) ocean = coupled_model.ocean - ice = coupled_model.ice + sea_ice = coupled_model.sea_ice ρₒ = coupled_model.ocean_density cₒ = coupled_model.ocean_heat_capacity - Qₒ = ice.model.external_thermal_fluxes.bottom + Qₒ = sea_ice.model.external_thermal_fluxes.bottom Tₒ = ocean.model.tracers.T Sₒ = ocean.model.tracers.S Δt = ocean.Δt - hᵢ = ice.model.ice_thickness + hᵢ = sea_ice.model.ice_thickness - liquidus = ice.model.phase_transitions.liquidus + liquidus = sea_ice.model.phase_transitions.liquidus grid = ocean.model.grid arch = architecture(grid) # What about the latent heat removed from the ocean when ice forms? # Is it immediately removed from the ocean? Or is it stored in the ice? - launch!(arch, grid, :xy, _compute_ice_ocean_latent_heat!, + launch!(arch, grid, :xy, _compute_sea_ice_ocean_latent_heat_flux!, Qₒ, grid, hᵢ, Tₒ, Sₒ, liquidus, ρₒ, cₒ, Δt) return nothing end -@kernel function _compute_ice_ocean_latent_heat!(latent_heat, - grid, - ice_thickness, - ocean_temperature, - ocean_salinity, - liquidus, - ρₒ, cₒ, Δt) +function adjust_ice_covered_ocean_temperature!(coupled_model) + sea_ice_ocean_latent_heat_flux!(coupled_model) + sea_ice = coupled_model.sea_ice + Qₒ = sea_ice.model.external_thermal_fluxes.bottom + parent(Qₒ) .= 0 + return nothing +end + +@kernel function _compute_sea_ice_ocean_latent_heat_flux!(latent_heat_flux, + grid, + ice_thickness, + ocean_temperature, + ocean_salinity, + liquidus, + ρₒ, cₒ, Δt) i, j = @index(Global, NTuple) Nz = size(grid, 3) - Qₒ = latent_heat + Qₒ = latent_heat_flux hᵢ = ice_thickness Tₒ = ocean_temperature Sₒ = ocean_salinity @@ -189,3 +159,4 @@ end # Store ice-ocean flux @inbounds Qₒ[i, j, 1] = δQ end + From 0e3a926be4e2caab36023c7a4122b956ef13763d Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 13 Nov 2023 10:08:19 -0700 Subject: [PATCH 033/182] Clean up examples dir --- examples/analyze_neverworld_simulation.jl | 43 --- examples/animate_neverworld_simulation.jl | 152 ----------- examples/compute_mixed_layer_depth.jl | 27 -- examples/melting_baroclinicity.jl | 244 ------------------ .../quarter_degree_near_global_simulation.jl | 96 ------- examples/quarter_degree_omip_run.jl | 36 --- examples/run_neverworld_simulation.jl | 135 ---------- ...ed_perfect_one_degree_model_calibration.jl | 0 .../gm_one_degree_model_calibration.jl | 0 ...spect_one_degree_near_global_simulation.jl | 0 .../one_degree_near_global_simulation.jl | 0 .../perfect_one_degree_model_calibration.jl | 0 12 files changed, 733 deletions(-) delete mode 100644 examples/analyze_neverworld_simulation.jl delete mode 100644 examples/animate_neverworld_simulation.jl delete mode 100644 examples/compute_mixed_layer_depth.jl delete mode 100644 examples/melting_baroclinicity.jl delete mode 100644 examples/quarter_degree_near_global_simulation.jl delete mode 100644 examples/quarter_degree_omip_run.jl delete mode 100644 examples/run_neverworld_simulation.jl rename {examples => experiments/one_degree_simulations}/distributed_perfect_one_degree_model_calibration.jl (100%) rename {examples => experiments/one_degree_simulations}/gm_one_degree_model_calibration.jl (100%) rename {examples => experiments/one_degree_simulations}/inspect_one_degree_near_global_simulation.jl (100%) rename {examples => experiments/one_degree_simulations}/one_degree_near_global_simulation.jl (100%) rename {examples => experiments/one_degree_simulations}/perfect_one_degree_model_calibration.jl (100%) diff --git a/examples/analyze_neverworld_simulation.jl b/examples/analyze_neverworld_simulation.jl deleted file mode 100644 index f76a0035..00000000 --- a/examples/analyze_neverworld_simulation.jl +++ /dev/null @@ -1,43 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Printf -using JLD2 - -dir = "archive" -backend = OnDisk() -bt = FieldTimeSeries("$dir/neverworld_xyz.jld2", "b"; backend) -t = bt.times -Nt = length(t) -grid = bt.grid - -Nyears = 20 -t_end = 200 * 360 * day # 200 "years" -t_start = (200 - Nyears) * 360 * day # 200 "years" - -t = bt.times -n_stop = searchsortedfirst(t, t_stop) -n_start = searchsortedfirst(t, t_start) - 1 - -for season = 1:4 - n_average_start = n_start + season - 1 - n_average = n_average_start:4:n_stop - - for name in ("b", "u", "v", "w", "e", "κᶜ") - ψt = FieldTimeSeries("$dir/neverworld_xyz.jld2", name; backend) - LX, LY, LZ = location(ψt) - ψ_avg = Field{LX, LY, LZ}(grid) - - for n in n_average - @info name season n - ψn = ψt[n] - ψ_avg .+= ψn / length(n_average) - end - - filename = string("climatology_", name, "_season_", season, ".jld2") - file = jldopen(filename, "a+") - file[name] = ψ_avg - file["season"] = season - close(file) - end -end - diff --git a/examples/animate_neverworld_simulation.jl b/examples/animate_neverworld_simulation.jl deleted file mode 100644 index 822ff075..00000000 --- a/examples/animate_neverworld_simulation.jl +++ /dev/null @@ -1,152 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using GLMakie -using Printf -using Statistics - -# Some plotting parameters -ζlim = 6e-5 - -# Plot a limited number of years (here, 10) -Nyears = 3 -t_end = 200 * 360 * day # 200 "years" -t_start = (200 - Nyears) * 360 * day # 200 "years" - -# Load OnDisk time-series without loading massive amount of data -backend = OnDisk() -bxyt = FieldTimeSeries("neverworld_xy.jld2", "b"; backend) - -# Determine which iterations to load into memory -t̃ = bxyt.times -n_end = searchsortedfirst(t̃, t_end) -n_start = searchsortedfirst(t̃, t_start) - 1 - -t = times = t̃[n_start:n_end] -Nt = length(t) - -bxyt = FieldTimeSeries("neverworld_xy.jld2", "b"; times) -uxyt = FieldTimeSeries("neverworld_xy.jld2", "u"; times) -vxyt = FieldTimeSeries("neverworld_xy.jld2", "v"; times) -exyt = FieldTimeSeries("neverworld_xy.jld2", "e"; times) -κxyt = FieldTimeSeries("neverworld_xy.jld2", "κᶜ"; times) - -byzt = FieldTimeSeries("neverworld_zonal_average.jld2", "b"; times) -eyzt = FieldTimeSeries("neverworld_zonal_average.jld2", "e"; times) -κyzt = FieldTimeSeries("neverworld_zonal_average.jld2", "κᶜ"; times) - -# Hack to set immersed regions to NaN -for ft in (bxyt, uxyt, exyt, κxyt, byzt, eyzt, κyzt) - fp = parent(ft) - fp[fp .== 0] .= NaN -end - -fig = Figure(resolution=(2000, 1800)) - -axbxy = Axis(fig[2, 1], xlabel="Longitude", ylabel="Latitude", title="b(x, y)") -axζxy = Axis(fig[2, 2], xlabel="Longitude", ylabel="Latitude", title="ζ(x, y)") -axexy = Axis(fig[2, 3], xlabel="Longitude", ylabel="Latitude", title="e(x, y)") - -axNyz = Axis(fig[3, 1], xlabel="Longitude", ylabel="z (m)", title="N²(y, z)") -axeyz = Axis(fig[3, 2], xlabel="Longitude", ylabel="z (m)", title="e(y, z)") -axκyz = Axis(fig[3, 3], xlabel="Longitude", ylabel="z (m)", title="κᶜ(y, z)") - -slider = Slider(fig[5, 1:3], range=1:Nt, startvalue=Nt) -n = slider.value - -title = @lift begin - t_day = t[$n] / day - t_year = floor(Int, t_day / 360) - yearday = t_day % 360 - return @sprintf("CATKE Neverworld at % 3d years, % 3d days", t_year, yearday) -end - -Label(fig[0, 1:3], title, fontsize=36) - -using Oceananigans.Operators: ζ₃ᶠᶠᶜ -grid = bxyt.grid -grid = grid.underlying_grid -Nx, Ny, Nz = size(grid) -uxy = Field{Face, Center, Center}(grid, indices=(:, :, 1)) -vxy = Field{Center, Face, Center}(grid, indices=(:, :, 1)) -ζop = KernelFunctionOperation{Face, Face, Center}(ζ₃ᶠᶠᶜ, grid, uxy, vxy) -ζxy = Field(ζop, indices=(:, :, 1)) - -ζxyn = @lift begin - uxyn = uxyt[$n] - vxyn = vxyt[$n] - interior(uxy) .= interior(uxyn) - interior(vxy) .= interior(vxyn) - compute!(ζxy) - return interior(ζxy, :, :, 1) -end - -byz = Field{Nothing, Center, Center}(grid) -N²yz = Field(∂z(byz)) - -N²yzn = @lift begin - byzn = byzt[$n] - interior(byz) .= interior(byzn) - compute!(N²yz) - return interior(N²yz, 1, :, :) -end - -bxyn = @lift interior(bxyt[$n], :, :, 1) -exyn = @lift interior(exyt[$n], :, :, 1) - -byzn = @lift interior(byzt[$n], 1, :, :) -eyzn = @lift interior(eyzt[$n], 1, :, :) -κyzn = @lift interior(κyzt[$n], 1, :, :) - -κlims = @lift begin - κ_mean = mean(filter(!isnan, interior(κyzt[$n]))) - (κ_mean/2, 3κ_mean) -end - -eyzlims = @lift begin - e_mean = mean(filter(!isnan, interior(eyzt[$n]))) - (e_mean/2, 3e_mean) -end - -exylims = @lift begin - e_mean = mean(filter(!isnan, interior(eyzt[$n]))) - (e_mean/10, e_mean) -end - -x, y, z = nodes(bxyt) -xf, yf, zf = nodes(grid, Face(), Face(), Face()) -cbkw = (vertical=false, flipaxis=true, tellwidth=false) - -hm = heatmap!(axbxy, x, y, bxyn, colorrange=(-0.05, 0.05)) -Colorbar(fig[1, 1], hm; label="Buoyancy", cbkw...) - -hm = heatmap!(axζxy, x, y, ζxyn, colormap=:balance, colorrange=(-ζlim, ζlim)) -Colorbar(fig[1, 2], hm; label="Relative vertical vorticity (s⁻¹)", cbkw...) - -hm = heatmap!(axexy, x, y, exyn, colormap=:solar, colorrange=exylims) -Colorbar(fig[1, 3], hm; label="Turbulent kinetic energy (m² s⁻²)", cbkw...) - -cbkw = (vertical=false, flipaxis=false, tellwidth=false) - -hm = heatmap!(axNyz, y, zf, N²yzn, nan_color=:gray, colorrange=(1e-6, 1e-4)) -Colorbar(fig[4, 1], hm; label="Buoyancy gradient (s⁻²)", cbkw...) -contour!(axNyz, y, z, byzn, levels=30, color=:white, linewidth=3) - -hm = heatmap!(axeyz, y, z, eyzn, nan_color=:gray, colormap=:solar, colorrange=eyzlims) -Colorbar(fig[4, 2], hm; label="Turbulent kinetic energy (m² s⁻²)", cbkw...) -contour!(axeyz, y, z, byzn, levels=30, color=:white, linewidth=3) - -hm = heatmap!(axκyz, y, zf, κyzn, nan_color=:gray, colormap=:solar, colorrange=κlims) -Colorbar(fig[4, 3], hm; label="Tracer eddy diffusivity (m² s⁻¹)", cbkw...) -contour!(axκyz, y, z, byzn, levels=30, color=:white, linewidth=3) - -ylims!(axNyz, -4000, 0) -ylims!(axeyz, -4000, 0) -ylims!(axκyz, -4000, 0) - -display(fig) - -record(fig, "catke_neverworld.mp4", 1:Nt, framerate=8) do nn - @info "Recording frame $nn of $Nt..." - n[] = nn -end - diff --git a/examples/compute_mixed_layer_depth.jl b/examples/compute_mixed_layer_depth.jl deleted file mode 100644 index 07defabf..00000000 --- a/examples/compute_mixed_layer_depth.jl +++ /dev/null @@ -1,27 +0,0 @@ -using ClimaOcean.NearGlobalSimulations: one_degree_near_global_simulation -using ClimaOcean.Diagnostics -using Oceananigans -using Oceananigans - -using GLMakie - -# Build the simulation -simulation = one_degree_near_global_simulation(CPU()) -model = simulation.model - -h = MixedLayerDepthField(model) -compute!(h) -x, y, z = nodes(model.tracers.T) - -fig = Figure(resolution=(1800, 1200)) -ax = Axis(fig[1, 1], xlabel="Longitude", ylabel="Latitude") -hm = heatmap!(ax, x, y, interior(h, :, :, 1), colorrange=(-1, 100)) - -Colorbar(fig[1, 2], hm; - vertical = true, - tellheight = false, - flipaxis = true, - label = "Mixed layer depth (m)") - -display(fig) - diff --git a/examples/melting_baroclinicity.jl b/examples/melting_baroclinicity.jl deleted file mode 100644 index fda05588..00000000 --- a/examples/melting_baroclinicity.jl +++ /dev/null @@ -1,244 +0,0 @@ -using Oceananigans -using Oceananigans.Architectures: arch_array -using Oceananigans.Fields: ZeroField, ConstantField -using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity -using Oceananigans.Units -using Oceananigans.Utils: prettysummary - -using SeawaterPolynomials: TEOS10EquationOfState, thermal_expansion, haline_contraction - -using ClimaSeaIce -using ClimaSeaIce: melting_temperature -using ClimaSeaIce.ThermalBoundaryConditions: RadiativeEmission, IceWaterThermalEquilibrium - -using Printf -using GLMakie -using Statistics - -include("ice_ocean_model.jl") - -arch = GPU() -Nx = Ny = 256 -Nz = 10 -Lz = 400 -x = y = (-50kilometers, 50kilometers) -halo = (4, 4, 4) -topology = (Periodic, Bounded, Bounded) - -ice_grid = RectilinearGrid(arch; x, y, - size = (Nx, Ny), - topology = (topology[1], topology[2], Flat), - halo = halo[1:2]) - -ocean_grid = RectilinearGrid(arch; topology, halo, x, y, - size = (Nx, Ny, Nz), - z = (-Lz, 0)) - -# Top boundary conditions: -# - outgoing radiative fluxes emitted from surface -# - incoming shortwave radiation starting after 40 days - -ice_ocean_heat_flux = Field{Center, Center, Nothing}(ice_grid) -top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(ice_grid) -top_salt_flux = Qˢ = Field{Center, Center, Nothing}(ice_grid) -# top_salt_flux = Qˢ = arch_array(arch, zeros(Nx, Ny)) - -# Generate a zero-dimensional grid for a single column slab model - -boundary_conditions = (T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), - S = FieldBoundaryConditions(top=FluxBoundaryCondition(Qˢ))) - -equation_of_state = TEOS10EquationOfState() -buoyancy = SeawaterBuoyancy(; equation_of_state) -horizontal_biharmonic_diffusivity = HorizontalScalarBiharmonicDiffusivity(κ=5e6) - -ocean_model = HydrostaticFreeSurfaceModel(; buoyancy, boundary_conditions, - grid = ocean_grid, - momentum_advection = WENO(), - tracer_advection = WENO(), - #closure = (horizontal_biharmonic_diffusivity, CATKEVerticalDiffusivity()), - closure = CATKEVerticalDiffusivity(), - coriolis = FPlane(f=1.4e-4), - tracers = (:T, :S, :e)) - -Nz = size(ocean_grid, 3) -So = ocean_model.tracers.S -ocean_surface_salinity = view(So, :, :, Nz) -bottom_bc = IceWaterThermalEquilibrium(ConstantField(30)) #ocean_surface_salinity) - -u, v, w = ocean_model.velocities -ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), - v = view(v, :, :, Nz), #interior(v, :, :, Nz), - w = ZeroField()) - -ice_model = SlabSeaIceModel(ice_grid; - velocities = ocean_surface_velocities, - advection = nothing, #WENO(), - ice_consolidation_thickness = 0.05, - ice_salinity = 4, - internal_thermal_flux = ConductiveFlux(conductivity=2), - #top_thermal_flux = ConstantField(-100), # W m⁻² - top_thermal_flux = ConstantField(0), # W m⁻² - top_thermal_boundary_condition = PrescribedTemperature(0), - bottom_thermal_boundary_condition = bottom_bc, - bottom_thermal_flux = ice_ocean_heat_flux) - -ocean_simulation = Simulation(ocean_model; Δt=20minutes, verbose=false) -ice_simulation = Simulation(ice_model, Δt=20minutes, verbose=false) - -# Initial condition -S₀ = 30 -T₀ = melting_temperature(ice_model.phase_transitions.liquidus, S₀) + 2.0 - -N²S = 1e-6 -β = haline_contraction(T₀, S₀, 0, equation_of_state) -g = ocean_model.buoyancy.model.gravitational_acceleration -dSdz = - g * β * N²S - -uᵢ(x, y, z) = 0.0 -Tᵢ(x, y, z) = T₀ # + 0.1 * randn() -Sᵢ(x, y, z) = S₀ + dSdz * z #+ 0.1 * randn() - -function hᵢ(x, y) - if sqrt(x^2 + y^2) < 20kilometers - #return 1 + 0.1 * rand() - return 2 - else - return 0 - end -end - -set!(ocean_model, u=uᵢ, S=Sᵢ, T=T₀) -set!(ice_model, h=hᵢ) - -coupled_model = IceOceanModel(ice_simulation, ocean_simulation) -coupled_simulation = Simulation(coupled_model, Δt=1minutes, stop_time=20days) - -S = ocean_model.tracers.S -by = - g * β * ∂y(S) - -function progress(sim) - h = sim.model.ice.model.ice_thickness - S = sim.model.ocean.model.tracers.S - T = sim.model.ocean.model.tracers.T - u = sim.model.ocean.model.velocities.u - msg1 = @sprintf("Iter: % 6d, time: % 12s", iteration(sim), prettytime(sim)) - msg2 = @sprintf(", max(h): %.2f", maximum(h)) - msg3 = @sprintf(", min(S): %.2f", minimum(S)) - msg4 = @sprintf(", extrema(T): (%.2f, %.2f)", minimum(T), maximum(T)) - msg5 = @sprintf(", max|∂y b|: %.2e", maximum(abs, by)) - msg6 = @sprintf(", max|u|: %.2e", maximum(abs, u)) - @info msg1 * msg2 * msg3 * msg4 * msg5 * msg6 - return nothing -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -h = ice_model.ice_thickness -T = ocean_model.tracers.T -S = ocean_model.tracers.S -u, v, w = ocean_model.velocities -η = ocean_model.free_surface.η - -ht = [] -Tt = [] -Ft = [] -Qt = [] -St = [] -ut = [] -vt = [] -ηt = [] -ζt = [] -tt = [] - -ζ = Field(∂x(v) - ∂y(u)) - -function saveoutput(sim) - compute!(ζ) - hn = Array(interior(h, :, :, 1)) - Fn = Array(interior(Qˢ, :, :, 1)) - Qn = Array(interior(Qᵀ, :, :, 1)) - Tn = Array(interior(T, :, :, Nz)) - Sn = Array(interior(S, :, :, Nz)) - un = Array(interior(u, :, :, Nz)) - vn = Array(interior(v, :, :, Nz)) - ηn = Array(interior(η, :, :, 1)) - ζn = Array(interior(ζ, :, :, Nz)) - push!(ht, hn) - push!(Ft, Fn) - push!(Qt, Qn) - push!(Tt, Tn) - push!(St, Sn) - push!(ut, un) - push!(vt, vn) - push!(ηt, ηn) - push!(ζt, ζn) - push!(tt, time(sim)) -end - -coupled_simulation.callbacks[:output] = Callback(saveoutput, IterationInterval(10)) - -run!(coupled_simulation) - -##### -##### Viz -##### - -set_theme!(Theme(fontsize=24)) - -x = xnodes(ocean_grid, Center()) -y = ynodes(ocean_grid, Center()) - -fig = Figure(resolution=(2400, 700)) - -axh = Axis(fig[1, 1], xlabel="x (km)", ylabel="y (km)", title="Ice thickness") -axT = Axis(fig[1, 2], xlabel="x (km)", ylabel="y (km)", title="Ocean surface temperature") -axS = Axis(fig[1, 3], xlabel="x (km)", ylabel="y (km)", title="Ocean surface salinity") -axZ = Axis(fig[1, 4], xlabel="x (km)", ylabel="y (km)", title="Ocean vorticity") - -Nt = length(tt) -slider = Slider(fig[2, 1:4], range=1:Nt, startvalue=Nt) -n = slider.value - -title = @lift string("Melt-driven baroclinic instability after ", prettytime(tt[$n])) -Label(fig[0, 1:3], title) - -hn = @lift ht[$n] -Fn = @lift Ft[$n] -Tn = @lift Tt[$n] -Sn = @lift St[$n] -un = @lift ut[$n] -vn = @lift vt[$n] -ηn = @lift ηt[$n] -ζn = @lift ζt[$n] -Un = @lift mean(ut[$n], dims=1)[:] - -x = x ./ 1e3 -y = y ./ 1e3 - -Stop = view(S, :, :, Nz) -Smax = maximum(Stop) -Smin = minimum(Stop) - -compute!(ζ) -ζtop = view(ζ, :, :, Nz) -ζmax = maximum(abs, ζtop) -ζlim = 2e-4 #ζmax / 2 - -heatmap!(axh, x, y, hn, colorrange=(0, 1), colormap=:grays) -heatmap!(axT, x, y, Tn, colormap=:thermal) -heatmap!(axS, x, y, Sn, colorrange = (29, 30), colormap=:haline) -heatmap!(axZ, x, y, ζn, colorrange=(-ζlim, ζlim), colormap=:redblue) - -#heatmap!(axZ, x, y, Tn, colormap=:thermal) -#heatmap!(axF, x, y, Fn) - -display(fig) - -#= -record(fig, "salty_baroclinic_ice_cube.mp4", 1:Nt, framerate=48) do nn - @info string(nn) - n[] = nn -end -=# - diff --git a/examples/quarter_degree_near_global_simulation.jl b/examples/quarter_degree_near_global_simulation.jl deleted file mode 100644 index b687792a..00000000 --- a/examples/quarter_degree_near_global_simulation.jl +++ /dev/null @@ -1,96 +0,0 @@ -using ClimaOcean.NearGlobalSimulations: quarter_degree_near_global_simulation - -using Oceananigans -using Oceananigans.Units -using Oceananigans.Utils: WallTimeInterval -using Oceananigans.BuoyancyModels: buoyancy -using Oceananigans.Models.HydrostaticFreeSurfaceModels: VerticalVorticityField -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: - MixingLength, TurbulentKineticEnergyEquation, CATKEVerticalDiffusivity - -using ParameterEstimocean.Parameters: closure_with_parameters -using JLD2 - -##### -##### Boundary layer turbulence closure options -##### - -# "Ri-based" --- uses calibrated defaults in Oceananigans -ri_based = RiBasedVerticalDiffusivity() - -# Choose closure -boundary_layer_turbulence_closure = ri_based - -@show boundary_layer_turbulence_closure - -##### -##### Build the simulation -##### - -start_time = 0days -stop_time = start_time + 10years - -simulation = quarter_degree_near_global_simulation(; start_time, stop_time, boundary_layer_turbulence_closure) - -# Define output -slices_save_interval = 1day -fields_save_interval = 30days -Nx, Ny, Nz = size(simulation.model.grid) - -dir = "/storage2/simone/quarter-degree-data/" -closure_name = typeof(boundary_layer_turbulence_closure).name.wrapper -output_prefix = "near_global_$(Nx)_$(Ny)_$(Nz)_$closure_name" - -simulation.output_writers[:checkpointer] = Checkpointer(simulation.model; dir, - prefix = output_prefix * "_checkpointer", - schedule = WallTimeInterval(10minutes), - cleanup = true, - overwrite_existing = true) - -model = simulation.model - -simulation.output_writers[:fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); dir, - schedule = TimeInterval(slices_save_interval), - filename = output_prefix * "_fields", - with_halos = true, - overwrite_existing = true) - -slice_indices = [(:, :, Nz), (:, :, Nz-10)] -output_names = [:surface, :near_surface] -for n = 1:2 - indices = slice_indices[n] - - outputs = Dict() - - for name in keys(model.tracers) - c = model.tracers[name] - outputs[name] = Field(c; indices) - end - - outputs[:u] = Field(model.velocities.u; indices) - outputs[:v] = Field(model.velocities.v; indices) - outputs[:w] = Field(model.velocities.w; indices) - outputs[:η] = model.free_surface.η - outputs[:ζ] = VerticalVorticityField(model.grid, model.velocities; indices) - - name = output_names[n] - simulation.output_writers[name] = JLD2OutputWriter(model, outputs; dir, - schedule = TimeInterval(slices_save_interval), - filename = output_prefix * "_fields_$name", - with_halos = true, - overwrite_existing = true) -end - -@info "Running a simulation with Δt = $(prettytime(simulation.Δt))" - -spinup = 11days -simulation.Δt = 1minute -simulation.stop_time = time(simulation) + spinup -run!(simulation) - -simulation.stop_time = start_time + 2.2years - spinup -simulation.Δt = 10minutes -run!(simulation) - -@info "Simulation took $(prettytime(simulation.run_wall_time))." - diff --git a/examples/quarter_degree_omip_run.jl b/examples/quarter_degree_omip_run.jl deleted file mode 100644 index 8a5afb84..00000000 --- a/examples/quarter_degree_omip_run.jl +++ /dev/null @@ -1,36 +0,0 @@ -using GLMakie -using Oceananigans -using ClimaOcean.Bathymetry: regrid_bathymetry -using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching - -##### -##### Quarter degree near-global grid -##### - -arch = CPU() - -z_faces = stretched_vertical_faces(surface_layer_Δz = 8, - surface_layer_height = 128, - stretching = PowerLawStretching(1.02), - minimum_depth = 6000) - -grid = LatitudeLongitudeGrid(arch; - size = (4 * 360, 4 * 160, 1), - latitude = (-80, 80), - longitude = (-180, 180), - z = z_faces, - halo = (4, 4, 4)) - -h = regrid_bathymetry(grid, height_above_water=1, minimum_depth=5) - -λ, φ, z = nodes(h) - -land = interior(h) .> 0 -interior(h)[land] .= NaN - -fig = Figure(resolution=(2400, 1200)) -ax = Axis(fig[1, 1], xlabel="Longitude", ylabel="Latitude") -heatmap!(ax, λ, φ, interior(h, :, :, 1), nan_color=:white, colorrange=(-5000, 0)) - -display(fig) - diff --git a/examples/run_neverworld_simulation.jl b/examples/run_neverworld_simulation.jl deleted file mode 100644 index 0acddbe3..00000000 --- a/examples/run_neverworld_simulation.jl +++ /dev/null @@ -1,135 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity -using Oceananigans.ImmersedBoundaries: PartialCellBottom, GridFittedBottom -using ClimaOcean.IdealizedSimulations: neverworld_simulation -using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching -using Printf -using CUDA - -closure = CATKEVerticalDiffusivity(minimum_turbulent_kinetic_energy = 1e-6, - minimum_convective_buoyancy_flux = 1e-11) - -# closure = RiBasedVerticalDiffusivity() - -z = stretched_vertical_faces(surface_layer_Δz = 8, - surface_layer_height = 64, - stretching = PowerLawStretching(1.02), - maximum_Δz = 400.0, - minimum_depth = 4000) - -simulation = neverworld_simulation(GPU(); z, - #ImmersedBoundaryType = GridFittedBottom, - ImmersedBoundaryType = PartialCellBottom, - horizontal_resolution = 1/8, - longitude = (0, 60), - latitude = (-70, 0), - time_step = 10minutes, - stop_time = 4 * 360days, - closure) - -model = simulation.model -grid = model.grid - -@show grid -@show model - -start_time = Ref(time_ns()) -previous_model_time = Ref(time(simulation)) - -function progress(sim) - b = sim.model.tracers.b - e = sim.model.tracers.e - u, v, w = sim.model.velocities - - msg = @sprintf("Iter: %d, time: %s, extrema(b): (%6.2e, %6.2e)", - iteration(sim), prettytime(sim), minimum(b), maximum(b)) - - msg *= @sprintf(", max(e): %6.2e", maximum(e)) - - msg *= @sprintf(", max|u|: %6.2e, max|w|: %6.2e", - maximum(maximum(abs, q) for q in (u, v, w)), maximum(abs, w)) - - try - κᶜ = sim.model.diffusivity_fields.κᶜ - msg *= @sprintf(", max(κᶜ): %6.2e", maximum(κᶜ)) - catch - end - - elapsed = 1e-9 * (time_ns() - start_time[]) - elapsed_model_time = time(sim) - previous_model_time[] - SYPD = (elapsed_model_time/360days) / (elapsed/day) - - msg *= @sprintf(", wall time: %s, SYPD: %.1f", prettytime(elapsed), SYPD) - start_time[] = time_ns() - previous_model_time[] = time(sim) - - @info msg - - return nothing -end - -simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -# Set up output -Nx, Ny, Nz = size(grid) -Δt = simulation.Δt -Δt_minutes = round(Int, Δt / minutes) -ib_str = grid.immersed_boundary isa PartialCellBottom ? "partial_cells" : "full_cells" -output_suffix = "$(Nx)_$(Ny)_$(Nz)_dt$(Δt_minutes)_$(ib_str).jld2" -output_dir = "." #/nobackup1/glwagner/" -fine_output_frequency = 1day -i = round(Int, Nx/10) # index for yz-sliced output - -z = znodes(grid, Face(), with_halos=true) - -K = CUDA.@allowscalar [Nz, - searchsortedfirst(z, -100), - searchsortedfirst(z, -400)] - -i = round(Int, Nx/10) # index for yz-sliced output - -diffusivity_fields = (; κᶜ = model.diffusivity_fields.κᶜ) -outputs = merge(model.velocities, model.tracers, diffusivity_fields) -zonally_averaged_outputs = NamedTuple(n => Average(outputs[n], dims=1) for n in keys(outputs)) - -simulation.output_writers[:yz] = JLD2OutputWriter(model, outputs; - schedule = TimeInterval(fine_output_frequency), - filename = joinpath(output_dir, "neverworld_yz_" * output_suffix), - indices = (i, :, :), - with_halos = true, - overwrite_existing = true) - -simulation.output_writers[:zonal] = JLD2OutputWriter(model, zonally_averaged_outputs; - schedule = TimeInterval(fine_output_frequency), - filename = joinpath(output_dir, "neverworld_zonal_average_" * output_suffix), - with_halos = true, - overwrite_existing = true) - -for (n, k) in enumerate(K) - name = Symbol(:xy, n) - simulation.output_writers[name] = JLD2OutputWriter(model, outputs; - schedule = TimeInterval(fine_output_frequency), - filename = joinpath(output_dir, "neverworld_xy$(n)_" * output_suffix), - indices = (:, :, Nz), - with_halos = true, - overwrite_existing = true) -end - -simulation.output_writers[:xyz] = JLD2OutputWriter(model, outputs; - schedule = TimeInterval(90days), - filename = joinpath(output_dir, "neverworld_xyz_" * output_suffix), - with_halos = true, - overwrite_existing = true) - -simulation.output_writers[:checkpointer] = Checkpointer(model, - schedule = TimeInterval(360days), - dir = output_dir, - prefix = "neverworld_$(Nx)_$(Ny)_$(Nz)_checkpoint", - cleanup = true) - -@info "Running..." -@show simulation - -run!(simulation) - diff --git a/examples/distributed_perfect_one_degree_model_calibration.jl b/experiments/one_degree_simulations/distributed_perfect_one_degree_model_calibration.jl similarity index 100% rename from examples/distributed_perfect_one_degree_model_calibration.jl rename to experiments/one_degree_simulations/distributed_perfect_one_degree_model_calibration.jl diff --git a/examples/gm_one_degree_model_calibration.jl b/experiments/one_degree_simulations/gm_one_degree_model_calibration.jl similarity index 100% rename from examples/gm_one_degree_model_calibration.jl rename to experiments/one_degree_simulations/gm_one_degree_model_calibration.jl diff --git a/examples/inspect_one_degree_near_global_simulation.jl b/experiments/one_degree_simulations/inspect_one_degree_near_global_simulation.jl similarity index 100% rename from examples/inspect_one_degree_near_global_simulation.jl rename to experiments/one_degree_simulations/inspect_one_degree_near_global_simulation.jl diff --git a/examples/one_degree_near_global_simulation.jl b/experiments/one_degree_simulations/one_degree_near_global_simulation.jl similarity index 100% rename from examples/one_degree_near_global_simulation.jl rename to experiments/one_degree_simulations/one_degree_near_global_simulation.jl diff --git a/examples/perfect_one_degree_model_calibration.jl b/experiments/one_degree_simulations/perfect_one_degree_model_calibration.jl similarity index 100% rename from examples/perfect_one_degree_model_calibration.jl rename to experiments/one_degree_simulations/perfect_one_degree_model_calibration.jl From aa8c0531bd8911d535991476017a94c7df3440f0 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 15 Nov 2023 08:02:58 -0700 Subject: [PATCH 034/182] Implement JRA55 momentum forcing --- .../prototype_omip_simulation/Manifest.toml | 229 ++++++++++-------- .../omip_simulation.jl | 39 ++- src/ClimaOcean.jl | 3 + src/DataWrangling/JRA55.jl | 38 +-- src/OceanSeaIceModels/OceanSeaIceModels.jl | 39 ++- .../PrescribedAtmospheres.jl | 12 + .../atmosphere_ocean_fluxes.jl | 63 +++-- .../atmosphere_sea_ice_fluxes.jl | 4 +- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 10 +- src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl | 6 +- 10 files changed, 283 insertions(+), 160 deletions(-) create mode 100644 src/OceanSeaIceModels/PrescribedAtmospheres.jl diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 4f68fe87..16dbf360 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -27,9 +27,9 @@ version = "0.4.4" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "76289dc51920fdc6e0013c872ba9551d54961c24" +git-tree-sha1 = "02f731463748db57cc2ebfbd9fbc9ce8280d3433" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.6.2" +version = "3.7.1" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] @@ -47,9 +47,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "f83ec24f76d4c8f525099b2ac475fc098138ec31" +git-tree-sha1 = "16267cf279190ca7c1b30d020758ced95db89cd0" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.4.11" +version = "7.5.1" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -104,9 +104,9 @@ version = "0.4.2" uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" [[deps.BitFlags]] -git-tree-sha1 = "43b1a4a8f797c1cddadf60499a8a077d4af2cd2d" +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.7" +version = "0.1.8" [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -141,20 +141,21 @@ uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" version = "1.0.1+0" [[deps.CUDA]] -deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "Statistics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "f062a48c26ae027f70c44f48f244862aec47bf99" +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", "Statistics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "64461b0e9df3069248979113ce8ab6d11bd371cf" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.0.0" -weakdeps = ["SpecialFunctions"] +version = "5.1.0" +weakdeps = ["ChainRulesCore", "SpecialFunctions"] [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" SpecialFunctionsExt = "SpecialFunctions" [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "2f64185414751a5f878c4ab616c0edd94ade3419" +git-tree-sha1 = "1e42ef1bdb45487ff28de16182c0df4920181dc3" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.6.0+4" +version = "0.7.0+0" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] @@ -164,9 +165,9 @@ version = "0.2.2" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "105eb8cf6ec6e8b93493da42ec789c3f65f7d749" +git-tree-sha1 = "92394521ec4582c11d089a3b15b76ef2cb850994" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.9.2+3" +version = "0.10.0+1" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -197,8 +198,8 @@ uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" version = "0.1.0" [[deps.ClimaSeaIce]] -deps = ["Adapt", "GLMakie", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -path = "/home/greg/Projects/ClimaSeaIce.jl" +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +path = "/Users/gregorywagner/Projects/ClimaSeaIce.jl" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" @@ -277,9 +278,9 @@ version = "1.0.5+1" [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "5372dbbf8f0bdb8c700db5367132925c0771ef7e" +git-tree-sha1 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.2.1" +version = "2.3.0" [[deps.ConstructionBase]] deps = ["LinearAlgebra"] @@ -348,9 +349,9 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelaunayTriangulation]] deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] -git-tree-sha1 = "bea7984f7e09aeb28a3b071c420a0186cb4fabad" +git-tree-sha1 = "7cb0d72a53c1d93665eeadfa9d51af9df60bf6b2" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "0.8.8" +version = "0.8.10" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -364,6 +365,12 @@ git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" version = "1.15.1" +[[deps.DiskArrays]] +deps = ["OffsetArrays"] +git-tree-sha1 = "1bfa9de80f35ac63c6c381b2d43c590875896a1f" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.3.22" + [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" @@ -380,18 +387,20 @@ deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.Distributions]] -deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "3d5873f811f582873bb9871fc9c451784d5dc8c7" +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "a6c00f894f24460379cb7136633cef54ac9f6f4a" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.102" +version = "0.25.103" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" [deps.Distributions.weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.DocStringExtensions]] deps = ["LibGit2"] @@ -589,15 +598,15 @@ version = "3.3.8+0" [[deps.GLMakie]] deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "b46b637cf3e1945354e77c016f867198b829d2f6" +git-tree-sha1 = "8236ce4eda9837d15bab49573bba16ba0652b486" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.8.11" +version = "0.8.12" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "8ad8f375ae365aa1eb2f42e2565a40b55a4b69a8" +git-tree-sha1 = "85d7fb51afb3def5dcb85ad31c3707795c8bccc1" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "9.0.0" +version = "9.1.0" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -607,9 +616,9 @@ version = "0.1.5" [[deps.GPUCompiler]] deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] -git-tree-sha1 = "5e4487558477f191c043166f8301dd0b4be4e2b2" +git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.24.5" +version = "0.25.0" [[deps.GeoInterface]] deps = ["Extents"] @@ -681,6 +690,12 @@ git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" version = "2.8.1+1" +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8ecb0b34472a3c98f945e3c75fc7d5428d165511" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.9.3+0" + [[deps.HypergeometricFunctions]] deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" @@ -779,9 +794,9 @@ version = "0.20.9" [[deps.IntervalSets]] deps = ["Dates", "Random"] -git-tree-sha1 = "8e59ea773deee525c99a8018409f64f19fb719e6" +git-tree-sha1 = "3d8866c029dd6b16e69e0d4a939c4dfcb98fac47" uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.7" +version = "0.7.8" weakdeps = ["Statistics"] [deps.IntervalSets.extensions] @@ -810,9 +825,9 @@ version = "1.8.0" [[deps.IterativeSolvers]] deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] -git-tree-sha1 = "1169632f425f79429f245113b775a0e3d121457c" +git-tree-sha1 = "b435d190ef8369cf4d79cc9dd5fba88ba0165307" uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" -version = "0.9.2" +version = "0.9.3" [[deps.IteratorInterfaceExtensions]] git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" @@ -820,10 +835,10 @@ uuid = "82899510-4779-5014-852e-03e436cf321d" version = "1.0.0" [[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "572d024660119ee626938419c14db0db5f3f3283" +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] +git-tree-sha1 = "9bbb5130d3b4fa52846546bca4791ecbdfb52730" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.36" +version = "0.4.38" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -863,9 +878,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "5f1ecfddb6abde48563d08b2cc7e5116ebcd6c27" +git-tree-sha1 = "95063c5bc98ba0c47e75e05ae71f1fed4deac6f6" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.10" +version = "0.9.12" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -886,16 +901,25 @@ uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" version = "3.100.1+0" [[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Printf", "Unicode"] -git-tree-sha1 = "4ea2928a96acfcf8589e6cd1429eff2a3a82c366" +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] +git-tree-sha1 = "c879e47398a7ab671c782e02b51a4456794a7fa3" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.3.0" +version = "6.4.0" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "e7c01b69bcbcb93fd4cbc3d0fea7d229541e18d2" +git-tree-sha1 = "a84f8f1e8caaaa4e3b4c101306b9e801d3883ace" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.26+0" +version = "0.0.27+0" + +[[deps.LLVMLoopInfo]] +git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" +uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" +version = "1.0.0" [[deps.LLVMOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -910,9 +934,9 @@ uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" version = "2.10.1+0" [[deps.LaTeXStrings]] -git-tree-sha1 = "f2355693d6778a178ade15952b7ac47a4ff97996" +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.3.0" +version = "1.3.1" [[deps.LazyArtifacts]] deps = ["Artifacts", "Pkg"] @@ -1067,9 +1091,9 @@ version = "4.1.2+0" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] -git-tree-sha1 = "781916a2ebf2841467cda03b6f1af43e23839d85" +git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.9" +version = "0.1.10" [[deps.MPItrampoline_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] @@ -1084,16 +1108,16 @@ uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.11" [[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "1d16d20279a145119899b4205258332f0fbeaa94" +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "35fa3c150cd96fd77417a23965b7037b90d6ffc9" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.19.11" +version = "0.19.12" [[deps.MakieCore]] deps = ["Observables", "REPL"] -git-tree-sha1 = "a94bf3fef9c690a2a4ac1d09d86a59ab89c7f8e4" +git-tree-sha1 = "9b11acd07f21c4d035bd4156e789532e8ee2cc70" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.6.8" +version = "0.6.9" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -1104,11 +1128,6 @@ version = "0.4.2" deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" -[[deps.Match]] -git-tree-sha1 = "1d9bc5c1a6e7ee24effb93f175c9342f9154d97f" -uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf" -version = "1.2.0" - [[deps.MathTeXEngine]] deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "Test", "UnicodeFun"] git-tree-sha1 = "8f52dbaa1351ce4cb847d95568cb29e62a307d93" @@ -1116,10 +1135,10 @@ uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" version = "0.5.6" [[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "Random", "Sockets"] -git-tree-sha1 = "03a9b9718f5682ecb107ac9f7308991db4ce395b" +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "f512dc13e64e96f703fd92ce617755ee6b5adf0f" uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.7" +version = "1.1.8" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] @@ -1134,9 +1153,9 @@ version = "0.4.10" [[deps.MicrosoftMPI_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "a7023883872e52bc29bcaac74f19adf39347d2d5" +git-tree-sha1 = "b01beb91d20b0d1312a9471a36017b5b339d26de" uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" -version = "10.1.4+0" +version = "10.1.4+1" [[deps.Missings]] deps = ["DataAPI"] @@ -1174,10 +1193,10 @@ uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" version = "0.4.4" [[deps.NCDatasets]] -deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "4263c4220f22e20729329838bf7e94a49d1ac32f" +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "7fcb4378f9c648a186bcb996fa29acc929a179ed" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.12.17" +version = "0.13.1" [[deps.NLSolversBase]] deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] @@ -1220,15 +1239,15 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.Observables]] -git-tree-sha1 = "6862738f9796b3edc1c09d0890afce4eca9e7e93" +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.5.4" +version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -path = "/home/greg/Projects/Oceananigans.jl" +path = "/Users/gregorywagner/Projects/Oceananigans.jl" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.89.3" +version = "0.90.2" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -1271,10 +1290,10 @@ uuid = "05823500-19ac-5b8b-9628-191a04bc5112" version = "0.8.1+2" [[deps.OpenMPI_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "e25c1778a98e34219a00455d6e4384e017ea9762" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] +git-tree-sha1 = "694458ae803b684f09c07f90459cb79655fb377d" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "4.1.6+0" +version = "5.0.0+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] @@ -1284,9 +1303,9 @@ version = "1.4.1" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "ceeda72c9fd6bbebc4f4f598560789145a8b6c4c" +git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.11+0" +version = "3.0.12+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1318,9 +1337,15 @@ version = "10.42.0+1" [[deps.PDMats]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "66b2fcd977db5329aa35cac121e5b94dd6472198" +git-tree-sha1 = "f6f85a2edb9c356b829934ad3caed2ad0ebbfc99" uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.28" +version = "0.11.29" + +[[deps.PMIx_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] +git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" +uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" +version = "4.2.7+0" [[deps.PNGFiles]] deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] @@ -1354,9 +1379,9 @@ version = "0.12.3" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851" +git-tree-sha1 = "a935806434c9d4c506ba941871b327b96d41f2bf" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.7.2" +version = "2.8.0" [[deps.PencilArrays]] deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] @@ -1380,9 +1405,9 @@ version = "0.15.1" [[deps.Permutations]] deps = ["Combinatorics", "LinearAlgebra", "Random"] -git-tree-sha1 = "25e2bb0973689836bf164ecb960762f1bb8794dd" +git-tree-sha1 = "4f69b02cf40a0f494d0438ab29de32e14ef96e7b" uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" -version = "0.4.17" +version = "0.4.18" [[deps.Pixman_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] @@ -1414,9 +1439,9 @@ version = "0.1.2" [[deps.Polynomials]] deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "ea78a2764f31715093de7ab495e12c0187f231d1" +git-tree-sha1 = "5a95b69396b77fdb2c48970a535610c4743810e2" uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "4.0.4" +version = "4.0.5" [deps.Polynomials.extensions] PolynomialsChainRulesCoreExt = "ChainRulesCore" @@ -1462,9 +1487,9 @@ version = "2.2.8" [[deps.Primes]] deps = ["IntegerMathUtils"] -git-tree-sha1 = "4c9f306e5d6603ae203c2000dd460d81a5251489" +git-tree-sha1 = "1d05623b5952aed1307bf8b43bec8b8d1ef94b6e" uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.5.4" +version = "0.5.5" [[deps.Printf]] deps = ["Unicode"] @@ -1590,9 +1615,9 @@ version = "0.4.1" [[deps.Roots]] deps = ["ChainRulesCore", "CommonSolve", "Printf", "Setfield"] -git-tree-sha1 = "06b5ac80ff1b88bd82df92c1c1875eea3954cd6e" +git-tree-sha1 = "0f1d92463a020321983d04c110f476c274bafe2e" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.0.20" +version = "2.0.22" [deps.Roots.extensions] RootsForwardDiffExt = "ForwardDiff" @@ -1608,9 +1633,9 @@ version = "2.0.20" [[deps.Rotations]] deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "0783924e4a332493f72490253ba4e668aeba1d73" +git-tree-sha1 = "792d8fd4ad770b6d517a13ebb8dadfcac79405b8" uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.6.0" +version = "1.6.1" [[deps.RoundingEmulator]] git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" @@ -1623,9 +1648,9 @@ version = "0.7.0" [[deps.Scratch]] deps = ["Dates"] -git-tree-sha1 = "30449ee12237627992a99d5e30ae63e4d78cd24a" +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.2.0" +version = "1.2.1" [[deps.SeawaterPolynomials]] git-tree-sha1 = "958ba75b90c7c8a117d041d33184134201cf8c0f" @@ -1634,9 +1659,9 @@ version = "0.3.2" [[deps.SentinelArrays]] deps = ["Dates", "Random"] -git-tree-sha1 = "04bdff0b09c65ff3e06a05e3eb7b120223da3d39" +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.0" +version = "1.4.1" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -1741,9 +1766,9 @@ weakdeps = ["ChainRulesCore"] [[deps.StableHashTraits]] deps = ["Compat", "SHA", "Tables", "TupleTools"] -git-tree-sha1 = "19df33ca14f24a3ad2df9e89124bd5f5cc8467a2" +git-tree-sha1 = "d29023a76780bb8a3f2273b29153fd00828cb73f" uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" -version = "1.0.1" +version = "1.1.1" [[deps.StackViews]] deps = ["OffsetArrays"] @@ -1875,9 +1900,9 @@ version = "1.0.1" [[deps.Tables]] deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.0" +version = "1.11.1" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -2107,6 +2132,12 @@ deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" version = "5.8.0+1" +[[deps.libevent_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll"] +git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" +uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" +version = "2.1.13+1" + [[deps.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" @@ -2141,6 +2172,12 @@ deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" +[[deps.prrte_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_jll"] +git-tree-sha1 = "5adb2d7a18a30280feb66cad6f1a1dfdca2dc7b0" +uuid = "eb928a42-fffd-568d-ab9c-3f5d54fc65b9" +version = "3.0.2+0" + [[deps.x264_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index a360a3b0..035f3ce6 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -3,8 +3,8 @@ using Oceananigans.Units using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity using Oceananigans.Fields: ConstantField, ZeroField using ClimaOcean -using ClimaOcean.OceanSeaIceModels: OceanSeaIceModel -using ClimaOcean.OceanSeaIceModels: adjust_ice_covered_ocean_temperature! +using ClimaOcean.OceanSeaIceModels: adjust_ice_covered_ocean_temperature!, PrescribedAtmosphere +using ClimaOcean.JRA55: jra55_field_time_series using ClimaSeaIce using ClimaSeaIce: IceWaterThermalEquilibrium using SeawaterPolynomials.TEOS10: TEOS10EquationOfState @@ -59,9 +59,9 @@ Nx, Ny′, Nz = size(Tᵢ) ##### Construct the grid ##### -arch = GPU() +arch =CPU() southern_limit = -79 -northern_limit = -30 +northern_limit = -50 j₁ = 4 * (90 + southern_limit) j₂ = 720 - 4 * (90 - northern_limit) + 1 Ny = j₂ - j₁ + 1 @@ -177,19 +177,32 @@ ice_model = SlabSeaIceModel(ice_grid; advection = nothing, ice_consolidation_thickness = 0.05, ice_salinity = 4, - internal_thermal_flux = ConductiveFlux(conductivity=2), - top_thermal_flux = ConstantField(0), # W m⁻² - top_thermal_boundary_condition = PrescribedTemperature(0), - bottom_thermal_boundary_condition = bottom_bc, - bottom_thermal_flux = ice_ocean_heat_flux) + internal_heat_flux = ConductiveFlux(conductivity=2), + top_heat_flux = ConstantField(0), # W m⁻² + top_heat_boundary_condition = PrescribedTemperature(0), + bottom_heat_boundary_condition = bottom_bc, + bottom_heat_flux = ice_ocean_heat_flux) set!(ice_model, h=ℋᵢ) -ocean_simulation = Simulation(ocean_model; Δt=5minutes, verbose=false) -ice_simulation = Simulation(ice_model, Δt=5minutes, verbose=false) +ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) +ice = Simulation(ice_model, Δt=5minutes, verbose=false) -coupled_model = OceanSeaIceModel(ice_simulation, ocean_simulation) -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=30days) + +time_indices = 1:10 +u_jra55_native = jra55_field_time_series(:eastward_velocity; time_indices, architecture=arch) +v_jra55_native = jra55_field_time_series(:northward_velocity; time_indices, architecture=arch) + +times = u_jra55_native.times +u_bcs = u_jra55_native.boundary_conditions +v_bcs = v_jra55_native.boundary_conditions +u_jra55 = FieldTimeSeries{Face, Center, Nothing}(grid, times; boundary_conditions=u_bcs) +v_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_conditions=v_bcs) +velocities = (u=u_jra55, v=v_jra55) +atmosphere = PrescribedAtmosphere(velocities, times) + +coupled_model = OceanSeaIceModel(ice, ocean, atmosphere) +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=1) #stop_time=30days) adjust_ice_covered_ocean_temperature!(coupled_model) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 329d16af..dfc29d8e 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -1,5 +1,7 @@ module ClimaOcean +export OceanSeaIceModel + using Oceananigans using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ using DataDeps @@ -67,6 +69,7 @@ include("NearGlobalSimulations/NearGlobalSimulations.jl") include("OceanSeaIceModels/OceanSeaIceModels.jl") using .DataWrangling: JRA55 +using .OceanSeaIceModels: OceanSeaIceModel end # module diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 64ee5db3..3868e698 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -6,7 +6,7 @@ using Oceananigans.BoundaryConditions: fill_halo_regions! using NCDatasets # A list of all variables provided in the JRA55 dataset: -jra55_short_names = (:freshwater_river_flux, +jra55_variable_names = (:freshwater_river_flux, :freshwater_rain_flux, :freshwater_snow_flux, :freshwater_iceberg_flux, @@ -15,9 +15,9 @@ jra55_short_names = (:freshwater_river_flux, :relative_humidity, :downwelling_longwave_radiation, :downwelling_shortwave_radiation, - :atmospheric_temperature, - :atmospheric_eastward_velocity, - :atmospheric_northward_velocity) + :temperature, + :eastward_velocity, + :northward_velocity) file_names = Dict( :freshwater_river_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers @@ -29,9 +29,9 @@ file_names = Dict( :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity :downwelling_longwave_radiation => "RYF.rlds.1990_1991.nc", # Downwelling longwave radiation :downwelling_shortwave_radiation => "RYF.rsds.1990_1991.nc", # Downwelling shortwave radiation - :atmospheric_temperature => "RYF.tas.1990_1991.nc", # Near-surface air temperature - :atmospheric_eastward_velocity => "RYF.uas.1990_1991.nc", # Eastward near-surface wind - :atmospheric_northward_velocity => "RYF.vas.1990_1991.nc", # Northward near-surface wind + :temperature => "RYF.tas.1990_1991.nc", # Near-surface air temperature + :eastward_velocity => "RYF.uas.1990_1991.nc", # Eastward near-surface wind + :northward_velocity => "RYF.vas.1990_1991.nc", # Northward near-surface wind ) short_names = Dict( @@ -44,9 +44,9 @@ short_names = Dict( :relative_humidity => "rhuss", # Surface relative humidity :downwelling_longwave_radiation => "rlds", # Downwelling longwave radiation :downwelling_shortwave_radiation => "rsds", # Downwelling shortwave radiation - :atmospheric_temperature => "tas", # Near-surface air temperature - :atmospheric_eastward_velocity => "uas", # Eastward near-surface wind - :atmospheric_northward_velocity => "vas", # Northward near-surface wind + :temperature => "tas", # Near-surface air temperature + :eastward_velocity => "uas", # Eastward near-surface wind + :northward_velocity => "vas", # Northward near-surface wind ) urls = Dict( @@ -80,14 +80,14 @@ urls = Dict( :downwelling_shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - :atmospheric_temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * - "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", + :temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * + "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", - :atmospheric_eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * - "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", + :eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * + "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", - :atmospheric_northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * - "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", + :northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * + "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", ) """ @@ -118,9 +118,9 @@ available from the JRA55-do are: - `:relative_humidity` ("rhuss") - `:downwelling_longwave_radiation` ("rlds") - `:downwelling_shortwave_radiation` ("rsds") - - `:atmospheric_temperature` ("ras") - - `:atmospheric_eastward_velocity` ("uas") - - `:atmospheric_northward_velocity` ("vas") + - `:temperature` ("ras") + - `:eastward_velocity` ("uas") + - `:northward_velocity` ("vas") Keyword arguments ================= diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index e4b0924d..5ce0e517 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -3,7 +3,7 @@ module OceanSeaIceModels using Oceananigans.Operators using Oceananigans.Architectures: architecture -using Oceananigans.BoundaryConditions: fill_halo_regions! +using Oceananigans.BoundaryConditions: fill_halo_regions!, BoundaryCondition using Oceananigans.Models: AbstractModel using Oceananigans.TimeSteppers: tick! using Oceananigans.Utils: launch! @@ -29,10 +29,46 @@ using Oceananigans.Utils: Time using Oceananigans.Grids: architecture using Oceananigans.Models: AbstractModel +##### +##### Interface +##### + +function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + u = interior(ocean.model.velocities.u, :, :, Nz) + v = interior(ocean.model.velocities.v, :, :, Nz) + w = interior(ocean.model.velocities.w, :, :, Nz+1) + return (; u, v, w) +end + +function surface_flux(f::Field) + top_bc = f.boundary_conditions.top + if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} + return top_bc.condition + else + return nothing + end +end + +##### +##### Some implementation +##### + +include("atmosphere_sea_ice_fluxes.jl") +include("atmosphere_ocean_fluxes.jl") include("sea_ice_ocean_fluxes.jl") include("ocean_sea_ice_model.jl") include("ocean_only_model.jl") +# "No atmosphere" implementation +const NoAtmosphereModel = OceanSeaIceModel{<:Any, <:Any, Nothing} +compute_atmosphere_ocean_fluxes!(coupled_model::NoAtmosphereModel) = nothing + +include("PrescribedAtmospheres.jl") + +using .PrescribedAtmospheres: PrescribedAtmosphere + # Or "AtmosphereModels" # include("Atmospheres.jl") # using .Atmospheres @@ -45,3 +81,4 @@ function default_nan_checker(model::OceanSeaIceModel) end end # module + diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl new file mode 100644 index 00000000..0eec5297 --- /dev/null +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -0,0 +1,12 @@ +module PrescribedAtmospheres + +import ..OceanSeaIceModels: surface_velocities + +struct PrescribedAtmosphere{U, T} + velocities :: U + times :: T +end + +surface_velocities(pa::PrescribedAtmosphere) = pa.velocities + +end # module diff --git a/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl index 2377b499..554e1645 100644 --- a/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl @@ -1,34 +1,57 @@ -# If there is no atmosphere, do not compute fluxes! (this model has the ocean component which -# will handle the top boundary_conditions, for example if we want to impose a value BC) -compute_air_sea_flux!(coupled_model::NoAtmosphereModel) = nothing +function compute_atmosphere_ocean_fluxes!(coupled_model) + ocean = coupled_model.ocean + atmosphere = coupled_model.atmosphere -function compute_air_sea_flux!(coupled_model) - ocean = coupled_model.ocean - forcing = coupled_model.atmospheric_forcing + momentum_fluxes = (u = surface_flux(ocean.model.velocities.u), + v = surface_flux(ocean.model.velocities.v)) - (; T, S) = ocean.model.tracers - (; u, v) = ocean.model.velocities - - grid = ocean.model.grid - clock = ocean.model.clock - fields = prognostic_fields(ocean.model) - - Qˢ = T.boundary_conditions.top.condition - Fˢ = S.boundary_conditions.top.condition - τˣ = u.boundary_conditions.top.condition - τʸ = v.boundary_conditions.top.condition + tracers = ocean.model.tracers + tracer_fluxes = NamedTuple(name => surface_flux(tracers[name]) for name in keys(tracers)) + #= ε = coupled_model.ocean_emissivity ρₒ = coupled_model.ocean_density cₒ = coupled_model.ocean_heat_capacity I₀ = coupled_model.solar_insolation + =# - ice_thickness = coupled_model.ice.model.ice_thickness + grid = ocean.model.grid + arch = architecture(grid) + clock = ocean.model.clock + ocean_velocities = surface_velocities(ocean) + atmosphere_velocities = surface_velocities(atmosphere) + ice_thickness = coupled_model.sea_ice.model.ice_thickness - launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, I₀, - grid, clock, fields, forcing, ice_thickness) + #= + launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, + momentum_fluxes, tracer_fluxes, + ocean_velocities, atmosphere_velocities, ice_thickness) + =# return nothing end +@kernel function _compute_atmosphere_ocean_fluxes!(momentum_fluxes, + tracer_fluxes, + ocean_velocities, + atmosphere_velocities, + ice_thickness) + + i, j = @index(Global, NTuple) + + τˣ = momentum_fluxes.u + τʸ = momentum_fluxes.v + + Cd = 1e-3 + ρₐ = 1.2 + ρₒ = 1020 + + @inbounds begin + ua = atmosphere_velocities.u[i, j, 1] + va = atmosphere_velocities.v[i, j, 1] + + τˣ[i, j, 1] = ρₐ / ρₒ * Cd * ua * sqrt(ua^2 + va^2) + τʸ[i, j, 1] = ρₐ / ρₒ * Cd * va * sqrt(ua^2 + va^2) + end +end diff --git a/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl index e450e3ca..fdc232e6 100644 --- a/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl +++ b/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl @@ -1,3 +1 @@ -# Place holder for now -compute_air_ice_flux!(coupled_model) = nothing - +# Nothing yet... diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 7e42ddb5..86fc0a7e 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -42,7 +42,7 @@ function OceanSeaIceModel(ice, ocean, atmosphere=nothing; previous_ice_concentration = deepcopy(ice.model.ice_concentration) grid = ocean.model.grid - ice_ocean_thermal_flux = Field{Center, Center, Nothing}(grid) + ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) ice_ocean_salt_flux = Field{Center, Center, Nothing}(grid) solar_insolation = Field{Center, Center, Nothing}(grid) @@ -52,10 +52,10 @@ function OceanSeaIceModel(ice, ocean, atmosphere=nothing; # How would we ensure consistency? try - if ice.model.external_thermal_fluxes.top isa RadiativeEmission - ice_radiation = ice.model.external_thermal_fluxes.top + if ice.model.external_heat_fluxes.top isa RadiativeEmission + ice_radiation = ice.model.external_heat_fluxes.top else - ice_radiation = filter(flux isa RadiativeEmission, ice.model.external_thermal_fluxes.top) |> first + ice_radiation = filter(flux isa RadiativeEmission, ice.model.external_heat_fluxes.top) |> first end reference_temperature = ice_radiation.reference_temperature @@ -121,7 +121,7 @@ end function update_state!(coupled_model::OceanSeaIceModel, callbacks=nothing) # update_model_field_time_series!(coupled_model.atmosphere.model) - # compute_atmosphere_ocean_fluxes!(coupled_model) + compute_atmosphere_ocean_fluxes!(coupled_model) # compute_atmosphere_sea_ice_fluxes!(coupled_model) compute_sea_ice_ocean_fluxes!(coupled_model) return nothing diff --git a/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl index 171b86ff..6c21cd5f 100644 --- a/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl @@ -62,7 +62,7 @@ function sea_ice_ocean_latent_heat_flux!(coupled_model) sea_ice = coupled_model.sea_ice ρₒ = coupled_model.ocean_density cₒ = coupled_model.ocean_heat_capacity - Qₒ = sea_ice.model.external_thermal_fluxes.bottom + Qₒ = sea_ice.model.external_heat_fluxes.bottom Tₒ = ocean.model.tracers.T Sₒ = ocean.model.tracers.S Δt = ocean.Δt @@ -83,7 +83,7 @@ end function adjust_ice_covered_ocean_temperature!(coupled_model) sea_ice_ocean_latent_heat_flux!(coupled_model) sea_ice = coupled_model.sea_ice - Qₒ = sea_ice.model.external_thermal_fluxes.bottom + Qₒ = sea_ice.model.external_heat_fluxes.bottom parent(Qₒ) .= 0 return nothing end @@ -129,7 +129,7 @@ end # temperature of the grid cells accordingly. adjust_temperature = freezing | icy_surface_cell - # Compute change in ocean thermal energy. + # Compute change in ocean heat energy. # # - When Tᴺ < Tₘ, we heat the ocean back to melting temperature by extracting heat from the ice, # assuming that the heat flux (which is carried by nascent ice crystals called frazil ice) floats From d7a20d0505c4300b719046536bf0626993c1977e Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 15 Nov 2023 12:48:45 -0700 Subject: [PATCH 035/182] Implementing momentum fluxes --- .../atmosphere_ocean_momentum_flux.jl | 49 +++++++++++++++++ .../compute_atmosphere_ocean_fluxes.jl | 54 +++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl create mode 100644 src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl diff --git a/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl b/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl new file mode 100644 index 00000000..a1aa6eb6 --- /dev/null +++ b/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl @@ -0,0 +1,49 @@ +struct AtmosphereOceanMomentumFlux{F, CD} + formulation :: F + drag_coefficient :: CD +end + +##### +##### Relative velocities +##### + +# Compute the square of a FieldTimeSeries at `time` +@inline Δϕt²(i, j, k, grid, ϕ1t, ϕ2, time) = @inbounds (ϕ1t[i, j, k, time] - ϕ2[i, j, k])^2 + +const ThreeDArray = AbstractArray{<:Any, 3} +const FourDArray = AbstractArray{<:Any, 4} + +@inline function Δu_mod_ΔU(i, j, grid, time::Time, + uₒ::ThreeDArray, + vₒ::ThreeDArray, + uₐ::FourDArray, + vₐ::FourDArray) + + Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] + Δv² = ℑyᶠᶜᶜ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) + return Δu * sqrt(Δu^2 + Δv²) +end + +@inline function Δv_mod_ΔU(i, j, grid, time::Time, + uₒ::ThreeDArray, + vₒ::ThreeDArray, + uₐ::FourDArray, + vₐ::FourDArray) + + Δu² = ℑxᶜᶠᶜ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) + Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] + return Δv * sqrt(Δu² + Δv^2) +end + +@inline function x_atmopsphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) + time = Time(clock.time) + x_ΔU_ΔU = Δu_mod_ΔU(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) + return ρₐ / ρₒ * cᴰ * x_ΔU_ΔU +end + +@inline function y_atmopsphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) + time = Time(clock.time) + y_ΔU_ΔU = Δv_mod_ΔU(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) + return ρₐ / ρₒ * cᴰ * y_ΔU_ΔU +end + diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl new file mode 100644 index 00000000..7df5c0db --- /dev/null +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -0,0 +1,54 @@ +function compute_atmosphere_ocean_fluxes!(coupled_model) + ocean = coupled_model.ocean + atmosphere = coupled_model.atmosphere + + momentum_fluxes = (u = surface_flux(ocean.model.velocities.u), + v = surface_flux(ocean.model.velocities.v)) + + tracers = ocean.model.tracers + tracer_fluxes = NamedTuple(name => surface_flux(tracers[name]) for name in keys(tracers)) + + grid = ocean.model.grid + arch = architecture(grid) + clock = ocean.model.clock + ocean_velocities = surface_velocities(ocean) + ocean_reference_density = coupled_model.ocean_reference_density + atmosphere_velocities = surface_velocities(atmosphere) + ice_thickness = coupled_model.sea_ice.model.ice_thickness + + launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, + grid, clock, momentum_fluxes, tracer_fluxes, + ocean_velocities, atmosphere_velocities, ocean_reference_density, + ice_thickness) + + return nothing +end + + +@kernel function _compute_atmosphere_ocean_fluxes!(grid, + clock, + momentum_fluxes, + tracer_fluxes, + ocean_velocities, + atmosphere_velocities, + ocean_reference_density, + ice_thickness) + + i, j = @index(Global, NTuple) + + τˣ = momentum_fluxes.u + τʸ = momentum_fluxes.v + time = Time(clock.time) + + Uₒ = ocean_velocities + Uₐ = atmosphere_velocities + cᴰ = 1e-3 + ρₐ = 1.2 + ρₒ = ocean_reference_density + + @inbounds begin + τˣ[i, j, 1] = x_atmosphere_ocean_momentum_flux(i, j, grid, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) + τʸ[i, j, 1] = y_atmosphere_ocean_momentum_flux(i, j, grid, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) + end +end + From c108b8d27cbee9a295fc65acdcc96ba2b4113dd9 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 15 Nov 2023 16:35:11 -0700 Subject: [PATCH 036/182] Really a revamp --- .../omip_simulation.jl | 4 +- src/OceanSeaIceModels/OceanSeaIceModels.jl | 8 ++- .../atmosphere_ocean_fluxes.jl | 57 ------------------- .../atmosphere_ocean_momentum_flux.jl | 57 +++++++++++-------- .../compute_atmosphere_ocean_fluxes.jl | 14 +++-- src/OceanSeaIceModels/cross_realm_fluxes.jl | 22 +++++++ src/OceanSeaIceModels/ocean_only_model.jl | 10 +++- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 35 +++++++++--- src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl | 2 +- 9 files changed, 109 insertions(+), 100 deletions(-) delete mode 100644 src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl create mode 100644 src/OceanSeaIceModels/cross_realm_fluxes.jl diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 035f3ce6..ef99aa0b 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -61,7 +61,7 @@ Nx, Ny′, Nz = size(Tᵢ) arch =CPU() southern_limit = -79 -northern_limit = -50 +northern_limit = -75 j₁ = 4 * (90 + southern_limit) j₂ = 720 - 4 * (90 - northern_limit) + 1 Ny = j₂ - j₁ + 1 @@ -204,6 +204,7 @@ atmosphere = PrescribedAtmosphere(velocities, times) coupled_model = OceanSeaIceModel(ice, ocean, atmosphere) coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=1) #stop_time=30days) +#= adjust_ice_covered_ocean_temperature!(coupled_model) wall_clock = Ref(time_ns()) @@ -318,3 +319,4 @@ record(fig, "omip_simulation.mp4", 1:Nt, framerate=24) do nn end =# +=# diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 5ce0e517..fc220f99 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -44,19 +44,25 @@ end function surface_flux(f::Field) top_bc = f.boundary_conditions.top + return top_bc.condition + + #= if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} return top_bc.condition else return nothing end + =# end ##### ##### Some implementation ##### +include("cross_realm_fluxes.jl") include("atmosphere_sea_ice_fluxes.jl") -include("atmosphere_ocean_fluxes.jl") +include("atmosphere_ocean_momentum_flux.jl") +include("compute_atmosphere_ocean_fluxes.jl") include("sea_ice_ocean_fluxes.jl") include("ocean_sea_ice_model.jl") include("ocean_only_model.jl") diff --git a/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl deleted file mode 100644 index 554e1645..00000000 --- a/src/OceanSeaIceModels/atmosphere_ocean_fluxes.jl +++ /dev/null @@ -1,57 +0,0 @@ -function compute_atmosphere_ocean_fluxes!(coupled_model) - ocean = coupled_model.ocean - atmosphere = coupled_model.atmosphere - - momentum_fluxes = (u = surface_flux(ocean.model.velocities.u), - v = surface_flux(ocean.model.velocities.v)) - - tracers = ocean.model.tracers - tracer_fluxes = NamedTuple(name => surface_flux(tracers[name]) for name in keys(tracers)) - - #= - ε = coupled_model.ocean_emissivity - ρₒ = coupled_model.ocean_density - cₒ = coupled_model.ocean_heat_capacity - I₀ = coupled_model.solar_insolation - =# - - grid = ocean.model.grid - arch = architecture(grid) - clock = ocean.model.clock - ocean_velocities = surface_velocities(ocean) - atmosphere_velocities = surface_velocities(atmosphere) - ice_thickness = coupled_model.sea_ice.model.ice_thickness - - #= - launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, - momentum_fluxes, tracer_fluxes, - ocean_velocities, atmosphere_velocities, ice_thickness) - =# - - return nothing -end - -@kernel function _compute_atmosphere_ocean_fluxes!(momentum_fluxes, - tracer_fluxes, - ocean_velocities, - atmosphere_velocities, - ice_thickness) - - i, j = @index(Global, NTuple) - - τˣ = momentum_fluxes.u - τʸ = momentum_fluxes.v - - Cd = 1e-3 - ρₐ = 1.2 - ρₒ = 1020 - - @inbounds begin - ua = atmosphere_velocities.u[i, j, 1] - va = atmosphere_velocities.v[i, j, 1] - - τˣ[i, j, 1] = ρₐ / ρₒ * Cd * ua * sqrt(ua^2 + va^2) - τʸ[i, j, 1] = ρₐ / ρₒ * Cd * va * sqrt(ua^2 + va^2) - end -end - diff --git a/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl b/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl index a1aa6eb6..27655235 100644 --- a/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl +++ b/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl @@ -1,7 +1,4 @@ -struct AtmosphereOceanMomentumFlux{F, CD} - formulation :: F - drag_coefficient :: CD -end +using Oceananigans.Operators: ℑxᶜᵃᵃ, ℑyᵃᶜᵃ ##### ##### Relative velocities @@ -13,37 +10,47 @@ end const ThreeDArray = AbstractArray{<:Any, 3} const FourDArray = AbstractArray{<:Any, 4} -@inline function Δu_mod_ΔU(i, j, grid, time::Time, - uₒ::ThreeDArray, - vₒ::ThreeDArray, - uₐ::FourDArray, - vₐ::FourDArray) +@inline transfer_velocityᶠᶜᶜ(i, j, grid, time, Uₒ, Uₐ) = transfer_velocityᶠᶜᶜ(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) +@inline transfer_velocityᶜᶠᶜ(i, j, grid, time, Uₒ, Uₐ) = transfer_velocityᶜᶠᶜ(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) + +@inline function transfer_velocityᶠᶜᶜ(i, j, grid, time::Time, uₒ, vₒ, + uₐ::FourDArray, vₐ::FourDArray) Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] - Δv² = ℑyᶠᶜᶜ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) - return Δu * sqrt(Δu^2 + Δv²) + Δv² = ℑyᵃᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) + return sqrt(Δu^2 + Δv²) end -@inline function Δv_mod_ΔU(i, j, grid, time::Time, - uₒ::ThreeDArray, - vₒ::ThreeDArray, - uₐ::FourDArray, - vₐ::FourDArray) +@inline function transfer_velocityᶜᶠᶜ(i, j, grid, time::Time, uₒ, vₒ, + uₐ::FourDArray, vₐ::FourDArray) - Δu² = ℑxᶜᶠᶜ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) + Δu² = ℑxᶜᵃᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] - return Δv * sqrt(Δu² + Δv^2) + return sqrt(Δu² + Δv^2) end -@inline function x_atmopsphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) - time = Time(clock.time) - x_ΔU_ΔU = Δu_mod_ΔU(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) - return ρₐ / ρₒ * cᴰ * x_ΔU_ΔU +@inline function Δu_transfer_velocity(i, j, grid, time::Time, uₒ, vₒ, + uₐ::FourDArray, vₐ::FourDArray) + transfer_velocity = transfer_velocityᶠᶜᶜ(i, j, grid, time, uₒ, vₒ, uₐ, vₐ) + Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] + return Δu * transfer_velocity +end + +@inline function Δv_transfer_velocity(i, j, grid, time::Time, uₒ, vₒ, + uₐ::FourDArray, vₐ::FourDArray) + transfer_velocity = transfer_velocityᶠᶜᶜ(i, j, grid, time, uₒ, vₒ, uₐ, vₐ) + Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] + return Δv * transfer_velocity +end + +@inline function x_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) + x_transfer_velocity_transfer_velocity = Δu_transfer_velocity(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) + return ρₐ / ρₒ * cᴰ * x_transfer_velocity_transfer_velocity end -@inline function y_atmopsphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) +@inline function y_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) time = Time(clock.time) - y_ΔU_ΔU = Δv_mod_ΔU(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) - return ρₐ / ρₒ * cᴰ * y_ΔU_ΔU + y_transfer_velocity_transfer_velocity = Δv_transfer_velocity(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) + return ρₐ / ρₒ * cᴰ * y_transfer_velocity_transfer_velocity end diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index 7df5c0db..f8a1ba58 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -2,9 +2,6 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) ocean = coupled_model.ocean atmosphere = coupled_model.atmosphere - momentum_fluxes = (u = surface_flux(ocean.model.velocities.u), - v = surface_flux(ocean.model.velocities.v)) - tracers = ocean.model.tracers tracer_fluxes = NamedTuple(name => surface_flux(tracers[name]) for name in keys(tracers)) @@ -16,6 +13,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_velocities = surface_velocities(atmosphere) ice_thickness = coupled_model.sea_ice.model.ice_thickness + Jₐₒ = coupled_model.atmosphere_ocean_fluxes + launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, grid, clock, momentum_fluxes, tracer_fluxes, ocean_velocities, atmosphere_velocities, ocean_reference_density, @@ -45,10 +44,15 @@ end cᴰ = 1e-3 ρₐ = 1.2 ρₒ = ocean_reference_density + time = Time(clock.time) + + # Compute transfer velocity scale + Utᶠᶜᶜ = transfer_velocityᶠᶜᶜ(i, j, grid, time, Uₒ, Uₐ) + Utᶜᶠᶜ = transfer_velocityᶜᶠᶜ(i, j, grid, time, Uₒ, Uₐ) @inbounds begin - τˣ[i, j, 1] = x_atmosphere_ocean_momentum_flux(i, j, grid, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) - τʸ[i, j, 1] = y_atmosphere_ocean_momentum_flux(i, j, grid, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) + τˣ[i, j, 1] = x_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) + τʸ[i, j, 1] = y_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) end end diff --git a/src/OceanSeaIceModels/cross_realm_fluxes.jl b/src/OceanSeaIceModels/cross_realm_fluxes.jl new file mode 100644 index 00000000..ef20dc41 --- /dev/null +++ b/src/OceanSeaIceModels/cross_realm_fluxes.jl @@ -0,0 +1,22 @@ +struct CrossRealmFluxes{EQ, F} + formula :: EQ + fluxes :: F +end + +struct RelativeSpeed end +struct AtmosphereOnlySpeed end + +struct FluxFormula{T, CD} + transfer_velocity_scale :: T + transfer_coefficient :: CD +end + +function AtmosphereOceanMomentumFlux(; transfer_velocity_scale = RelativeSpeed(), + drag_coefficient = 1e-3) + + return AtmosphereOceanMomentumFlux(transfer_velocity_scale, + drag_coefficient) +end + + + diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 8401a180..1ef186a3 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -6,6 +6,7 @@ OceanOnlyModel(ocean; kw...) = OceanSeaIceModel(nothing, ocean; kw...) ##### No ice-ocean fluxes in this model!! ##### +#= compute_ice_ocean_salinity_flux!(::OceanOnlyModel) = nothing ice_ocean_latent_heat!(::OceanOnlyModel) = nothing @@ -14,12 +15,16 @@ ice_ocean_latent_heat!(::OceanOnlyModel) = nothing ##### function time_step!(coupled_model::OceanOnlyModel, Δt; callbacks=nothing) - compute_air_sea_flux!(coupled_model) time_step!(ocean) tick!(coupled_model.clock, Δt) return nothing end +function update_state!(coupled_model::OceanOnlyModel; callbacks=nothing) + compute_air_sea_flux!(coupled_model) + return nothing +end + function compute_air_sea_fluxes!(coupled_model::OceanOnlyModel) ocean = coupled_model.ocean forcing = coupled_model.atmospheric_forcing @@ -37,7 +42,7 @@ function compute_air_sea_fluxes!(coupled_model::OceanOnlyModel) τʸ = v.boundary_conditions.top.condition ε = coupled_model.ocean_emissivity - ρₒ = coupled_model.ocean_density + ρₒ = coupled_model.ocean_reference_density cₒ = coupled_model.ocean_heat_capacity I₀ = coupled_model.solar_insolation @@ -46,3 +51,4 @@ function compute_air_sea_fluxes!(coupled_model::OceanOnlyModel) return nothing end +=# diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 86fc0a7e..f843c86a 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -2,23 +2,28 @@ using Oceananigans.Models: update_model_field_time_series! using Oceananigans.TimeSteppers: Clock using Oceananigans -struct Radiation{FT, S} - solar_insolation :: S +struct Radiation{FT, SW, LW} + downwelling_shortwave_radiation :: SW + downwelling_longwave_radiation :: LW ocean_emissivity :: FT stefan_boltzmann_constant :: FT reference_temperature :: FT end -struct OceanSeaIceModel{FT, I, A, O, C, G, R, PI, PC} <: AbstractModel{Nothing} +struct OceanSeaIceModel{FT, I, A, O, C, AO, AI, IO, G, R, PI, PC} <: AbstractModel{Nothing} clock :: C grid :: G # TODO: make it so simulation does not require this atmosphere :: A sea_ice :: I ocean :: O + atmosphere_ocean_fluxes :: AO + atmosphere_sea_ice_fluxes :: AI + sea_ice_ocean_fluxes :: IO radiation :: R previous_ice_thickness :: PI previous_ice_concentration :: PC - ocean_density :: FT + # The ocean is Boussinesq, so these are _only_ coupled properties: + ocean_reference_density :: FT ocean_heat_capacity :: FT end @@ -44,9 +49,8 @@ function OceanSeaIceModel(ice, ocean, atmosphere=nothing; grid = ocean.model.grid ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) ice_ocean_salt_flux = Field{Center, Center, Nothing}(grid) - solar_insolation = Field{Center, Center, Nothing}(grid) - ocean_density = 1024 + ocean_reference_density = 1024 ocean_heat_capacity = 3991 reference_temperature = 273.15 @@ -66,20 +70,35 @@ function OceanSeaIceModel(ice, ocean, atmosphere=nothing; ocean_emissivity = 1 stefan_boltzmann_constant = 5.67e-8 - radiation = Radiation(solar_insolation, + radiation = Radiation(nothing, nothing, convert(FT, ocean_emissivity), convert(FT, stefan_boltzmann_constant), convert(FT, reference_temperature)) + # Set up fluxes + momentum_fluxes = (u = surface_flux(ocean.model.velocities.u), + v = surface_flux(ocean.model.velocities.v)) + + @show momentum_fluxes + @show momentum_fluxes.u + @show momentum_fluxes.v + + atmosphere_ocean_fluxes = AtmosphereOceanMomentumFlux() + atmosphere_sea_ice_fluxes = nothing + sea_ice_ocean_fluxes = nothing + return OceanSeaIceModel(clock, ocean.model.grid, atmosphere, ice, ocean, + atmosphere_ocean_fluxes, + atmosphere_sea_ice_fluxes, + sea_ice_ocean_fluxes, radiation, previous_ice_thickness, previous_ice_concentration, - convert(FT, ocean_density), + convert(FT, ocean_reference_density), convert(FT, ocean_heat_capacity)) end diff --git a/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl index 6c21cd5f..bda1319c 100644 --- a/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl @@ -60,7 +60,7 @@ end function sea_ice_ocean_latent_heat_flux!(coupled_model) ocean = coupled_model.ocean sea_ice = coupled_model.sea_ice - ρₒ = coupled_model.ocean_density + ρₒ = coupled_model.ocean_reference_density cₒ = coupled_model.ocean_heat_capacity Qₒ = sea_ice.model.external_heat_fluxes.bottom Tₒ = ocean.model.tracers.T From 9a1652697949c85cf530ac63b3b94352046e0d21 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 16 Nov 2023 06:22:19 -0700 Subject: [PATCH 037/182] Radiation, cross realm fluxs, bulk formula --- .../omip_ocean_component.jl | 37 +++++++ .../omip_sea_ice_component.jl | 34 ++++++ .../omip_simulation.jl | 100 +++--------------- src/OceanSeaIceModels/OceanSeaIceModels.jl | 1 + .../compute_atmosphere_ocean_fluxes.jl | 9 +- src/OceanSeaIceModels/cross_realm_fluxes.jl | 44 +++++--- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 36 ++----- src/OceanSeaIceModels/radiation.jl | 41 +++++++ 8 files changed, 179 insertions(+), 123 deletions(-) create mode 100644 experiments/prototype_omip_simulation/omip_ocean_component.jl create mode 100644 experiments/prototype_omip_simulation/omip_sea_ice_component.jl create mode 100644 src/OceanSeaIceModels/radiation.jl diff --git a/experiments/prototype_omip_simulation/omip_ocean_component.jl b/experiments/prototype_omip_simulation/omip_ocean_component.jl new file mode 100644 index 00000000..9c14b05a --- /dev/null +++ b/experiments/prototype_omip_simulation/omip_ocean_component.jl @@ -0,0 +1,37 @@ +ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) +top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) +top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) +top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) +top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(grid) + +ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), + T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) + +# Model construction +teos10 = TEOS10EquationOfState() +buoyancy = SeawaterBuoyancy(equation_of_state=teos10) + +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: MixingLength +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: TurbulentKineticEnergyEquation + +mixing_length = MixingLength(Cᵇ=0.01) +turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) +closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) + +tracer_advection = WENO() +momentum_advection = VectorInvariant(vorticity_scheme = WENO(), + divergence_scheme = WENO(), + vertical_scheme = WENO()) + +ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, + tracer_advection, momentum_advection, + tracers = (:T, :S, :e), + free_surface = SplitExplicitFreeSurface(cfl=0.2; grid), + boundary_conditions = ocean_boundary_conditions, + coriolis = HydrostaticSphericalCoriolis()) + +set!(ocean_model, T=Tᵢ, S=Sᵢ) + +ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) diff --git a/experiments/prototype_omip_simulation/omip_sea_ice_component.jl b/experiments/prototype_omip_simulation/omip_sea_ice_component.jl new file mode 100644 index 00000000..c93e2770 --- /dev/null +++ b/experiments/prototype_omip_simulation/omip_sea_ice_component.jl @@ -0,0 +1,34 @@ +ice_grid = LatitudeLongitudeGrid(arch, + size = (Nx, Ny), + longitude = (0, 360), + halo = (7, 7), + latitude = (southern_limit, northern_limit), + topology = (Periodic, Bounded, Flat)) + +ice_grid = ImmersedBoundaryGrid(ice_grid, GridFittedBottom(bottom_height)) + +Nz = size(grid, 3) +So = ocean_model.tracers.S +ocean_surface_salinity = view(So, :, :, Nz) +bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) + +u, v, w = ocean_model.velocities +ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), + v = view(v, :, :, Nz), #interior(v, :, :, Nz), + w = ZeroField()) + +ice_model = SlabSeaIceModel(ice_grid; + velocities = ocean_surface_velocities, + advection = nothing, + ice_consolidation_thickness = 0.05, + ice_salinity = 4, + internal_heat_flux = ConductiveFlux(conductivity=2), + top_heat_flux = ConstantField(0), # W m⁻² + top_heat_boundary_condition = PrescribedTemperature(0), + bottom_heat_boundary_condition = bottom_bc, + bottom_heat_flux = ice_ocean_heat_flux) + +set!(ice_model, h=ℋᵢ) + +ice = Simulation(ice_model, Δt=5minutes, verbose=false) + diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index ef99aa0b..17928640 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -2,11 +2,18 @@ using Oceananigans using Oceananigans.Units using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity using Oceananigans.Fields: ConstantField, ZeroField + using ClimaOcean -using ClimaOcean.OceanSeaIceModels: adjust_ice_covered_ocean_temperature!, PrescribedAtmosphere +using ClimaOcean.OceanSeaIceModels: + adjust_ice_covered_ocean_temperature!, + PrescribedAtmosphere, + Radiation + using ClimaOcean.JRA55: jra55_field_time_series + using ClimaSeaIce using ClimaSeaIce: IceWaterThermalEquilibrium + using SeawaterPolynomials.TEOS10: TEOS10EquationOfState using NCDatasets @@ -102,93 +109,13 @@ grid = LatitudeLongitudeGrid(arch, grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) -##### -##### Setup ice model -##### - -ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) -top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) -top_salt_flux = Qˢ = Field{Center, Center, Nothing}(grid) - -ocean_boundary_conditions = (T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), - S = FieldBoundaryConditions(top=FluxBoundaryCondition(Qˢ))) - -#= -using Oceananigans.Grids: φnodes, λnodes - -λ = λnodes(grid, Center()) -φ = φnodes(grid, Center()) - -fig = Figure() -ax = Axis(fig[1, 1]) -heatmap!(ax, λ, φ, bottom_height) -=# - -# Model construction -teos10 = TEOS10EquationOfState() -buoyancy = SeawaterBuoyancy(equation_of_state=teos10) - -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: MixingLength -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: TurbulentKineticEnergyEquation - -mixing_length = MixingLength(Cᵇ=0.01) -turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) -closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) - -tracer_advection = WENO() -momentum_advection = VectorInvariant(vorticity_scheme = WENO(), - divergence_scheme = WENO(), - vertical_scheme = WENO()) - -ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, - tracer_advection, momentum_advection, - tracers = (:T, :S, :e), - free_surface = SplitExplicitFreeSurface(cfl=0.2; grid), - boundary_conditions = ocean_boundary_conditions, - coriolis = HydrostaticSphericalCoriolis()) - -set!(ocean_model, T=Tᵢ, S=Sᵢ) +include("omip_ocean_component.jl") +include("omip_sea_ice_component.jl") ##### -##### Setup ice model +##### Setup JRA55 atmosphere ##### -ice_grid = LatitudeLongitudeGrid(arch, - size = (Nx, Ny), - longitude = (0, 360), - halo = (7, 7), - latitude = (southern_limit, northern_limit), - topology = (Periodic, Bounded, Flat)) - -ice_grid = ImmersedBoundaryGrid(ice_grid, GridFittedBottom(bottom_height)) - -Nz = size(grid, 3) -So = ocean_model.tracers.S -ocean_surface_salinity = view(So, :, :, Nz) -bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) - -u, v, w = ocean_model.velocities -ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), - v = view(v, :, :, Nz), #interior(v, :, :, Nz), - w = ZeroField()) - -ice_model = SlabSeaIceModel(ice_grid; - velocities = ocean_surface_velocities, - advection = nothing, - ice_consolidation_thickness = 0.05, - ice_salinity = 4, - internal_heat_flux = ConductiveFlux(conductivity=2), - top_heat_flux = ConstantField(0), # W m⁻² - top_heat_boundary_condition = PrescribedTemperature(0), - bottom_heat_boundary_condition = bottom_bc, - bottom_heat_flux = ice_ocean_heat_flux) - -set!(ice_model, h=ℋᵢ) - -ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) -ice = Simulation(ice_model, Δt=5minutes, verbose=false) - - time_indices = 1:10 u_jra55_native = jra55_field_time_series(:eastward_velocity; time_indices, architecture=arch) v_jra55_native = jra55_field_time_series(:northward_velocity; time_indices, architecture=arch) @@ -204,6 +131,11 @@ atmosphere = PrescribedAtmosphere(velocities, times) coupled_model = OceanSeaIceModel(ice, ocean, atmosphere) coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=1) #stop_time=30days) +@show coupled_model.atmosphere_ocean_fluxes.momentum.flux.u +@show coupled_model.atmosphere_ocean_fluxes.momentum.formula +@show coupled_model.atmosphere_ocean_fluxes.tracers.T.formula +@show coupled_model.atmosphere_ocean_fluxes.tracers.T.flux + #= adjust_ice_covered_ocean_temperature!(coupled_model) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index fc220f99..370c4848 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -60,6 +60,7 @@ end ##### include("cross_realm_fluxes.jl") +include("radiation.jl") include("atmosphere_sea_ice_fluxes.jl") include("atmosphere_ocean_momentum_flux.jl") include("compute_atmosphere_ocean_fluxes.jl") diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index f8a1ba58..732164b8 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -37,6 +37,9 @@ end τˣ = momentum_fluxes.u τʸ = momentum_fluxes.v + Q = tracer_fluxes.T + F = tracer_fluxes.S + time = Time(clock.time) Uₒ = ocean_velocities @@ -47,12 +50,14 @@ end time = Time(clock.time) # Compute transfer velocity scale - Utᶠᶜᶜ = transfer_velocityᶠᶜᶜ(i, j, grid, time, Uₒ, Uₐ) - Utᶜᶠᶜ = transfer_velocityᶜᶠᶜ(i, j, grid, time, Uₒ, Uₐ) + Vᶠᶜᶜ = transfer_velocityᶠᶜᶜ(i, j, grid, time, Uₒ, Uₐ) + Vᶜᶠᶜ = transfer_velocityᶜᶠᶜ(i, j, grid, time, Uₒ, Uₐ) @inbounds begin τˣ[i, j, 1] = x_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) τʸ[i, j, 1] = y_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) + + # Q[i, j, 1] = ρₐ end end diff --git a/src/OceanSeaIceModels/cross_realm_fluxes.jl b/src/OceanSeaIceModels/cross_realm_fluxes.jl index ef20dc41..70b0d5fb 100644 --- a/src/OceanSeaIceModels/cross_realm_fluxes.jl +++ b/src/OceanSeaIceModels/cross_realm_fluxes.jl @@ -1,22 +1,42 @@ -struct CrossRealmFluxes{EQ, F} - formula :: EQ - fluxes :: F -end +struct RelativeAtmosphereOceanVelocity end +struct AtmosphereVelocity end -struct RelativeSpeed end -struct AtmosphereOnlySpeed end +##### +##### Bulk formula +##### -struct FluxFormula{T, CD} - transfer_velocity_scale :: T +struct BulkFormula{T, CD} + transfer_velocity :: T transfer_coefficient :: CD end -function AtmosphereOceanMomentumFlux(; transfer_velocity_scale = RelativeSpeed(), - drag_coefficient = 1e-3) +function BulkFormula(FT=Float64; + transfer_velocity = RelativeAtmosphereOceanVelocity(), + transfer_coefficient = convert(FT, 1e-3)) + + return BulkFormula(transfer_velocity, transfer_coefficient) +end + +##### +##### Abstraction for fluxes across the realms +##### - return AtmosphereOceanMomentumFlux(transfer_velocity_scale, - drag_coefficient) +struct CrossRealmFlux{EQ, F} + formula :: EQ + flux :: F end +""" + CrossRealmFlux(flux_field; formula = nothing) +May the realms communicate. +""" +function CrossRealmFlux(flux_field; formula = nothing) + + if isnothing(formula) # constant coefficient then + formula = BulkFormula(eltype(flux_field)) + end + + return CrossRealmFlux(formula, flux_field) +end diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index f843c86a..360d0fa5 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -2,14 +2,6 @@ using Oceananigans.Models: update_model_field_time_series! using Oceananigans.TimeSteppers: Clock using Oceananigans -struct Radiation{FT, SW, LW} - downwelling_shortwave_radiation :: SW - downwelling_longwave_radiation :: LW - ocean_emissivity :: FT - stefan_boltzmann_constant :: FT - reference_temperature :: FT -end - struct OceanSeaIceModel{FT, I, A, O, C, AO, AI, IO, G, R, PI, PC} <: AbstractModel{Nothing} clock :: C grid :: G # TODO: make it so simulation does not require this @@ -41,6 +33,7 @@ fields(::OSIM) = NamedTuple() default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) function OceanSeaIceModel(ice, ocean, atmosphere=nothing; + radiation = nothing, clock = default_clock(eltype(ocean.model))) previous_ice_thickness = deepcopy(ice.model.ice_thickness) @@ -65,27 +58,20 @@ function OceanSeaIceModel(ice, ocean, atmosphere=nothing; reference_temperature = ice_radiation.reference_temperature catch end + + u_flux_field = surface_flux(ocean.model.velocities.u) + v_flux_field = surface_flux(ocean.model.velocities.v) - FT = eltype(ocean.model.grid) - ocean_emissivity = 1 - stefan_boltzmann_constant = 5.67e-8 - - radiation = Radiation(nothing, nothing, - convert(FT, ocean_emissivity), - convert(FT, stefan_boltzmann_constant), - convert(FT, reference_temperature)) + momentum_flux = (u = CrossRealmFlux(u_flux_field), + v = CrossRealmFlux(v_flux_field)) - # Set up fluxes - momentum_fluxes = (u = surface_flux(ocean.model.velocities.u), - v = surface_flux(ocean.model.velocities.v)) + tracer_fluxes = (T = nothing, S = nothing) - @show momentum_fluxes - @show momentum_fluxes.u - @show momentum_fluxes.v + atmosphere_ocean_fluxes = (momentum = momentum_flux, + tracers = tracer_fluxes) - atmosphere_ocean_fluxes = AtmosphereOceanMomentumFlux() - atmosphere_sea_ice_fluxes = nothing - sea_ice_ocean_fluxes = nothing + atmosphere_sea_ice_fluxes = NamedTuple() + sea_ice_ocean_fluxes = NamedTuple() return OceanSeaIceModel(clock, ocean.model.grid, diff --git a/src/OceanSeaIceModels/radiation.jl b/src/OceanSeaIceModels/radiation.jl new file mode 100644 index 00000000..5c85f7a1 --- /dev/null +++ b/src/OceanSeaIceModels/radiation.jl @@ -0,0 +1,41 @@ +struct Radiation{FT, SW, LW, OE, IE, OA, IA} + downwelling_shortwave_radiation :: SW + downwelling_longwave_radiation :: LW + ocean_emissivity :: OE + ice_emissivity :: IE + ocean_albedo :: OA + ice_albedo :: IA + stefan_boltzmann_constant :: FT + reference_temperature :: FT +end + +function Radiation(FT=Float64; + downwelling_shortwave_radiation = nothing, + downwelling_longwave_radiation = nothing, + ocean_emissivity = 0.97, + ice_emissivity = 1.0, + ocean_albedo = 0.3, + ice_albedo = 0.7, + stefan_boltzmann_constant = 5.67e-8) + + if downwelling_shortwave_radiation isa AbstractArray + # Replace FT with appropriate eltype + FT = eltype(downwelling_shortwave_radiation) + elseif downwelling_longwave_radiation isa AbstractArray + FT = eltype(downwelling_longwave_radiation) + end + + ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) + ice_emissivity isa Number && (ice_emissivity = convert(FT, ice_emissivity)) + ocean_albedo isa Number && (ocean_albedo = convert(FT, ocean_albedo)) + ice_albedo isa Number && (ice_albedo = convert(FT, ice_albedo)) + + return Radiation(downwelling_shortwave_radiation, + downwelling_longwave_radiation, + ocean_emissivity, + ice_emissivity, + ocean_albedo, + ice_albedo, + stefan_boltzmann_constant) +end + From 1713ee13244b35e79baf11fdd1e672411be8120c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 20 Nov 2023 09:35:45 -0700 Subject: [PATCH 038/182] Starts implementing better interface for fluxes --- src/OceanSeaIceModels/OceanSeaIceModels.jl | 26 ------ src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl | 92 +++++++++++++++++++ src/OceanSeaIceModels/ocean_sea_ice_model.jl | 40 +------- 3 files changed, 96 insertions(+), 62 deletions(-) create mode 100644 src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 370c4848..5779096c 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -29,32 +29,6 @@ using Oceananigans.Utils: Time using Oceananigans.Grids: architecture using Oceananigans.Models: AbstractModel -##### -##### Interface -##### - -function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) - grid = ocean.model.grid - Nz = size(grid, 3) - u = interior(ocean.model.velocities.u, :, :, Nz) - v = interior(ocean.model.velocities.v, :, :, Nz) - w = interior(ocean.model.velocities.w, :, :, Nz+1) - return (; u, v, w) -end - -function surface_flux(f::Field) - top_bc = f.boundary_conditions.top - return top_bc.condition - - #= - if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} - return top_bc.condition - else - return nothing - end - =# -end - ##### ##### Some implementation ##### diff --git a/src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl new file mode 100644 index 00000000..fa842d8c --- /dev/null +++ b/src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl @@ -0,0 +1,92 @@ +##### +##### Utilities +##### + +function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + u = interior(ocean.model.velocities.u, :, :, Nz) + v = interior(ocean.model.velocities.v, :, :, Nz) + w = interior(ocean.model.velocities.w, :, :, Nz+1) + return (; u, v, w) +end + +function surface_flux(f::Field) + top_bc = f.boundary_conditions.top + if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} + return top_bc.condition + else + return nothing + end +end + +function extract_top_surface_fluxes(model::HydrostaticFreeSurfaceModel) + u_flux = surface_flux(model.velocities.u) + v_flux = surface_flux(model.velocities.v) + + ocean_momentum_fluxes = (u = u_flux, v = v_flux) + + ocean_tracers = model.tracers + ocean_tracer_fluxes = NamedTuple(name => surface_flux(ocean_tracers[name]) + for name in keys(ocean_tracers)) + + ocean_fluxes = (momentum = ocean_momentum_fluxes, + tracers = ocean_tracer_fluxes) + + return ocean_fluxes +end + +##### +##### Total flux across each surface +##### + +struct OceanSeaIceSurfaceFluxes{O, IT, IB} + ocean :: O + sea_ice_top :: IT + sea_ice_bottom :: IB +end + +function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing) + ocean_fluxes = extract_top_surface_fluxes(ocean.model) + + if isnothing(sea_ice) + sea_ice_top_fluxes = nothing + sea_ice_bottom_fluxes = nothing + else + sea_ice_top_fluxes = extract_top_surface_fluxes(ice.model) + sea_ice_bottom_fluxes = extract_bottom_surface_fluxes(ice.model) + end + + return OceanSeaIceSurfaceFluxes(ocean_fluxes, + sea_ice_top_fluxes, + sea_ice_bottom_fluxes) +end + +##### +##### Cross-realm fluxes +##### + +struct CrossRealmFluxes{S, R, AO, AI, IO} + surfaces :: S + radiation :: R + atmosphere_ocean :: AO + atmosphere_sea_ice :: AI + sea_ice_ocean :: IO +end + +function CrossRealmFluxes(ocean_simulation, sea_ice_simulation=nothing; + radiation = nothing, + atmosphere_ocean = nothing, + atmosphere_sea_ice = nothing, + sea_ice_ocean = nothing) + + surfaces = OceanSeaIceSurfaceFluxes(ocean_simulation, sea_ice_simulation) + + return CrossRealmFluxes(surfaces, + radiation, + atmosphere_ocean, + atmosphere_sea_ice, + sea_ice_ocean) +end + + diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 360d0fa5..84391ec5 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -2,16 +2,13 @@ using Oceananigans.Models: update_model_field_time_series! using Oceananigans.TimeSteppers: Clock using Oceananigans -struct OceanSeaIceModel{FT, I, A, O, C, AO, AI, IO, G, R, PI, PC} <: AbstractModel{Nothing} +struct OceanSeaIceModel{FT, I, A, O, F, PI, PC, C, G} <: AbstractModel{Nothing} clock :: C grid :: G # TODO: make it so simulation does not require this atmosphere :: A sea_ice :: I ocean :: O - atmosphere_ocean_fluxes :: AO - atmosphere_sea_ice_fluxes :: AI - sea_ice_ocean_fluxes :: IO - radiation :: R + fluxes :: F previous_ice_thickness :: PI previous_ice_concentration :: PC # The ocean is Boussinesq, so these are _only_ coupled properties: @@ -45,42 +42,13 @@ function OceanSeaIceModel(ice, ocean, atmosphere=nothing; ocean_reference_density = 1024 ocean_heat_capacity = 3991 - reference_temperature = 273.15 - - # How would we ensure consistency? - try - if ice.model.external_heat_fluxes.top isa RadiativeEmission - ice_radiation = ice.model.external_heat_fluxes.top - else - ice_radiation = filter(flux isa RadiativeEmission, ice.model.external_heat_fluxes.top) |> first - end - - reference_temperature = ice_radiation.reference_temperature - catch - end - - u_flux_field = surface_flux(ocean.model.velocities.u) - v_flux_field = surface_flux(ocean.model.velocities.v) - - momentum_flux = (u = CrossRealmFlux(u_flux_field), - v = CrossRealmFlux(v_flux_field)) - - tracer_fluxes = (T = nothing, S = nothing) - - atmosphere_ocean_fluxes = (momentum = momentum_flux, - tracers = tracer_fluxes) - - atmosphere_sea_ice_fluxes = NamedTuple() - sea_ice_ocean_fluxes = NamedTuple() + # reference_temperature = 273.15 # for radiation? return OceanSeaIceModel(clock, ocean.model.grid, atmosphere, ice, ocean, - atmosphere_ocean_fluxes, - atmosphere_sea_ice_fluxes, - sea_ice_ocean_fluxes, radiation, previous_ice_thickness, previous_ice_concentration, @@ -105,7 +73,7 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=nothing) parent(h⁻) .= parent(hⁿ) end - sea_ice.Δt = Δt + sea_ice.Δt = Δt ocean.Δt = Δt time_step!(sea_ice) From f18e716935d5e52422146f0407a7f9b6dbda83c8 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 20 Nov 2023 11:13:46 -0700 Subject: [PATCH 039/182] Let structure take shape --- .../omip_simulation.jl | 7 +- src/OceanSeaIceModels/OceanSeaIceModels.jl | 2 +- src/OceanSeaIceModels/cross_realm_fluxes.jl | 42 ----- src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl | 92 ---------- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 8 +- .../ocean_sea_ice_model_fluxes.jl | 171 ++++++++++++++++++ 6 files changed, 179 insertions(+), 143 deletions(-) delete mode 100644 src/OceanSeaIceModels/cross_realm_fluxes.jl delete mode 100644 src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl create mode 100644 src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 17928640..4899d75a 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -128,14 +128,9 @@ v_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_condition velocities = (u=u_jra55, v=v_jra55) atmosphere = PrescribedAtmosphere(velocities, times) -coupled_model = OceanSeaIceModel(ice, ocean, atmosphere) +coupled_model = OceanSeaIceModel(ocean, ice, atmosphere) coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=1) #stop_time=30days) -@show coupled_model.atmosphere_ocean_fluxes.momentum.flux.u -@show coupled_model.atmosphere_ocean_fluxes.momentum.formula -@show coupled_model.atmosphere_ocean_fluxes.tracers.T.formula -@show coupled_model.atmosphere_ocean_fluxes.tracers.T.flux - #= adjust_ice_covered_ocean_temperature!(coupled_model) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 5779096c..d31b5c4d 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -33,7 +33,7 @@ using Oceananigans.Models: AbstractModel ##### Some implementation ##### -include("cross_realm_fluxes.jl") +include("ocean_sea_ice_model_fluxes.jl") include("radiation.jl") include("atmosphere_sea_ice_fluxes.jl") include("atmosphere_ocean_momentum_flux.jl") diff --git a/src/OceanSeaIceModels/cross_realm_fluxes.jl b/src/OceanSeaIceModels/cross_realm_fluxes.jl deleted file mode 100644 index 70b0d5fb..00000000 --- a/src/OceanSeaIceModels/cross_realm_fluxes.jl +++ /dev/null @@ -1,42 +0,0 @@ -struct RelativeAtmosphereOceanVelocity end -struct AtmosphereVelocity end - -##### -##### Bulk formula -##### - -struct BulkFormula{T, CD} - transfer_velocity :: T - transfer_coefficient :: CD -end - -function BulkFormula(FT=Float64; - transfer_velocity = RelativeAtmosphereOceanVelocity(), - transfer_coefficient = convert(FT, 1e-3)) - - return BulkFormula(transfer_velocity, transfer_coefficient) -end - -##### -##### Abstraction for fluxes across the realms -##### - -struct CrossRealmFlux{EQ, F} - formula :: EQ - flux :: F -end - -""" - CrossRealmFlux(flux_field; formula = nothing) - -May the realms communicate. -""" -function CrossRealmFlux(flux_field; formula = nothing) - - if isnothing(formula) # constant coefficient then - formula = BulkFormula(eltype(flux_field)) - end - - return CrossRealmFlux(formula, flux_field) -end - diff --git a/src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl deleted file mode 100644 index fa842d8c..00000000 --- a/src/OceanSeaIceModels/ocean_sea_ice_fluxes.jl +++ /dev/null @@ -1,92 +0,0 @@ -##### -##### Utilities -##### - -function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) - grid = ocean.model.grid - Nz = size(grid, 3) - u = interior(ocean.model.velocities.u, :, :, Nz) - v = interior(ocean.model.velocities.v, :, :, Nz) - w = interior(ocean.model.velocities.w, :, :, Nz+1) - return (; u, v, w) -end - -function surface_flux(f::Field) - top_bc = f.boundary_conditions.top - if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} - return top_bc.condition - else - return nothing - end -end - -function extract_top_surface_fluxes(model::HydrostaticFreeSurfaceModel) - u_flux = surface_flux(model.velocities.u) - v_flux = surface_flux(model.velocities.v) - - ocean_momentum_fluxes = (u = u_flux, v = v_flux) - - ocean_tracers = model.tracers - ocean_tracer_fluxes = NamedTuple(name => surface_flux(ocean_tracers[name]) - for name in keys(ocean_tracers)) - - ocean_fluxes = (momentum = ocean_momentum_fluxes, - tracers = ocean_tracer_fluxes) - - return ocean_fluxes -end - -##### -##### Total flux across each surface -##### - -struct OceanSeaIceSurfaceFluxes{O, IT, IB} - ocean :: O - sea_ice_top :: IT - sea_ice_bottom :: IB -end - -function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing) - ocean_fluxes = extract_top_surface_fluxes(ocean.model) - - if isnothing(sea_ice) - sea_ice_top_fluxes = nothing - sea_ice_bottom_fluxes = nothing - else - sea_ice_top_fluxes = extract_top_surface_fluxes(ice.model) - sea_ice_bottom_fluxes = extract_bottom_surface_fluxes(ice.model) - end - - return OceanSeaIceSurfaceFluxes(ocean_fluxes, - sea_ice_top_fluxes, - sea_ice_bottom_fluxes) -end - -##### -##### Cross-realm fluxes -##### - -struct CrossRealmFluxes{S, R, AO, AI, IO} - surfaces :: S - radiation :: R - atmosphere_ocean :: AO - atmosphere_sea_ice :: AI - sea_ice_ocean :: IO -end - -function CrossRealmFluxes(ocean_simulation, sea_ice_simulation=nothing; - radiation = nothing, - atmosphere_ocean = nothing, - atmosphere_sea_ice = nothing, - sea_ice_ocean = nothing) - - surfaces = OceanSeaIceSurfaceFluxes(ocean_simulation, sea_ice_simulation) - - return CrossRealmFluxes(surfaces, - radiation, - atmosphere_ocean, - atmosphere_sea_ice, - sea_ice_ocean) -end - - diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 84391ec5..939759f8 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -29,7 +29,7 @@ prognostic_fields(cm::OSIM) = nothing fields(::OSIM) = NamedTuple() default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) -function OceanSeaIceModel(ice, ocean, atmosphere=nothing; +function OceanSeaIceModel(ocean, ice=nothing, atmosphere=nothing; radiation = nothing, clock = default_clock(eltype(ocean.model))) @@ -43,13 +43,17 @@ function OceanSeaIceModel(ice, ocean, atmosphere=nothing; ocean_reference_density = 1024 ocean_heat_capacity = 3991 # reference_temperature = 273.15 # for radiation? + + fluxes = CrossRealmFluxes(ocean, ice; radiation) + + FT = eltype(ocean.model.grid) return OceanSeaIceModel(clock, ocean.model.grid, atmosphere, ice, ocean, - radiation, + fluxes, previous_ice_thickness, previous_ice_concentration, convert(FT, ocean_reference_density), diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl new file mode 100644 index 00000000..a437b3ce --- /dev/null +++ b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl @@ -0,0 +1,171 @@ +using Oceananigans.Models.HydrostaticFreeSurfaceModels: HydrostaticFreeSurfaceModel +using ClimaSeaIce.SlabSeaIceModels: SlabSeaIceModel + +##### +##### Utilities +##### + +function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + u = interior(ocean.model.velocities.u, :, :, Nz) + v = interior(ocean.model.velocities.v, :, :, Nz) + w = interior(ocean.model.velocities.w, :, :, Nz+1) + return (; u, v, w) +end + +function surface_flux(f::Field) + top_bc = f.boundary_conditions.top + if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} + return top_bc.condition + else + return nothing + end +end + +##### +##### Convenience containers for surface fluxes +##### + +struct OceanSurfaceFluxes{M, T} + momentum :: M + tracers :: T +end + +Base.summary(osf::OceanSurfaceFluxes) = "OceanSurfaceFluxes" +Base.show(io::IO, osf::OceanSurfaceFluxes) = print(io, summary(osf)) + +struct SeaIceSurfaceFluxes{M, T} + momentum :: M + tracers :: T +end + +Base.summary(sisf::SeaIceSurfaceFluxes) = "SeaIceSurfaceFluxes" +Base.show(io::IO, sisf::SeaIceSurfaceFluxes) = print(io, summary(sisf)) + +function extract_top_surface_fluxes(model::HydrostaticFreeSurfaceModel) + u_flux = surface_flux(model.velocities.u) + v_flux = surface_flux(model.velocities.v) + + ocean_momentum_fluxes = (u = u_flux, v = v_flux) + + ocean_tracers = model.tracers + + ocean_tracer_fluxes = NamedTuple(name => surface_flux(ocean_tracers[name]) + for name in keys(ocean_tracers) + if surface_flux(ocean_tracers[name]) isa AbstractArray) + + ocean_fluxes = OceanSurfaceFluxes(ocean_momentum_fluxes, + ocean_tracer_fluxes) + + return ocean_fluxes +end + +extract_top_surface_fluxes(model::SlabSeaIceModel) = nothing +extract_bottom_surface_fluxes(model::SlabSeaIceModel) = nothing + +##### +##### Total flux across each surface +##### + +struct OceanSeaIceSurfaces{O, IT, IB} + ocean :: O + sea_ice_top :: IT + sea_ice_bottom :: IB +end + +Base.summary(osis::OceanSeaIceSurfaces) = "OceanSeaIceSurfaces" +Base.show(io::IO, osis::OceanSeaIceSurfaces) = print(io, summary(osis)) + +function OceanSeaIceSurfaces(ocean, sea_ice=nothing) + ocean_fluxes = extract_top_surface_fluxes(ocean.model) + + if isnothing(sea_ice) + sea_ice_top_fluxes = nothing + sea_ice_bottom_fluxes = nothing + else + sea_ice_top_fluxes = extract_top_surface_fluxes(sea_ice.model) + sea_ice_bottom_fluxes = extract_bottom_surface_fluxes(sea_ice.model) + end + + return OceanSeaIceSurfaces(ocean_fluxes, + sea_ice_top_fluxes, + sea_ice_bottom_fluxes) +end + +##### +##### Cross-realm fluxes +##### + +struct CrossRealmFluxes{S, R, AO, AI, IO} + surfaces :: S + radiation :: R + atmosphere_ocean :: AO + atmosphere_sea_ice :: AI + sea_ice_ocean :: IO +end + +function CrossRealmFluxes(ocean_simulation, sea_ice_simulation=nothing; + radiation = nothing, + atmosphere_ocean = nothing, + atmosphere_sea_ice = nothing, + sea_ice_ocean = nothing) + + surfaces = OceanSeaIceSurfaces(ocean_simulation, sea_ice_simulation) + + return CrossRealmFluxes(surfaces, + radiation, + atmosphere_ocean, + atmosphere_sea_ice, + sea_ice_ocean) +end + +Base.summary(crf::CrossRealmFluxes) = "CrossRealmFluxes" +Base.show(io::IO, crf::CrossRealmFluxes) = print(io, summary(crf)) + +##### +##### CrossRealmFlux +##### + +struct RelativeAtmosphereOceanVelocity end +struct AtmosphereVelocity end + +##### +##### Bulk formula +##### + +struct BulkFormula{T, CD} + transfer_velocity :: T + transfer_coefficient :: CD +end + +function BulkFormula(FT=Float64; + transfer_velocity = RelativeAtmosphereOceanVelocity(), + transfer_coefficient = convert(FT, 1e-3)) + + return BulkFormula(transfer_velocity, transfer_coefficient) +end + +##### +##### Abstraction for fluxes across the realms +##### + +struct CrossRealmFlux{EQ, F} + formula :: EQ + flux :: F +end + +""" + CrossRealmFlux(flux_field; formula = nothing) + +May the realms communicate. +""" +function CrossRealmFlux(flux_field; formula = nothing) + + if isnothing(formula) # constant coefficient then + formula = BulkFormula(eltype(flux_field)) + end + + return CrossRealmFlux(formula, flux_field) +end + From e530248e6522dba95b279b498e45eb24ce2a35f2 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 20 Nov 2023 15:22:52 -0700 Subject: [PATCH 040/182] We have momentum flux --- .../omip_simulation.jl | 17 ++- src/OceanSeaIceModels/OceanSeaIceModels.jl | 5 + .../atmosphere_ocean_momentum_flux.jl | 40 +------ .../compute_atmosphere_ocean_fluxes.jl | 51 ++++++--- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 2 +- .../ocean_sea_ice_model_fluxes.jl | 105 ++++++++++-------- 6 files changed, 117 insertions(+), 103 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 4899d75a..db5350e2 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -131,7 +131,6 @@ atmosphere = PrescribedAtmosphere(velocities, times) coupled_model = OceanSeaIceModel(ocean, ice, atmosphere) coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=1) #stop_time=30days) -#= adjust_ice_covered_ocean_temperature!(coupled_model) wall_clock = Ref(time_ns()) @@ -170,6 +169,22 @@ coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outp run!(coupled_simulation) +using GLMakie + +fig = Figure(resolution=(2400, 1200)) + +axx = Axis(fig[1, 1]) +axy = Axis(fig[1, 2]) + +τˣ = coupled_model.fluxes.surfaces.ocean.momentum.u +τʸ = coupled_model.fluxes.surfaces.ocean.momentum.v +τˣ = interior(τˣ, :, :, 1) +τʸ = interior(τˣ, :, :, 1) + +heatmap!(axx, λ, φ, τˣ) +heatmap!(axy, λ, φ, τʸ) + +#= ##### ##### Visualize ##### diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index d31b5c4d..a52eaf55 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -29,6 +29,11 @@ using Oceananigans.Utils: Time using Oceananigans.Grids: architecture using Oceananigans.Models: AbstractModel +using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries + +const SomeKindOfFieldTimeSeries = Union{FieldTimeSeries, + GPUAdaptedFieldTimeSeries} + ##### ##### Some implementation ##### diff --git a/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl b/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl index 27655235..d68b3a12 100644 --- a/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl +++ b/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl @@ -4,45 +4,6 @@ using Oceananigans.Operators: ℑxᶜᵃᵃ, ℑyᵃᶜᵃ ##### Relative velocities ##### -# Compute the square of a FieldTimeSeries at `time` -@inline Δϕt²(i, j, k, grid, ϕ1t, ϕ2, time) = @inbounds (ϕ1t[i, j, k, time] - ϕ2[i, j, k])^2 - -const ThreeDArray = AbstractArray{<:Any, 3} -const FourDArray = AbstractArray{<:Any, 4} - -@inline transfer_velocityᶠᶜᶜ(i, j, grid, time, Uₒ, Uₐ) = transfer_velocityᶠᶜᶜ(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) -@inline transfer_velocityᶜᶠᶜ(i, j, grid, time, Uₒ, Uₐ) = transfer_velocityᶜᶠᶜ(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) - -@inline function transfer_velocityᶠᶜᶜ(i, j, grid, time::Time, uₒ, vₒ, - uₐ::FourDArray, vₐ::FourDArray) - - Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] - Δv² = ℑyᵃᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) - return sqrt(Δu^2 + Δv²) -end - -@inline function transfer_velocityᶜᶠᶜ(i, j, grid, time::Time, uₒ, vₒ, - uₐ::FourDArray, vₐ::FourDArray) - - Δu² = ℑxᶜᵃᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) - Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] - return sqrt(Δu² + Δv^2) -end - -@inline function Δu_transfer_velocity(i, j, grid, time::Time, uₒ, vₒ, - uₐ::FourDArray, vₐ::FourDArray) - transfer_velocity = transfer_velocityᶠᶜᶜ(i, j, grid, time, uₒ, vₒ, uₐ, vₐ) - Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] - return Δu * transfer_velocity -end - -@inline function Δv_transfer_velocity(i, j, grid, time::Time, uₒ, vₒ, - uₐ::FourDArray, vₐ::FourDArray) - transfer_velocity = transfer_velocityᶠᶜᶜ(i, j, grid, time, uₒ, vₒ, uₐ, vₐ) - Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] - return Δv * transfer_velocity -end - @inline function x_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) x_transfer_velocity_transfer_velocity = Δu_transfer_velocity(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) return ρₐ / ρₒ * cᴰ * x_transfer_velocity_transfer_velocity @@ -54,3 +15,4 @@ end return ρₐ / ρₒ * cᴰ * y_transfer_velocity_transfer_velocity end + diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index 732164b8..cd682305 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -13,49 +13,70 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_velocities = surface_velocities(atmosphere) ice_thickness = coupled_model.sea_ice.model.ice_thickness - Jₐₒ = coupled_model.atmosphere_ocean_fluxes + momentum_flux_fields = coupled_model.fluxes.surfaces.ocean.momentum + momentum_flux_formulae = coupled_model.fluxes.atmosphere_ocean.momentum launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, - grid, clock, momentum_fluxes, tracer_fluxes, - ocean_velocities, atmosphere_velocities, ocean_reference_density, + grid, clock, + momentum_flux_fields, + momentum_flux_formulae, + ocean_velocities, + atmosphere_velocities, ice_thickness) return nothing end +@inline function air_sea_difference(i, j, grid, time, ::RelativeAtmosphereOceanVelocity, + air::SomeKindOfFieldTimeSeries, sea::AbstractArray) + + return @inbounds air[i, j, 1, time] - sea[i, j, 1] +end @kernel function _compute_atmosphere_ocean_fluxes!(grid, clock, - momentum_fluxes, - tracer_fluxes, + momentum_flux_fields, + momentum_flux_formula, ocean_velocities, atmosphere_velocities, - ocean_reference_density, ice_thickness) i, j = @index(Global, NTuple) - τˣ = momentum_fluxes.u - τʸ = momentum_fluxes.v - Q = tracer_fluxes.T - F = tracer_fluxes.S + τˣ = momentum_flux_fields.u + τʸ = momentum_flux_fields.v + # Q = tracer_fluxes.T + # F = tracer_fluxes.S time = Time(clock.time) Uₒ = ocean_velocities Uₐ = atmosphere_velocities + uₐ = Uₐ.u + vₐ = Uₐ.v + uₒ = Uₒ.u + vₒ = Uₒ.v + cᴰ = 1e-3 ρₐ = 1.2 - ρₒ = ocean_reference_density + ρₒ = 1024 time = Time(clock.time) + u_formula = momentum_flux_formula.u.transfer_velocity + v_formula = momentum_flux_formula.v.transfer_velocity + + cᴰ = momentum_flux_formula.u.transfer_coefficient + # Compute transfer velocity scale - Vᶠᶜᶜ = transfer_velocityᶠᶜᶜ(i, j, grid, time, Uₒ, Uₐ) - Vᶜᶠᶜ = transfer_velocityᶜᶠᶜ(i, j, grid, time, Uₒ, Uₐ) + Vᶠᶜᶜ = transfer_velocityᶠᶜᶜ(i, j, grid, time, u_formula, Uₐ, Uₒ) + Vᶜᶠᶜ = transfer_velocityᶜᶠᶜ(i, j, grid, time, v_formula, Uₐ, Uₒ) + + Δu = air_sea_difference(i, j, grid, time, u_formula, uₐ, uₒ) + Δv = air_sea_difference(i, j, grid, time, v_formula, vₐ, vₒ) @inbounds begin - τˣ[i, j, 1] = x_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) - τʸ[i, j, 1] = y_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) + τˣ[i, j, 1] = - ρₐ / ρₒ * cᴰ * Δu * Vᶠᶜᶜ + τʸ[i, j, 1] = - ρₐ / ρₒ * cᴰ * Δv * Vᶜᶠᶜ # Q[i, j, 1] = ρₐ end diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 939759f8..6b7dd091 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -44,7 +44,7 @@ function OceanSeaIceModel(ocean, ice=nothing, atmosphere=nothing; ocean_heat_capacity = 3991 # reference_temperature = 273.15 # for radiation? - fluxes = CrossRealmFluxes(ocean, ice; radiation) + fluxes = OceanSeaIceModelFluxes(ocean, ice; radiation) FT = eltype(ocean.model.grid) diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl index a437b3ce..2e4a7df1 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl @@ -25,23 +25,26 @@ end ##### ##### Convenience containers for surface fluxes +##### +##### "Cross realm fluxes" can refer to the flux _data_ (ie, fields representing +##### the total flux for a given variable), or to the flux _components_ / formula. ##### -struct OceanSurfaceFluxes{M, T} +struct CrossRealmFluxes{M, H, T} momentum :: M + heat :: H tracers :: T end -Base.summary(osf::OceanSurfaceFluxes) = "OceanSurfaceFluxes" -Base.show(io::IO, osf::OceanSurfaceFluxes) = print(io, summary(osf)) +CrossRealmFluxes(; momentum=nothing, heat=nothing, tracers=nothing) = + CrossRealmFluxes(momentum, heat, tracers) -struct SeaIceSurfaceFluxes{M, T} - momentum :: M - tracers :: T -end +Base.summary(osf::CrossRealmFluxes) = "CrossRealmFluxes" +Base.show(io::IO, osf::CrossRealmFluxes) = print(io, summary(osf)) -Base.summary(sisf::SeaIceSurfaceFluxes) = "SeaIceSurfaceFluxes" -Base.show(io::IO, sisf::SeaIceSurfaceFluxes) = print(io, summary(sisf)) +##### +##### Extractors for differnet models (maybe this belongs in the model repo's) +##### function extract_top_surface_fluxes(model::HydrostaticFreeSurfaceModel) u_flux = surface_flux(model.velocities.u) @@ -55,8 +58,8 @@ function extract_top_surface_fluxes(model::HydrostaticFreeSurfaceModel) for name in keys(ocean_tracers) if surface_flux(ocean_tracers[name]) isa AbstractArray) - ocean_fluxes = OceanSurfaceFluxes(ocean_momentum_fluxes, - ocean_tracer_fluxes) + ocean_fluxes = CrossRealmFluxes(momentum = ocean_momentum_fluxes, + tracers = ocean_tracer_fluxes) return ocean_fluxes end @@ -94,10 +97,10 @@ function OceanSeaIceSurfaces(ocean, sea_ice=nothing) end ##### -##### Cross-realm fluxes +##### Container for organizing information related to fluxes ##### -struct CrossRealmFluxes{S, R, AO, AI, IO} +struct OceanSeaIceModelFluxes{S, R, AO, AI, IO} surfaces :: S radiation :: R atmosphere_ocean :: AO @@ -105,23 +108,31 @@ struct CrossRealmFluxes{S, R, AO, AI, IO} sea_ice_ocean :: IO end -function CrossRealmFluxes(ocean_simulation, sea_ice_simulation=nothing; - radiation = nothing, - atmosphere_ocean = nothing, - atmosphere_sea_ice = nothing, - sea_ice_ocean = nothing) +function OceanSeaIceModelFluxes(ocean, sea_ice=nothing; + radiation = nothing, + atmosphere_ocean = nothing, + atmosphere_sea_ice = nothing, + sea_ice_ocean = nothing) + + surfaces = OceanSeaIceSurfaces(ocean, sea_ice) - surfaces = OceanSeaIceSurfaces(ocean_simulation, sea_ice_simulation) + if isnothing(atmosphere_ocean) # defaults + FT = eltype(ocean.model.grid) + τˣ = BulkFormula(FT, transfer_coefficient=1e-3) + τʸ = BulkFormula(FT, transfer_coefficient=1e-3) + momentum_flux_formulae = (u=τˣ, v=τʸ) + atmosphere_ocean = CrossRealmFluxes(momentum = momentum_flux_formulae) + end - return CrossRealmFluxes(surfaces, - radiation, - atmosphere_ocean, - atmosphere_sea_ice, - sea_ice_ocean) + return OceanSeaIceModelFluxes(surfaces, + radiation, + atmosphere_ocean, + atmosphere_sea_ice, + sea_ice_ocean) end -Base.summary(crf::CrossRealmFluxes) = "CrossRealmFluxes" -Base.show(io::IO, crf::CrossRealmFluxes) = print(io, summary(crf)) +Base.summary(crf::OceanSeaIceModelFluxes) = "OceanSeaIceModelFluxes" +Base.show(io::IO, crf::OceanSeaIceModelFluxes) = print(io, summary(crf)) ##### ##### CrossRealmFlux @@ -141,31 +152,31 @@ end function BulkFormula(FT=Float64; transfer_velocity = RelativeAtmosphereOceanVelocity(), - transfer_coefficient = convert(FT, 1e-3)) + transfer_coefficient = 1e-3) - return BulkFormula(transfer_velocity, transfer_coefficient) + return BulkFormula(transfer_velocity, + convert(FT, transfer_coefficient)) end -##### -##### Abstraction for fluxes across the realms -##### - -struct CrossRealmFlux{EQ, F} - formula :: EQ - flux :: F -end +@inline Δϕt²(i, j, k, grid, ϕ1t, ϕ2, time) = @inbounds (ϕ1t[i, j, k, time] - ϕ2[i, j, k])^2 -""" - CrossRealmFlux(flux_field; formula = nothing) +@inline function transfer_velocityᶠᶜᶜ(i, j, grid, time, ::RelativeAtmosphereOceanVelocity, Uₐ, Uₒ) + uₐ = Uₐ.u + vₐ = Uₐ.v + uₒ = Uₒ.u + vₒ = Uₒ.v -May the realms communicate. -""" -function CrossRealmFlux(flux_field; formula = nothing) - - if isnothing(formula) # constant coefficient then - formula = BulkFormula(eltype(flux_field)) - end - - return CrossRealmFlux(formula, flux_field) + Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] + Δv² = ℑyᵃᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) + return sqrt(Δu^2 + Δv²) end +@inline function transfer_velocityᶜᶠᶜ(i, j, grid, time, ::RelativeAtmosphereOceanVelocity, Uₐ, Uₒ) + uₐ = Uₐ.u + vₐ = Uₐ.v + uₒ = Uₒ.u + vₒ = Uₒ.v + Δu² = ℑxᶜᵃᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) + Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] + return sqrt(Δu² + Δv^2) +end From 5e47a56148a55bcd1aff1f89f1e4ad935d22e262 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 20 Nov 2023 19:46:36 -0700 Subject: [PATCH 041/182] Forgot to interpolate JRA55 data --- .../omip_simulation.jl | 26 ++++++++++++++----- .../compute_atmosphere_ocean_fluxes.jl | 14 +++++++++- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index db5350e2..edce7c4d 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -1,3 +1,4 @@ +#= using Oceananigans using Oceananigans.Units using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity @@ -121,15 +122,17 @@ u_jra55_native = jra55_field_time_series(:eastward_velocity; time_indices, arch v_jra55_native = jra55_field_time_series(:northward_velocity; time_indices, architecture=arch) times = u_jra55_native.times -u_bcs = u_jra55_native.boundary_conditions -v_bcs = v_jra55_native.boundary_conditions +u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing)) +v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing)) u_jra55 = FieldTimeSeries{Face, Center, Nothing}(grid, times; boundary_conditions=u_bcs) v_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_conditions=v_bcs) +interpolate!(u_jra55, u_jra55_native) +interpolate!(v_jra55, v_jra55_native) velocities = (u=u_jra55, v=v_jra55) atmosphere = PrescribedAtmosphere(velocities, times) coupled_model = OceanSeaIceModel(ocean, ice, atmosphere) -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=1) #stop_time=30days) +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) #stop_time=30days) adjust_ice_covered_ocean_temperature!(coupled_model) @@ -168,8 +171,11 @@ coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outp overwrite_existing = true) run!(coupled_simulation) +=# -using GLMakie +using ClimaOcean.OceanSeaIceModels: compute_atmosphere_ocean_fluxes! + +compute_atmosphere_ocean_fluxes!(coupled_model) fig = Figure(resolution=(2400, 1200)) @@ -178,11 +184,17 @@ axy = Axis(fig[1, 2]) τˣ = coupled_model.fluxes.surfaces.ocean.momentum.u τʸ = coupled_model.fluxes.surfaces.ocean.momentum.v + +λf, φc, zc = nodes(τˣ) +λc, φf, zc = nodes(τʸ) + τˣ = interior(τˣ, :, :, 1) -τʸ = interior(τˣ, :, :, 1) +τʸ = interior(τʸ, :, :, 1) -heatmap!(axx, λ, φ, τˣ) -heatmap!(axy, λ, φ, τʸ) +heatmap!(axx, λf, φc, τˣ) +heatmap!(axy, λc, φf, τʸ) + +display(fig) #= ##### diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index cd682305..e26ad881 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -30,7 +30,9 @@ end @inline function air_sea_difference(i, j, grid, time, ::RelativeAtmosphereOceanVelocity, air::SomeKindOfFieldTimeSeries, sea::AbstractArray) - return @inbounds air[i, j, 1, time] - sea[i, j, 1] + δ = @inbounds air[i, j, 1, time] - sea[i, j, 1] + @show air[i, j, 1, time] time δ + return δ end @kernel function _compute_atmosphere_ocean_fluxes!(grid, @@ -74,10 +76,20 @@ end Δu = air_sea_difference(i, j, grid, time, u_formula, uₐ, uₒ) Δv = air_sea_difference(i, j, grid, time, v_formula, vₐ, vₒ) + @show uₒ[i, j, 1] + @show vₒ[i, j, 1] + @show Vᶠᶜᶜ + @show Vᶜᶠᶜ + @show Δu + @show Δv + @inbounds begin τˣ[i, j, 1] = - ρₐ / ρₒ * cᴰ * Δu * Vᶠᶜᶜ τʸ[i, j, 1] = - ρₐ / ρₒ * cᴰ * Δv * Vᶜᶠᶜ + @show τˣ[i, j, 1] + @show τʸ[i, j, 1] + # Q[i, j, 1] = ρₐ end end From 2292cf858dfdd7aa904971a57af48be11f2562b6 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 21 Nov 2023 07:02:04 -0700 Subject: [PATCH 042/182] Add radiation --- .../omip_simulation.jl | 25 +++++--- .../compute_atmosphere_ocean_fluxes.jl | 57 ++++++++++++------- src/OceanSeaIceModels/radiation.jl | 7 ++- 3 files changed, 60 insertions(+), 29 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index edce7c4d..fa304fca 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -1,8 +1,7 @@ -#= using Oceananigans using Oceananigans.Units using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity -using Oceananigans.Fields: ConstantField, ZeroField +using Oceananigans.Fields: ConstantField, ZeroField, interpolate! using ClimaOcean using ClimaOcean.OceanSeaIceModels: @@ -69,7 +68,7 @@ Nx, Ny′, Nz = size(Tᵢ) arch =CPU() southern_limit = -79 -northern_limit = -75 +northern_limit = -50 j₁ = 4 * (90 + southern_limit) j₂ = 720 - 4 * (90 - northern_limit) + 1 Ny = j₂ - j₁ + 1 @@ -131,7 +130,19 @@ interpolate!(v_jra55, v_jra55_native) velocities = (u=u_jra55, v=v_jra55) atmosphere = PrescribedAtmosphere(velocities, times) -coupled_model = OceanSeaIceModel(ocean, ice, atmosphere) +tracer_flux_bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing)) +Qlw_jra55_native = jra55_field_time_series(:downwelling_longwave_radiation; time_indices, architecture=arch) +Qsw_jra55_native = jra55_field_time_series(:downwelling_shortwave_radiation; time_indices, architecture=arch) + +Qlw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=tracer_flux_bcs) +Qsw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=tracer_flux_bcs) +interpolate!(Qlw_jra55, Qlw_jra55_native) +interpolate!(Qsw_jra55, Qsw_jra55_native) + +radiation = Radiation(downwelling_shortwave_radiation = Qsw_jra55, + downwelling_longwave_radiation = Qlw_jra55) + +coupled_model = OceanSeaIceModel(ocean, ice, atmosphere; radiation) coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) #stop_time=30days) adjust_ice_covered_ocean_temperature!(coupled_model) @@ -171,11 +182,9 @@ coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outp overwrite_existing = true) run!(coupled_simulation) -=# - -using ClimaOcean.OceanSeaIceModels: compute_atmosphere_ocean_fluxes! -compute_atmosphere_ocean_fluxes!(coupled_model) +# using ClimaOcean.OceanSeaIceModels: compute_atmosphere_ocean_fluxes! +# compute_atmosphere_ocean_fluxes!(coupled_model) fig = Figure(resolution=(2400, 1200)) diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index e26ad881..60b159e3 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -14,14 +14,26 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) ice_thickness = coupled_model.sea_ice.model.ice_thickness momentum_flux_fields = coupled_model.fluxes.surfaces.ocean.momentum - momentum_flux_formulae = coupled_model.fluxes.atmosphere_ocean.momentum + tracer_flux_fields = coupled_model.fluxes.surfaces.ocean.tracers + momentum_flux_contributions = coupled_model.fluxes.atmosphere_ocean.momentum + heat_flux_contributions = coupled_model.fluxes.atmosphere_ocean.heat + tracer_flux_contributions = coupled_model.fluxes.atmosphere_ocean.heat + + atmosphere_ocean_parameters = ( + ρₐ = 1.2, + ρₒ = 1024,, + cₚ = 3991.0, + ) launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, grid, clock, momentum_flux_fields, - momentum_flux_formulae, + tracer_flux_fields, + momentum_flux_contributions, + heat_flux_contributions ocean_velocities, atmosphere_velocities, + atmosphere_ocean_parameters, ice_thickness) return nothing @@ -31,16 +43,21 @@ end air::SomeKindOfFieldTimeSeries, sea::AbstractArray) δ = @inbounds air[i, j, 1, time] - sea[i, j, 1] - @show air[i, j, 1, time] time δ + #@show air[i, j, 1, time] time δ return δ end @kernel function _compute_atmosphere_ocean_fluxes!(grid, clock, momentum_flux_fields, - momentum_flux_formula, + tracer_flux_fields, + momentum_flux_contributions, + heat_flux_contributions, + tracer_flux_contributions, ocean_velocities, atmosphere_velocities, + radiation, + atmosphere_ocean_parameters, ice_thickness) i, j = @index(Global, NTuple) @@ -59,15 +76,15 @@ end uₒ = Uₒ.u vₒ = Uₒ.v - cᴰ = 1e-3 - ρₐ = 1.2 - ρₒ = 1024 + ρₐ = atmosphere_ocean_parameters.ρₐ + ρₒ = atmosphere_ocean_parameters.ρₒ + cₚ = atmosphere_ocean_parameters.cₚ time = Time(clock.time) - u_formula = momentum_flux_formula.u.transfer_velocity - v_formula = momentum_flux_formula.v.transfer_velocity + u_formula = momentum_flux_contributions.u.transfer_velocity + v_formula = momentum_flux_contributions.v.transfer_velocity - cᴰ = momentum_flux_formula.u.transfer_coefficient + cᴰ = momentum_flux_contributions.u.transfer_coefficient # Compute transfer velocity scale Vᶠᶜᶜ = transfer_velocityᶠᶜᶜ(i, j, grid, time, u_formula, Uₐ, Uₒ) @@ -76,21 +93,21 @@ end Δu = air_sea_difference(i, j, grid, time, u_formula, uₐ, uₒ) Δv = air_sea_difference(i, j, grid, time, v_formula, vₐ, vₒ) - @show uₒ[i, j, 1] - @show vₒ[i, j, 1] - @show Vᶠᶜᶜ - @show Vᶜᶠᶜ - @show Δu - @show Δv - @inbounds begin τˣ[i, j, 1] = - ρₐ / ρₒ * cᴰ * Δu * Vᶠᶜᶜ τʸ[i, j, 1] = - ρₐ / ρₒ * cᴰ * Δv * Vᶜᶠᶜ - @show τˣ[i, j, 1] - @show τʸ[i, j, 1] + # @show τˣ[i, j, 1] + # @show τʸ[i, j, 1] - # Q[i, j, 1] = ρₐ + Q[i, j, 1] = radiative_fluxes(i, j, grid, time, radiation) end end +@inline function radiative_fluxes(i, j, grid, time, radiation) + Qˢʷ = radiation.downwelling_shortwave_radiation + Qˡʷ = radiation.downwelling_longwave_radiation + α = radiation.ocean_albedo + return @inbounds (1 - α) * Qˢʷ[i, j, 1, time] + Qˡʷ[i, j, 1, time] +end + diff --git a/src/OceanSeaIceModels/radiation.jl b/src/OceanSeaIceModels/radiation.jl index 5c85f7a1..55e0fdfb 100644 --- a/src/OceanSeaIceModels/radiation.jl +++ b/src/OceanSeaIceModels/radiation.jl @@ -16,6 +16,7 @@ function Radiation(FT=Float64; ice_emissivity = 1.0, ocean_albedo = 0.3, ice_albedo = 0.7, + reference_temperature = 273.15, stefan_boltzmann_constant = 5.67e-8) if downwelling_shortwave_radiation isa AbstractArray @@ -36,6 +37,10 @@ function Radiation(FT=Float64; ice_emissivity, ocean_albedo, ice_albedo, - stefan_boltzmann_constant) + stefan_boltzmann_constant, + reference_temperature) end +Base.summary(r::Radiation) = "Radiation" +Base.show(io::IO, r::Radiation) = print(io, summary(osf)) + From a16c354880d6ff09560d846c637dfeae3b61972c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 21 Nov 2023 12:40:34 -0700 Subject: [PATCH 043/182] Get the radiation fluxes in there --- .../omip_atmosphere_and_radiation.jl | 65 ++++++++ .../omip_simulation.jl | 85 ++++++---- src/OceanSeaIceModels/OceanSeaIceModels.jl | 3 + .../PrescribedAtmospheres.jl | 4 +- .../compute_atmosphere_ocean_fluxes.jl | 156 ++++++++++++++---- .../ocean_sea_ice_model_fluxes.jl | 49 +----- 6 files changed, 251 insertions(+), 111 deletions(-) create mode 100644 experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl diff --git a/experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl b/experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl new file mode 100644 index 00000000..3f5f0515 --- /dev/null +++ b/experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl @@ -0,0 +1,65 @@ +##### +##### Setup JRA55 atmosphere +##### + +time_indices = 1:10 + +u_jra55_native = jra55_field_time_series(:eastward_velocity; time_indices, architecture=arch) +v_jra55_native = jra55_field_time_series(:northward_velocity; time_indices, architecture=arch) + +T_jra55_native = jra55_field_time_series(:temperature; time_indices, architecture=arch) +q_jra55_native = jra55_field_time_series(:relative_humidity; time_indices, architecture=arch) + +Fr_jra55_native = jra55_field_time_series(:freshwater_rain_flux; time_indices, architecture=arch) +Fs_jra55_native = jra55_field_time_series(:freshwater_snow_flux; time_indices, architecture=arch) +#Fv_jra55_native = jra55_field_time_series(:freshwater_river_flux; time_indices, architecture=arch) +#Fi_jra55_native = jra55_field_time_series(:freshwater_iceberg_flux; time_indices, architecture=arch) + +times = u_jra55_native.times + +u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing)) +v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing)) +c_bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing)) + +u_jra55 = FieldTimeSeries{Face, Center, Nothing}(grid, times; boundary_conditions=u_bcs) +v_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_conditions=v_bcs) + +T_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +q_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Fr_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Fs_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) + +interpolate!(u_jra55, u_jra55_native) +interpolate!(v_jra55, v_jra55_native) +interpolate!(T_jra55, T_jra55_native) +interpolate!(q_jra55, q_jra55_native) +interpolate!(Fr_jra55, Fr_jra55_native) +interpolate!(Fs_jra55, Fs_jra55_native) + +velocities = (u = u_jra55, + v = v_jra55) + +tracers = (T = T_jra55, + q = q_jra55) + +freshwater_fluxes = (rain = Fr_jra55, + snow = Fs_jra55) + +atmosphere = PrescribedAtmosphere(velocities, freshwater_fluxes, tracers, times) + +##### +##### Radiation +##### + +Qlw_jra55_native = jra55_field_time_series(:downwelling_longwave_radiation; time_indices, architecture=arch) +Qsw_jra55_native = jra55_field_time_series(:downwelling_shortwave_radiation; time_indices, architecture=arch) + +Qlw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Qsw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) + +interpolate!(Qlw_jra55, Qlw_jra55_native) +interpolate!(Qsw_jra55, Qsw_jra55_native) + +radiation = Radiation(downwelling_shortwave_radiation = Qsw_jra55, + downwelling_longwave_radiation = Qlw_jra55) + diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index fa304fca..4b77e5cd 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -1,3 +1,4 @@ +#= using Oceananigans using Oceananigans.Units using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity @@ -66,9 +67,9 @@ Nx, Ny′, Nz = size(Tᵢ) ##### Construct the grid ##### -arch =CPU() +arch = CPU() southern_limit = -79 -northern_limit = -50 +northern_limit = -30 j₁ = 4 * (90 + southern_limit) j₂ = 720 - 4 * (90 - northern_limit) + 1 Ny = j₂ - j₁ + 1 @@ -109,38 +110,15 @@ grid = LatitudeLongitudeGrid(arch, grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) +# Defines `ocean`, an `Oceananigans.Simulation` include("omip_ocean_component.jl") -include("omip_sea_ice_component.jl") -##### -##### Setup JRA55 atmosphere -##### +# Defines `sea_ice`, an `Oceananigans.Simulation` +include("omip_sea_ice_component.jl") -time_indices = 1:10 -u_jra55_native = jra55_field_time_series(:eastward_velocity; time_indices, architecture=arch) -v_jra55_native = jra55_field_time_series(:northward_velocity; time_indices, architecture=arch) - -times = u_jra55_native.times -u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing)) -v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing)) -u_jra55 = FieldTimeSeries{Face, Center, Nothing}(grid, times; boundary_conditions=u_bcs) -v_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_conditions=v_bcs) -interpolate!(u_jra55, u_jra55_native) -interpolate!(v_jra55, v_jra55_native) -velocities = (u=u_jra55, v=v_jra55) -atmosphere = PrescribedAtmosphere(velocities, times) - -tracer_flux_bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing)) -Qlw_jra55_native = jra55_field_time_series(:downwelling_longwave_radiation; time_indices, architecture=arch) -Qsw_jra55_native = jra55_field_time_series(:downwelling_shortwave_radiation; time_indices, architecture=arch) - -Qlw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=tracer_flux_bcs) -Qsw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=tracer_flux_bcs) -interpolate!(Qlw_jra55, Qlw_jra55_native) -interpolate!(Qsw_jra55, Qsw_jra55_native) - -radiation = Radiation(downwelling_shortwave_radiation = Qsw_jra55, - downwelling_longwave_radiation = Qlw_jra55) +# Defines `atmosphere`, a `ClimaOcean.OceanSeaIceModels.PrescribedAtmosphere` +# also defines `radiation`, a `ClimaOcean.OceanSeaIceModels.Radiation` +include("omip_atmosphere_and_radiation.jl") coupled_model = OceanSeaIceModel(ocean, ice, atmosphere; radiation) coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) #stop_time=30days) @@ -182,6 +160,7 @@ coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outp overwrite_existing = true) run!(coupled_simulation) +=# # using ClimaOcean.OceanSeaIceModels: compute_atmosphere_ocean_fluxes! # compute_atmosphere_ocean_fluxes!(coupled_model) @@ -189,19 +168,57 @@ run!(coupled_simulation) fig = Figure(resolution=(2400, 1200)) axx = Axis(fig[1, 1]) -axy = Axis(fig[1, 2]) +axy = Axis(fig[2, 1]) +axQ = Axis(fig[3, 1]) τˣ = coupled_model.fluxes.surfaces.ocean.momentum.u τʸ = coupled_model.fluxes.surfaces.ocean.momentum.v +Jᵀ = coupled_model.fluxes.surfaces.ocean.tracers.T + +ρₒ = coupled_model.ocean_reference_density +cₚ = coupled_model.ocean_heat_capacity +Q = Field(ρₒ * cₚ * Jᵀ) +compute!(Q) λf, φc, zc = nodes(τˣ) λc, φf, zc = nodes(τʸ) +λc, φc, zc = nodes(Q) τˣ = interior(τˣ, :, :, 1) τʸ = interior(τʸ, :, :, 1) +Q = interior(Q, :, :, 1) + +# τˣ ./= ρₒ +# τʸ ./= ρₒ + +land = τˣ .== NaN +τˣ[land] .= 0 + +land = τʸ .== NaN +τʸ[land] .= 0 + +Qmax = maximum(abs, Q) +τmax = 1.0 #max(maximum(abs, τˣ), maximum(abs, τʸ)) + +Qlim = 3Qmax / 4 +τlim = 3τmax / 4 + +land = Q .== 0 +Q[land] .= NaN + +land = τˣ .== 0 +τˣ[land] .= NaN + +land = τʸ .== 0 +τʸ[land] .= NaN + +hmx = heatmap!(axx, λf, φc, τˣ, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) +hmy = heatmap!(axy, λc, φf, τʸ, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) +hmQ = heatmap!(axQ, λc, φc, Q, colorrange=(-Qlim, Qlim), colormap=:balance, nan_color=:gray) -heatmap!(axx, λf, φc, τˣ) -heatmap!(axy, λc, φf, τʸ) +Colorbar(fig[1, 2], hmx, label="Eastward momentum flux (N m⁻²)") +Colorbar(fig[2, 2], hmy, label="Northward momentum flux (N m⁻²)") +Colorbar(fig[3, 2], hmQ, label="Heat flux (W m⁻²)") display(fig) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index a52eaf55..3beb3f2c 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -34,6 +34,9 @@ using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries const SomeKindOfFieldTimeSeries = Union{FieldTimeSeries, GPUAdaptedFieldTimeSeries} +function surface_velocities end +function surface_tracers end + ##### ##### Some implementation ##### diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 0eec5297..73d08e48 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -2,8 +2,10 @@ module PrescribedAtmospheres import ..OceanSeaIceModels: surface_velocities -struct PrescribedAtmosphere{U, T} +struct PrescribedAtmosphere{U, F, T} velocities :: U + freshwater_fluxes :: F + tracers :: F times :: T end diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index 60b159e3..4a86b04d 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -1,74 +1,120 @@ +using Oceananigans.Grids: inactive_node + +##### +##### Utilities +##### + +# surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) = _surface_velocities(ocean) + +function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + u = interior(ocean.model.velocities.u, :, :, Nz) + v = interior(ocean.model.velocities.v, :, :, Nz) + w = interior(ocean.model.velocities.w, :, :, Nz+1) + return (; u, v, w) +end + +function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + tracers = ocean.model.tracers + tracer_names = keys(tracers) + sfc_tracers = NamedTuple(name => interior(tracers[name], :, :, Nz) + for name in tracer_names) + return sfc_tracers +end + +##### +##### Computation +##### + +const c = Center() +const f = Face() + function compute_atmosphere_ocean_fluxes!(coupled_model) ocean = coupled_model.ocean atmosphere = coupled_model.atmosphere - tracers = ocean.model.tracers - tracer_fluxes = NamedTuple(name => surface_flux(tracers[name]) for name in keys(tracers)) - + # Basic model properties grid = ocean.model.grid arch = architecture(grid) clock = ocean.model.clock + + # Ocean, atmosphere, and sea ice state ocean_velocities = surface_velocities(ocean) - ocean_reference_density = coupled_model.ocean_reference_density + ocean_tracers = surface_tracers(ocean) + atmosphere_velocities = surface_velocities(atmosphere) + atmosphere_tracers = nothing + ice_thickness = coupled_model.sea_ice.model.ice_thickness - momentum_flux_fields = coupled_model.fluxes.surfaces.ocean.momentum - tracer_flux_fields = coupled_model.fluxes.surfaces.ocean.tracers + # Fluxes, and flux contributors + net_momentum_fluxes = coupled_model.fluxes.surfaces.ocean.momentum + net_tracer_fluxes = coupled_model.fluxes.surfaces.ocean.tracers + radiation = coupled_model.fluxes.radiation momentum_flux_contributions = coupled_model.fluxes.atmosphere_ocean.momentum - heat_flux_contributions = coupled_model.fluxes.atmosphere_ocean.heat - tracer_flux_contributions = coupled_model.fluxes.atmosphere_ocean.heat + heat_flux_contributions = coupled_model.fluxes.atmosphere_ocean.heat + tracer_flux_contributions = coupled_model.fluxes.atmosphere_ocean.heat + # Parameters? atmosphere_ocean_parameters = ( ρₐ = 1.2, - ρₒ = 1024,, + ρₒ = coupled_model.ocean_reference_density, cₚ = 3991.0, ) launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, grid, clock, - momentum_flux_fields, - tracer_flux_fields, + net_momentum_fluxes, + net_tracer_fluxes, momentum_flux_contributions, - heat_flux_contributions + heat_flux_contributions, + tracer_flux_contributions, ocean_velocities, atmosphere_velocities, + ocean_tracers, + atmosphere_tracers, + radiation, atmosphere_ocean_parameters, ice_thickness) return nothing end -@inline function air_sea_difference(i, j, grid, time, ::RelativeAtmosphereOceanVelocity, +@inline function air_sea_difference(i, j, grid, time, ::RelativeVelocityScale, air::SomeKindOfFieldTimeSeries, sea::AbstractArray) δ = @inbounds air[i, j, 1, time] - sea[i, j, 1] - #@show air[i, j, 1, time] time δ return δ end @kernel function _compute_atmosphere_ocean_fluxes!(grid, clock, - momentum_flux_fields, - tracer_flux_fields, + net_momentum_fluxes, + net_tracer_fluxes, momentum_flux_contributions, heat_flux_contributions, tracer_flux_contributions, ocean_velocities, atmosphere_velocities, + ocean_tracers, + atmosphere_tracers, radiation, atmosphere_ocean_parameters, ice_thickness) i, j = @index(Global, NTuple) - - τˣ = momentum_flux_fields.u - τʸ = momentum_flux_fields.v - # Q = tracer_fluxes.T - # F = tracer_fluxes.S + kᴺ = size(grid, 3) # index of the top ocean cell time = Time(clock.time) + τˣ = net_momentum_fluxes.u + τʸ = net_momentum_fluxes.v + Jᵀ = net_tracer_fluxes.T + Jˢ = net_tracer_fluxes.S + Uₒ = ocean_velocities Uₐ = atmosphere_velocities uₐ = Uₐ.u @@ -76,38 +122,80 @@ end uₒ = Uₒ.u vₒ = Uₒ.v + Tₒ = ocean_tracers.T + ρₐ = atmosphere_ocean_parameters.ρₐ ρₒ = atmosphere_ocean_parameters.ρₒ cₚ = atmosphere_ocean_parameters.cₚ - time = Time(clock.time) - - u_formula = momentum_flux_contributions.u.transfer_velocity - v_formula = momentum_flux_contributions.v.transfer_velocity + u_formula = momentum_flux_contributions.u.velocity_scale + v_formula = momentum_flux_contributions.v.velocity_scale cᴰ = momentum_flux_contributions.u.transfer_coefficient # Compute transfer velocity scale - Vᶠᶜᶜ = transfer_velocityᶠᶜᶜ(i, j, grid, time, u_formula, Uₐ, Uₒ) - Vᶜᶠᶜ = transfer_velocityᶜᶠᶜ(i, j, grid, time, v_formula, Uₐ, Uₒ) + Vᶠᶜᶜ = bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, u_formula, Uₐ, Uₒ) + Vᶜᶠᶜ = bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, v_formula, Uₐ, Uₒ) Δu = air_sea_difference(i, j, grid, time, u_formula, uₐ, uₒ) Δv = air_sea_difference(i, j, grid, time, v_formula, vₐ, vₒ) @inbounds begin - τˣ[i, j, 1] = - ρₐ / ρₒ * cᴰ * Δu * Vᶠᶜᶜ - τʸ[i, j, 1] = - ρₐ / ρₒ * cᴰ * Δv * Vᶜᶠᶜ + atmos_ocean_τˣ = - ρₐ / ρₒ * cᴰ * Δu * Vᶠᶜᶜ + atmos_ocean_τʸ = - ρₐ / ρₒ * cᴰ * Δv * Vᶜᶠᶜ - # @show τˣ[i, j, 1] - # @show τʸ[i, j, 1] + # TODO: should this be peripheral_node? + τˣ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, f, c, c), zero(grid), atmos_ocean_τˣ) + τʸ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, f, c), zero(grid), atmos_ocean_τʸ) - Q[i, j, 1] = radiative_fluxes(i, j, grid, time, radiation) + # Radiation first + Q = downwelling_radiation(i, j, grid, time, radiation) + Q += upwelling_radiation(i, j, grid, time, radiation, Tₒ) + + # Then the rest of the heat fluxes + atmos_ocean_Jᵀ = Q / (ρₒ * cₚ) + Jᵀ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jᵀ) end end -@inline function radiative_fluxes(i, j, grid, time, radiation) +@inline Δϕt²(i, j, k, grid, ϕ1t, ϕ2, time) = @inbounds (ϕ1t[i, j, k, time] - ϕ2[i, j, k])^2 + +@inline function downwelling_radiation(i, j, grid, time, radiation) Qˢʷ = radiation.downwelling_shortwave_radiation Qˡʷ = radiation.downwelling_longwave_radiation α = radiation.ocean_albedo - return @inbounds (1 - α) * Qˢʷ[i, j, 1, time] + Qˡʷ[i, j, 1, time] + return @inbounds - (1 - α) * Qˢʷ[i, j, 1, time] - Qˡʷ[i, j, 1, time] +end + +@inline function upwelling_radiation(i, j, grid, time, radiation, Tₒ) + σ = radiation.stefan_boltzmann_constant + ϵ = radiation.ocean_emissivity + Tᵣ = radiation.reference_temperature + + # Note: positive implies _upward_ heat flux, and therefore cooling. + return @inbounds σ * ϵ * (Tₒ[i, j, 1] + Tᵣ)^4 +end + +@inline function bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) + uₐ = Uₐ.u + vₐ = Uₐ.v + uₒ = Uₒ.u + vₒ = Uₒ.v + + Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] + Δv² = ℑyᵃᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) + + return sqrt(Δu^2 + Δv²) +end + +@inline function bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) + uₐ = Uₐ.u + vₐ = Uₐ.v + uₒ = Uₒ.u + vₒ = Uₒ.v + + Δu² = ℑxᶜᵃᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) + Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] + + return sqrt(Δu² + Δv^2) end diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl index 2e4a7df1..7568d8c3 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl @@ -5,15 +5,6 @@ using ClimaSeaIce.SlabSeaIceModels: SlabSeaIceModel ##### Utilities ##### -function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) - grid = ocean.model.grid - Nz = size(grid, 3) - u = interior(ocean.model.velocities.u, :, :, Nz) - v = interior(ocean.model.velocities.v, :, :, Nz) - w = interior(ocean.model.velocities.w, :, :, Nz+1) - return (; u, v, w) -end - function surface_flux(f::Field) top_bc = f.boundary_conditions.top if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} @@ -108,7 +99,7 @@ struct OceanSeaIceModelFluxes{S, R, AO, AI, IO} sea_ice_ocean :: IO end -function OceanSeaIceModelFluxes(ocean, sea_ice=nothing; +function OceanSeaIceModelFluxes(ocean, sea_ice=nothing, atmosphere=nothing; radiation = nothing, atmosphere_ocean = nothing, atmosphere_sea_ice = nothing, @@ -134,49 +125,23 @@ end Base.summary(crf::OceanSeaIceModelFluxes) = "OceanSeaIceModelFluxes" Base.show(io::IO, crf::OceanSeaIceModelFluxes) = print(io, summary(crf)) -##### -##### CrossRealmFlux -##### - -struct RelativeAtmosphereOceanVelocity end -struct AtmosphereVelocity end - ##### ##### Bulk formula ##### +struct RelativeVelocityScale end +struct AtmosphereOnlyVelocityVelocityScale end + struct BulkFormula{T, CD} - transfer_velocity :: T + velocity_scale :: T transfer_coefficient :: CD end function BulkFormula(FT=Float64; - transfer_velocity = RelativeAtmosphereOceanVelocity(), + velocity_scale = RelativeVelocityScale(), transfer_coefficient = 1e-3) - return BulkFormula(transfer_velocity, + return BulkFormula(velocity_scale, convert(FT, transfer_coefficient)) end -@inline Δϕt²(i, j, k, grid, ϕ1t, ϕ2, time) = @inbounds (ϕ1t[i, j, k, time] - ϕ2[i, j, k])^2 - -@inline function transfer_velocityᶠᶜᶜ(i, j, grid, time, ::RelativeAtmosphereOceanVelocity, Uₐ, Uₒ) - uₐ = Uₐ.u - vₐ = Uₐ.v - uₒ = Uₒ.u - vₒ = Uₒ.v - - Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] - Δv² = ℑyᵃᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) - return sqrt(Δu^2 + Δv²) -end - -@inline function transfer_velocityᶜᶠᶜ(i, j, grid, time, ::RelativeAtmosphereOceanVelocity, Uₐ, Uₒ) - uₐ = Uₐ.u - vₐ = Uₐ.v - uₒ = Uₒ.u - vₒ = Uₒ.v - Δu² = ℑxᶜᵃᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) - Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] - return sqrt(Δu² + Δv^2) -end From bd517595832564a8651ceec67b4d27fad8fa0078 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 30 Nov 2023 13:42:18 -0700 Subject: [PATCH 044/182] Add radiative fluxes --- .../omip_atmosphere_and_radiation.jl | 30 +-- .../omip_simulation.jl | 7 +- src/OceanSeaIceModels/OceanSeaIceModels.jl | 9 +- .../PrescribedAtmospheres.jl | 50 ++++- .../atmosphere_sea_ice_fluxes.jl | 5 + .../compute_atmosphere_ocean_fluxes.jl | 116 +++++----- src/OceanSeaIceModels/getflux.jl | 14 -- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 23 +- .../ocean_sea_ice_model_fluxes.jl | 199 +++++++++++------- .../ocean_sea_ice_surfaces.jl | 55 +++++ src/OceanSeaIceModels/radiation.jl | 46 ---- src/OceanSeaIceModels/surface_radiation.jl | 37 ++++ 12 files changed, 357 insertions(+), 234 deletions(-) create mode 100644 src/OceanSeaIceModels/ocean_sea_ice_surfaces.jl delete mode 100644 src/OceanSeaIceModels/radiation.jl create mode 100644 src/OceanSeaIceModels/surface_radiation.jl diff --git a/experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl b/experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl index 3f5f0515..77d431cd 100644 --- a/experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl +++ b/experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl @@ -15,6 +15,9 @@ Fs_jra55_native = jra55_field_time_series(:freshwater_snow_flux; time_indices, #Fv_jra55_native = jra55_field_time_series(:freshwater_river_flux; time_indices, architecture=arch) #Fi_jra55_native = jra55_field_time_series(:freshwater_iceberg_flux; time_indices, architecture=arch) +Qlw_jra55_native = jra55_field_time_series(:downwelling_longwave_radiation; time_indices, architecture=arch) +Qsw_jra55_native = jra55_field_time_series(:downwelling_shortwave_radiation; time_indices, architecture=arch) + times = u_jra55_native.times u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing)) @@ -28,6 +31,8 @@ T_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_condit q_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) Fr_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) Fs_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Qlw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Qsw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) interpolate!(u_jra55, u_jra55_native) interpolate!(v_jra55, v_jra55_native) @@ -35,6 +40,8 @@ interpolate!(T_jra55, T_jra55_native) interpolate!(q_jra55, q_jra55_native) interpolate!(Fr_jra55, Fr_jra55_native) interpolate!(Fs_jra55, Fs_jra55_native) +interpolate!(Qlw_jra55, Qlw_jra55_native) +interpolate!(Qsw_jra55, Qsw_jra55_native) velocities = (u = u_jra55, v = v_jra55) @@ -42,24 +49,9 @@ velocities = (u = u_jra55, tracers = (T = T_jra55, q = q_jra55) -freshwater_fluxes = (rain = Fr_jra55, - snow = Fs_jra55) - -atmosphere = PrescribedAtmosphere(velocities, freshwater_fluxes, tracers, times) - -##### -##### Radiation -##### - -Qlw_jra55_native = jra55_field_time_series(:downwelling_longwave_radiation; time_indices, architecture=arch) -Qsw_jra55_native = jra55_field_time_series(:downwelling_shortwave_radiation; time_indices, architecture=arch) - -Qlw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Qsw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) - -interpolate!(Qlw_jra55, Qlw_jra55_native) -interpolate!(Qsw_jra55, Qsw_jra55_native) +freshwater_flux = (rain = Fr_jra55, + snow = Fs_jra55) -radiation = Radiation(downwelling_shortwave_radiation = Qsw_jra55, - downwelling_longwave_radiation = Qlw_jra55) +downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qsw_jra55) +atmosphere = PrescribedAtmosphere(times; velocities, freshwater_flux, tracers, downwelling_radiation) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 4b77e5cd..65c4fab9 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -1,4 +1,3 @@ -#= using Oceananigans using Oceananigans.Units using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity @@ -7,8 +6,9 @@ using Oceananigans.Fields: ConstantField, ZeroField, interpolate! using ClimaOcean using ClimaOcean.OceanSeaIceModels: adjust_ice_covered_ocean_temperature!, + TwoStreamDownwellingRadiation, PrescribedAtmosphere, - Radiation + SurfaceRadiation using ClimaOcean.JRA55: jra55_field_time_series @@ -120,7 +120,7 @@ include("omip_sea_ice_component.jl") # also defines `radiation`, a `ClimaOcean.OceanSeaIceModels.Radiation` include("omip_atmosphere_and_radiation.jl") -coupled_model = OceanSeaIceModel(ocean, ice, atmosphere; radiation) +coupled_model = OceanSeaIceModel(ocean, ice, atmosphere; surface_radiation) coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) #stop_time=30days) adjust_ice_covered_ocean_temperature!(coupled_model) @@ -160,7 +160,6 @@ coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outp overwrite_existing = true) run!(coupled_simulation) -=# # using ClimaOcean.OceanSeaIceModels: compute_atmosphere_ocean_fluxes! # compute_atmosphere_ocean_fluxes!(coupled_model) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 3beb3f2c..640ad4bb 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -34,15 +34,20 @@ using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries const SomeKindOfFieldTimeSeries = Union{FieldTimeSeries, GPUAdaptedFieldTimeSeries} +const SKOFTS = SomeKindOfFieldTimeSeries + function surface_velocities end function surface_tracers end +function sea_ice_thickness end + ##### ##### Some implementation ##### include("ocean_sea_ice_model_fluxes.jl") -include("radiation.jl") +include("ocean_sea_ice_surfaces.jl") +include("surface_radiation.jl") include("atmosphere_sea_ice_fluxes.jl") include("atmosphere_ocean_momentum_flux.jl") include("compute_atmosphere_ocean_fluxes.jl") @@ -56,7 +61,7 @@ compute_atmosphere_ocean_fluxes!(coupled_model::NoAtmosphereModel) = nothing include("PrescribedAtmospheres.jl") -using .PrescribedAtmospheres: PrescribedAtmosphere +using .PrescribedAtmospheres: PrescribedAtmosphere, TwoStreamDownwellingRadiation # Or "AtmosphereModels" # include("Atmospheres.jl") diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 73d08e48..433a6d31 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -1,14 +1,56 @@ module PrescribedAtmospheres -import ..OceanSeaIceModels: surface_velocities +import ..OceanSeaIceModels: surface_velocities, surface_tracers -struct PrescribedAtmosphere{U, F, T} +struct PrescribedAtmosphere{U, F, R, C, T} velocities :: U - freshwater_fluxes :: F - tracers :: F + freshwater_flux :: F + downwelling_radiation :: R + tracers :: C times :: T end +""" + PrescribedAtmosphere(times; + velocities = nothing, + freshwater_flux = nothing, + downwelling_radiation = nothing, + tracers = nothing) + +Return a representation of a prescribed time-evolving atmospheric +state with data given at `times`. +""" +function PrescribedAtmosphere(times; + velocities = nothing, + freshwater_flux = nothing, + downwelling_radiation = nothing, + tracers = nothing) + + return PrescribedAtmosphere(velocities, + freshwater_flux, + downwelling_radiation, + tracers, + times) +end + surface_velocities(pa::PrescribedAtmosphere) = pa.velocities +surface_tracers(pa::PrescribedAtmosphere) = pa.tracers +freshwater_fluxes(pa::PrescribedAtmosphere) = pa.freshwater_fluxes +struct TwoStreamDownwellingRadiation{SW, LW} + shortwave :: SW + longwave :: LW +end + +""" + TwoStreamDownwellingRadiation(shortwave=nothing, longwave=nothing) + +Return a two-stream model for downwelling radiation that +passes through he atmosphere and arrives at the surface of ocean +or sea ice. +""" +TwoStreamDownwellingRadiation(; shortwave=nothing, longwave=nothing) = + TwoStreamDownwellingRadiation(shortwave, longwave) + end # module + diff --git a/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl index fdc232e6..444360d5 100644 --- a/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl +++ b/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl @@ -1 +1,6 @@ +using ClimaSeaIce: SlabSeaIceModel + +sea_ice_thickness(sea_ice::Simulation{<:SlabSeaIceModel}) = + sea_ice.model.ice_thickness + # Nothing yet... diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index 4a86b04d..f6964c43 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -4,8 +4,6 @@ using Oceananigans.Grids: inactive_node ##### Utilities ##### -# surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) = _surface_velocities(ocean) - function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) grid = ocean.model.grid Nz = size(grid, 3) @@ -45,26 +43,29 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) ocean_velocities = surface_velocities(ocean) ocean_tracers = surface_tracers(ocean) - atmosphere_velocities = surface_velocities(atmosphere) - atmosphere_tracers = nothing + atmosphere_velocities = surface_velocities(atmosphere) + atmosphere_tracers = surface_tracers(atmosphere) + atmosphere_downwelling_radiation = downwelling_radiation(atmosphere) + atmosphere_freshwater_flux = freshwater_flux(atmosphere) - ice_thickness = coupled_model.sea_ice.model.ice_thickness + ice_thickness = sea_ice_thickness(sea_ice) # Fluxes, and flux contributors - net_momentum_fluxes = coupled_model.fluxes.surfaces.ocean.momentum - net_tracer_fluxes = coupled_model.fluxes.surfaces.ocean.tracers - radiation = coupled_model.fluxes.radiation + net_momentum_fluxes = coupled_model.surfaces.ocean.momentum + net_tracer_fluxes = coupled_model.surfaces.ocean.tracers momentum_flux_contributions = coupled_model.fluxes.atmosphere_ocean.momentum heat_flux_contributions = coupled_model.fluxes.atmosphere_ocean.heat - tracer_flux_contributions = coupled_model.fluxes.atmosphere_ocean.heat + tracer_flux_contributions = coupled_model.fluxes.atmosphere_ocean.tracers # Parameters? atmosphere_ocean_parameters = ( - ρₐ = 1.2, + ρₐ = 1.2, # ? ρₒ = coupled_model.ocean_reference_density, - cₚ = 3991.0, + cₚ = coupled_model.ocean_heat_capacity, ) + surface_radiation = coupled_model.fluxes.surface_radiation + launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, grid, clock, net_momentum_fluxes, @@ -76,20 +77,15 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_velocities, ocean_tracers, atmosphere_tracers, - radiation, + atmosphere_downwelling_radiation, + surface_radiation, + atmosphere_freshwater_flux, atmosphere_ocean_parameters, ice_thickness) return nothing end -@inline function air_sea_difference(i, j, grid, time, ::RelativeVelocityScale, - air::SomeKindOfFieldTimeSeries, sea::AbstractArray) - - δ = @inbounds air[i, j, 1, time] - sea[i, j, 1] - return δ -end - @kernel function _compute_atmosphere_ocean_fluxes!(grid, clock, net_momentum_fluxes, @@ -101,7 +97,9 @@ end atmosphere_velocities, ocean_tracers, atmosphere_tracers, - radiation, + downwelling_radiation, + surface_radiation, + freshwater_flux, atmosphere_ocean_parameters, ice_thickness) @@ -133,69 +131,59 @@ end cᴰ = momentum_flux_contributions.u.transfer_coefficient # Compute transfer velocity scale - Vᶠᶜᶜ = bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, u_formula, Uₐ, Uₒ) - Vᶜᶠᶜ = bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, v_formula, Uₐ, Uₒ) + ΔUᶠᶜᶜ = bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, u_formula, Uₐ, Uₒ) + ΔUᶜᶠᶜ = bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, v_formula, Uₐ, Uₒ) + ΔUᶜᶜᶜ = bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, v_formula, Uₐ, Uₒ) + # Compute momentum fluxes Δu = air_sea_difference(i, j, grid, time, u_formula, uₐ, uₒ) Δv = air_sea_difference(i, j, grid, time, v_formula, vₐ, vₒ) - @inbounds begin - atmos_ocean_τˣ = - ρₐ / ρₒ * cᴰ * Δu * Vᶠᶜᶜ - atmos_ocean_τʸ = - ρₐ / ρₒ * cᴰ * Δv * Vᶜᶠᶜ + atmos_ocean_τˣ = - ρₐ / ρₒ * cᴰ * Δu * ΔUᶠᶜᶜ + atmos_ocean_τʸ = - ρₐ / ρₒ * cᴰ * Δv * ΔUᶜᶠᶜ + + # Compute heat fluxes + # Radiation first + Q = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, surface_radiation) + Q += net_upwelling_radiation(i, j, grid, time, surface_radiation, Tₒ) + + # Then the rest of the heat fluxes + atmos_ocean_Jᵀ = Q / (ρₒ * cₚ) + # Compute salinity fluxes + F = tracer_flux(i, j, grid, time, freshwater_flux) + atmos_ocean_Jˢ = F + + @inbounds begin + # Set fluxes # TODO: should this be peripheral_node? τˣ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, f, c, c), zero(grid), atmos_ocean_τˣ) τʸ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, f, c), zero(grid), atmos_ocean_τʸ) - - # Radiation first - Q = downwelling_radiation(i, j, grid, time, radiation) - Q += upwelling_radiation(i, j, grid, time, radiation, Tₒ) - - # Then the rest of the heat fluxes - atmos_ocean_Jᵀ = Q / (ρₒ * cₚ) Jᵀ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jᵀ) + Jˢ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jˢ) end end @inline Δϕt²(i, j, k, grid, ϕ1t, ϕ2, time) = @inbounds (ϕ1t[i, j, k, time] - ϕ2[i, j, k])^2 -@inline function downwelling_radiation(i, j, grid, time, radiation) - Qˢʷ = radiation.downwelling_shortwave_radiation - Qˡʷ = radiation.downwelling_longwave_radiation - α = radiation.ocean_albedo - return @inbounds - (1 - α) * Qˢʷ[i, j, 1, time] - Qˡʷ[i, j, 1, time] -end +@inline function net_downwelling_radiation(i, j, grid, time, downwelling_radiation, surface_radiation) + Qˢʷ = downwelling_radiation.shortwave + Qˡʷ = downwelling_radiation.longwave -@inline function upwelling_radiation(i, j, grid, time, radiation, Tₒ) - σ = radiation.stefan_boltzmann_constant - ϵ = radiation.ocean_emissivity - Tᵣ = radiation.reference_temperature + # Assumes albedo is a constant + α = surface_radiation.reflection.ocean - # Note: positive implies _upward_ heat flux, and therefore cooling. - return @inbounds σ * ϵ * (Tₒ[i, j, 1] + Tᵣ)^4 -end - -@inline function bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) - uₐ = Uₐ.u - vₐ = Uₐ.v - uₒ = Uₒ.u - vₒ = Uₒ.v - - Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] - Δv² = ℑyᵃᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) - - return sqrt(Δu^2 + Δv²) + return @inbounds - (1 - α) * Qˢʷ[i, j, 1, time] - Qˡʷ[i, j, 1, time] end -@inline function bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) - uₐ = Uₐ.u - vₐ = Uₐ.v - uₒ = Uₒ.u - vₒ = Uₒ.v +@inline function upwelling_radiation(i, j, grid, time, surface_radiation, Tₒ) + σ = surface_radiation.stefan_boltzmann_constant + Tᵣ = surface_radiation.reference_temperature - Δu² = ℑxᶜᵃᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) - Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] + # Assumes emissivity is a constant + ϵ = surface_radiation.emission.ocean - return sqrt(Δu² + Δv^2) + # Note: positive implies _upward_ heat flux, and therefore cooling. + return @inbounds σ * ϵ * (Tₒ[i, j, 1] + Tᵣ)^4 end diff --git a/src/OceanSeaIceModels/getflux.jl b/src/OceanSeaIceModels/getflux.jl index cc4f0ccc..e69de29b 100644 --- a/src/OceanSeaIceModels/getflux.jl +++ b/src/OceanSeaIceModels/getflux.jl @@ -1,14 +0,0 @@ -@inline getflux(f::Nothing, i::Int, j::Int, grid::AbstractGrid, clock, fields) = nothing -@inline getflux(f::Number, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f -@inline getflux(f::Function, i::Int, j::Int, grid::AbstractGrid, clock, fields) = f(i, j, grid, clock, fields) -@inline getflux(f::AbstractArray{<:Any, 2}, i::Int, j::Int, grid::AbstractGrid, args...) = @inbounds f[i, j] -@inline getflux(f::AbstractField, i::Int, j::Int, grid::AbstractGrid, args...) = @inbounds f[i, j, 1] -@inline getflux(f::FieldTimeSeries, i::Int, j::Int, grid::AbstractGrid, clock, args...) = @inbounds f[i, j, Time(clock.time)] - -# If we have ice, do not compute fluxes! -@inline function getflux(ice_thickness, f, i::Int, j::Int, grid::AbstractGrid, args...) - h = @inbounds ice_thickness[i, j, 1] - return ifelse(h > 0, getflux(f, i, j, grid,args...), 0) -end - - diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 6b7dd091..5cb1c7aa 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -2,12 +2,13 @@ using Oceananigans.Models: update_model_field_time_series! using Oceananigans.TimeSteppers: Clock using Oceananigans -struct OceanSeaIceModel{FT, I, A, O, F, PI, PC, C, G} <: AbstractModel{Nothing} +struct OceanSeaIceModel{FT, I, A, O, S, F, PI, PC, C, G} <: AbstractModel{Nothing} clock :: C - grid :: G # TODO: make it so simulation does not require this + grid :: G # TODO: make it so Oceananigans.Ssimulation does not require this atmosphere :: A sea_ice :: I ocean :: O + surfaces :: S fluxes :: F previous_ice_thickness :: PI previous_ice_concentration :: PC @@ -29,12 +30,12 @@ prognostic_fields(cm::OSIM) = nothing fields(::OSIM) = NamedTuple() default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) -function OceanSeaIceModel(ocean, ice=nothing, atmosphere=nothing; - radiation = nothing, +function OceanSeaIceModel(ocean, sea_ice=nothing, atmosphere=nothing; + surface_radiation = nothing, clock = default_clock(eltype(ocean.model))) - previous_ice_thickness = deepcopy(ice.model.ice_thickness) - previous_ice_concentration = deepcopy(ice.model.ice_concentration) + previous_ice_thickness = deepcopy(sea_ice.model.ice_thickness) + previous_ice_concentration = deepcopy(sea_ice.model.ice_concentration) grid = ocean.model.grid ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) @@ -42,9 +43,14 @@ function OceanSeaIceModel(ocean, ice=nothing, atmosphere=nothing; ocean_reference_density = 1024 ocean_heat_capacity = 3991 - # reference_temperature = 273.15 # for radiation? - fluxes = OceanSeaIceModelFluxes(ocean, ice; radiation) + # Contains information about flux contributions: bulk formula, prescribed + # fluxes, etc. + fluxes = OceanSeaIceModelFluxes(eltype(grid); surface_radiation) + + # Contains a reference to the Fields holding net surface fluxes: + # ocean top surface, and both top and bottom sea ice surfaces + surfaces = OceanSeaIceSurfaces(ocean, sea_ice) FT = eltype(ocean.model.grid) @@ -53,6 +59,7 @@ function OceanSeaIceModel(ocean, ice=nothing, atmosphere=nothing; atmosphere, ice, ocean, + surfaces, fluxes, previous_ice_thickness, previous_ice_concentration, diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl index 7568d8c3..bc8b2d47 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl @@ -34,114 +34,167 @@ Base.summary(osf::CrossRealmFluxes) = "CrossRealmFluxes" Base.show(io::IO, osf::CrossRealmFluxes) = print(io, summary(osf)) ##### -##### Extractors for differnet models (maybe this belongs in the model repo's) +##### Container for organizing information related to fluxes ##### -function extract_top_surface_fluxes(model::HydrostaticFreeSurfaceModel) - u_flux = surface_flux(model.velocities.u) - v_flux = surface_flux(model.velocities.v) +struct RelativeVelocityScale end +struct AtmosphereOnlyVelocityScale end - ocean_momentum_fluxes = (u = u_flux, v = v_flux) +struct OceanSeaIceModelFluxes{U, R, AO, ASI, SIO} + bulk_velocity_scale :: U + surface_radiation :: R + atmosphere_ocean :: AO + atmosphere_sea_ice :: ASI + sea_ice_ocean :: SIO +end + +function OceanSeaIceModelFluxes(FT=Float64; + bulk_velocity_scale = RelativeVelocityScale(), + surface_radiation = nothing, + atmosphere_ocean = nothing, + atmosphere_sea_ice = nothing, + sea_ice_ocean = nothing) - ocean_tracers = model.tracers + if isnothing(atmosphere_ocean) # defaults + τˣ = BulkFormula(RelativeVelocity(), 1e-3) + τʸ = BulkFormula(RelativeVelocity(), 1e-3) + momentum_flux_formulae = (u=τˣ, v=τʸ) - ocean_tracer_fluxes = NamedTuple(name => surface_flux(ocean_tracers[name]) - for name in keys(ocean_tracers) - if surface_flux(ocean_tracers[name]) isa AbstractArray) + evaporation = BulkFormula(SpecificHumidity, 1e-3) + - ocean_fluxes = CrossRealmFluxes(momentum = ocean_momentum_fluxes, - tracers = ocean_tracer_fluxes) + atmosphere_ocean = CrossRealmFluxes(momentum = momentum_flux_formulae) + end - return ocean_fluxes + return OceanSeaIceModelFluxes(bulk_velocity_scale, + surface_radiation, + atmosphere_ocean, + atmosphere_sea_ice, + sea_ice_ocean) end -extract_top_surface_fluxes(model::SlabSeaIceModel) = nothing -extract_bottom_surface_fluxes(model::SlabSeaIceModel) = nothing +Base.summary(crf::OceanSeaIceModelFluxes) = "OceanSeaIceModelFluxes" +Base.show(io::IO, crf::OceanSeaIceModelFluxes) = print(io, summary(crf)) ##### -##### Total flux across each surface +##### Bulk formula ##### -struct OceanSeaIceSurfaces{O, IT, IB} - ocean :: O - sea_ice_top :: IT - sea_ice_bottom :: IB -end +""" + BulkFormula(air_sea_difference, transfer_coefficient) -Base.summary(osis::OceanSeaIceSurfaces) = "OceanSeaIceSurfaces" -Base.show(io::IO, osis::OceanSeaIceSurfaces) = print(io, summary(osis)) +The basic structure of a flux `J` computed by a bulk formula is: -function OceanSeaIceSurfaces(ocean, sea_ice=nothing) - ocean_fluxes = extract_top_surface_fluxes(ocean.model) - - if isnothing(sea_ice) - sea_ice_top_fluxes = nothing - sea_ice_bottom_fluxes = nothing - else - sea_ice_top_fluxes = extract_top_surface_fluxes(sea_ice.model) - sea_ice_bottom_fluxes = extract_bottom_surface_fluxes(sea_ice.model) - end +```math +J = ρₐ * C * Δc * ΔU +``` - return OceanSeaIceSurfaces(ocean_fluxes, - sea_ice_top_fluxes, - sea_ice_bottom_fluxes) +where `ρₐ` is the density of air, `C` is the `transfer_coefficient`, +`Δc` is the air_sea_difference, and `ΔU` is the bulk velocity scale. +""" +struct BulkFormula{F, CD} + air_sea_difference :: F + transfer_coefficient :: CD +end + +@inline function tracer_flux(i, j, grid, time, formula::BulkFormula, ΔU, atmosphere_state, ocean_state) + ρₐ = atmosphere_state.density + C = formula.transfer_coefficient + Δc = air_sea_difference(i, j, grid, time, formula.air_sea_difference, atmosphere_state, ocean_state) + return ρₐ * C * Δc * ΔU end +@inline tracer_flux(i, j, grid, time, flux::NamedTuple, args...) = + tracer_flux(i, j, grid, time, values(flux)) + +@inline tracer_flux(i, j, grid, time, flux::Tuple{<:Any, <:Any}, args...) = + tracer_flux(i, j, grid, time, flux[1], args...) + + tracer_flux(i, j, grid, time, flux[2], args...) + +@inline tracer_flux(i, j, grid, time, fts::SKOFTS, args...) = + @inbounds fts[i, j, 1, time] + ##### -##### Container for organizing information related to fluxes +##### Air-sea differences ##### -struct OceanSeaIceModelFluxes{S, R, AO, AI, IO} - surfaces :: S - radiation :: R - atmosphere_ocean :: AO - atmosphere_sea_ice :: AI - sea_ice_ocean :: IO +struct RelativeVelocity end + +struct MassSpecificHumidity{S} + saturation :: S end -function OceanSeaIceModelFluxes(ocean, sea_ice=nothing, atmosphere=nothing; - radiation = nothing, - atmosphere_ocean = nothing, - atmosphere_sea_ice = nothing, - sea_ice_ocean = nothing) +struct LargeYeagerSaturation{FT} + c1 :: FT + c2 :: FT + reference_temperature:: FT +end - surfaces = OceanSeaIceSurfaces(ocean, sea_ice) +function LargeYeagerSaturation(FT=Float64; + c1 = 0.98 * 640380, + c2 = -5107.4, + reference_temperature = 273.15) + return LargeYeagerSaturation(convert(FT, c1), + convert(FT, c2), + convert(FT, reference_temperature)) +end - if isnothing(atmosphere_ocean) # defaults - FT = eltype(ocean.model.grid) - τˣ = BulkFormula(FT, transfer_coefficient=1e-3) - τʸ = BulkFormula(FT, transfer_coefficient=1e-3) - momentum_flux_formulae = (u=τˣ, v=τʸ) - atmosphere_ocean = CrossRealmFluxes(momentum = momentum_flux_formulae) - end +#= +MassSpecificHumidity(FT=Float64; saturation = LargeYeagerSaturation(FT)) = + MassSpecificHumidity(saturation) + +struct InternalEnergy{C} + atmosphere_specific_heat :: C +end - return OceanSeaIceModelFluxes(surfaces, - radiation, - atmosphere_ocean, - atmosphere_sea_ice, - sea_ice_ocean) +InternalEnergy(FT::DataType; atmosphere_specific_heat=1000.5) = + InternalEnergy(convert(FT, atmosphere_specific_heat)) +=# + +@inline function air_sea_difference(i, j, grid, time, ::MassSpecificHumidity, atmos, ocean) + return air_sea_difference(i, j, grid, time, atmos, ocean) end -Base.summary(crf::OceanSeaIceModelFluxes) = "OceanSeaIceModelFluxes" -Base.show(io::IO, crf::OceanSeaIceModelFluxes) = print(io, summary(crf)) +@inline air_sea_difference(i, j, grid, time, air::SKOFTS, sea::AbstractArray) = + @inbounds air[i, j, 1, time] - sea[i, j, 1] ##### -##### Bulk formula +##### Bulk velocity scales ##### -struct RelativeVelocityScale end -struct AtmosphereOnlyVelocityVelocityScale end +@inline function bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) + uₐ = Uₐ.u + vₐ = Uₐ.v + uₒ = Uₒ.u + vₒ = Uₒ.v -struct BulkFormula{T, CD} - velocity_scale :: T - transfer_coefficient :: CD + Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] + Δv² = ℑxyᶠᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) + + return sqrt(Δu^2 + Δv²) +end + +@inline function bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) + uₐ = Uₐ.u + vₐ = Uₐ.v + uₒ = Uₒ.u + vₒ = Uₒ.v + + Δu² = ℑxyᶜᶠᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) + Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] + + return sqrt(Δu² + Δv^2) end -function BulkFormula(FT=Float64; - velocity_scale = RelativeVelocityScale(), - transfer_coefficient = 1e-3) +@inline function bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) + uₐ = Uₐ.u + vₐ = Uₐ.v + uₒ = Uₒ.u + vₒ = Uₒ.v + + Δu² = ℑxᶜᵃᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) + Δv² = ℑyᵃᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) - return BulkFormula(velocity_scale, - convert(FT, transfer_coefficient)) + return sqrt(Δu² + Δv²) end diff --git a/src/OceanSeaIceModels/ocean_sea_ice_surfaces.jl b/src/OceanSeaIceModels/ocean_sea_ice_surfaces.jl new file mode 100644 index 00000000..745614ea --- /dev/null +++ b/src/OceanSeaIceModels/ocean_sea_ice_surfaces.jl @@ -0,0 +1,55 @@ +##### +##### Extractors for differnet models (maybe this belongs in the model repo's) +##### + +function extract_top_surface_fluxes(model::HydrostaticFreeSurfaceModel) + u_flux = surface_flux(model.velocities.u) + v_flux = surface_flux(model.velocities.v) + + ocean_momentum_fluxes = (u = u_flux, v = v_flux) + + ocean_tracers = model.tracers + + ocean_tracer_fluxes = NamedTuple(name => surface_flux(ocean_tracers[name]) + for name in keys(ocean_tracers) + if surface_flux(ocean_tracers[name]) isa AbstractArray) + + ocean_fluxes = CrossRealmFluxes(momentum = ocean_momentum_fluxes, + tracers = ocean_tracer_fluxes) + + return ocean_fluxes +end + +extract_top_surface_fluxes(model::SlabSeaIceModel) = nothing +extract_bottom_surface_fluxes(model::SlabSeaIceModel) = nothing + +##### +##### Total flux across each surface +##### + +struct OceanSeaIceSurfaces{O, IT, IB} + ocean :: O + sea_ice_top :: IT + sea_ice_bottom :: IB +end + +Base.summary(osis::OceanSeaIceSurfaces) = "OceanSeaIceSurfaces" +Base.show(io::IO, osis::OceanSeaIceSurfaces) = print(io, summary(osis)) + +function OceanSeaIceSurfaces(ocean, sea_ice=nothing) + ocean_fluxes = extract_top_surface_fluxes(ocean.model) + + if isnothing(sea_ice) + sea_ice_top_fluxes = nothing + sea_ice_bottom_fluxes = nothing + else + sea_ice_top_fluxes = extract_top_surface_fluxes(sea_ice.model) + sea_ice_bottom_fluxes = extract_bottom_surface_fluxes(sea_ice.model) + end + + return OceanSeaIceSurfaces(ocean_fluxes, + sea_ice_top_fluxes, + sea_ice_bottom_fluxes) +end + + diff --git a/src/OceanSeaIceModels/radiation.jl b/src/OceanSeaIceModels/radiation.jl deleted file mode 100644 index 55e0fdfb..00000000 --- a/src/OceanSeaIceModels/radiation.jl +++ /dev/null @@ -1,46 +0,0 @@ -struct Radiation{FT, SW, LW, OE, IE, OA, IA} - downwelling_shortwave_radiation :: SW - downwelling_longwave_radiation :: LW - ocean_emissivity :: OE - ice_emissivity :: IE - ocean_albedo :: OA - ice_albedo :: IA - stefan_boltzmann_constant :: FT - reference_temperature :: FT -end - -function Radiation(FT=Float64; - downwelling_shortwave_radiation = nothing, - downwelling_longwave_radiation = nothing, - ocean_emissivity = 0.97, - ice_emissivity = 1.0, - ocean_albedo = 0.3, - ice_albedo = 0.7, - reference_temperature = 273.15, - stefan_boltzmann_constant = 5.67e-8) - - if downwelling_shortwave_radiation isa AbstractArray - # Replace FT with appropriate eltype - FT = eltype(downwelling_shortwave_radiation) - elseif downwelling_longwave_radiation isa AbstractArray - FT = eltype(downwelling_longwave_radiation) - end - - ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) - ice_emissivity isa Number && (ice_emissivity = convert(FT, ice_emissivity)) - ocean_albedo isa Number && (ocean_albedo = convert(FT, ocean_albedo)) - ice_albedo isa Number && (ice_albedo = convert(FT, ice_albedo)) - - return Radiation(downwelling_shortwave_radiation, - downwelling_longwave_radiation, - ocean_emissivity, - ice_emissivity, - ocean_albedo, - ice_albedo, - stefan_boltzmann_constant, - reference_temperature) -end - -Base.summary(r::Radiation) = "Radiation" -Base.show(io::IO, r::Radiation) = print(io, summary(osf)) - diff --git a/src/OceanSeaIceModels/surface_radiation.jl b/src/OceanSeaIceModels/surface_radiation.jl new file mode 100644 index 00000000..9c9e0a02 --- /dev/null +++ b/src/OceanSeaIceModels/surface_radiation.jl @@ -0,0 +1,37 @@ +struct SurfaceRadiation{FT, E, R} + emission :: E + reflection :: R + stefan_boltzmann_constant :: FT + reference_temperature :: FT +end + +function SurfaceRadiation(FT=Float64; + ocean_emissivity = 0.97, + sea_ice_emissivity = 1.0, + ocean_albedo = 0.3, + sea_ice_albedo = 0.7, + reference_temperature = 273.15, + stefan_boltzmann_constant = 5.67e-8) + + ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) + ice_emissivity isa Number && (ice_emissivity = convert(FT, ice_emissivity)) + ocean_albedo isa Number && (ocean_albedo = convert(FT, ocean_albedo)) + ice_albedo isa Number && (ice_albedo = convert(FT, ice_albedo)) + + emission = SurfaceProperties(ocean_emissivity, sea_ice_emissivity) + reflection = SurfaceProperties(ocean_albedo, sea_ice_albedo) + + return SurfaceRadiation(emission, + reflection, + convert(FT, stefan_boltzmann_constant), + convert(FT, reference_temperature)) +end + +Base.summary(r::SurfaceRadiation) = "SurfaceRadiation" +Base.show(io::IO, r::SurfaceRadiation) = print(io, summary(osf)) + +struct SurfaceProperties{O, I} + ocean :: O + sea_ice :: I +end + From ccf0497b80bfd26129b002a56fc5bdc3388b014a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 30 Nov 2023 14:44:29 -0700 Subject: [PATCH 045/182] Updates --- experiments/prototype_omip_simulation/omip_simulation.jl | 2 +- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 4 ++-- src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 65c4fab9..17fa28e3 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -120,7 +120,7 @@ include("omip_sea_ice_component.jl") # also defines `radiation`, a `ClimaOcean.OceanSeaIceModels.Radiation` include("omip_atmosphere_and_radiation.jl") -coupled_model = OceanSeaIceModel(ocean, ice, atmosphere; surface_radiation) +coupled_model = OceanSeaIceModel(ocean, ice, atmosphere; downwelling_radiation) coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) #stop_time=30days) adjust_ice_covered_ocean_temperature!(coupled_model) diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 5cb1c7aa..c779fd99 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -31,7 +31,7 @@ fields(::OSIM) = NamedTuple() default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) function OceanSeaIceModel(ocean, sea_ice=nothing, atmosphere=nothing; - surface_radiation = nothing, + downwelling_radiation = nothing, clock = default_clock(eltype(ocean.model))) previous_ice_thickness = deepcopy(sea_ice.model.ice_thickness) @@ -46,7 +46,7 @@ function OceanSeaIceModel(ocean, sea_ice=nothing, atmosphere=nothing; # Contains information about flux contributions: bulk formula, prescribed # fluxes, etc. - fluxes = OceanSeaIceModelFluxes(eltype(grid); surface_radiation) + fluxes = OceanSeaIceModelFluxes(eltype(grid); downwelling_radiation) # Contains a reference to the Fields holding net surface fluxes: # ocean top surface, and both top and bottom sea ice surfaces diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl index bc8b2d47..aa966096 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl @@ -42,7 +42,7 @@ struct AtmosphereOnlyVelocityScale end struct OceanSeaIceModelFluxes{U, R, AO, ASI, SIO} bulk_velocity_scale :: U - surface_radiation :: R + downwelling_radiation :: R atmosphere_ocean :: AO atmosphere_sea_ice :: ASI sea_ice_ocean :: SIO @@ -50,7 +50,7 @@ end function OceanSeaIceModelFluxes(FT=Float64; bulk_velocity_scale = RelativeVelocityScale(), - surface_radiation = nothing, + downwelling_radiation = nothing, atmosphere_ocean = nothing, atmosphere_sea_ice = nothing, sea_ice_ocean = nothing) @@ -67,7 +67,7 @@ function OceanSeaIceModelFluxes(FT=Float64; end return OceanSeaIceModelFluxes(bulk_velocity_scale, - surface_radiation, + downwelling_radiation, atmosphere_ocean, atmosphere_sea_ice, sea_ice_ocean) From 6ed41de64ca4f94c65e10bc5badbf299d6af7c91 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sat, 2 Dec 2023 08:20:25 -0700 Subject: [PATCH 046/182] All the formulas now --- ...obally_distributed_single_column_models.jl | 212 ++++++++++++++ ...re_and_radiation.jl => omip_atmosphere.jl} | 25 +- .../omip_ocean_component.jl | 6 +- .../omip_sea_ice_component.jl | 30 +- .../omip_simulation.jl | 36 +-- src/OceanSeaIceModels/OceanSeaIceModels.jl | 5 +- .../PrescribedAtmospheres.jl | 16 +- .../compute_atmosphere_ocean_fluxes.jl | 149 +++++----- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 64 +++-- .../ocean_sea_ice_model_fluxes.jl | 268 +++++++++++++----- src/OceanSeaIceModels/surface_radiation.jl | 20 +- 11 files changed, 596 insertions(+), 235 deletions(-) create mode 100644 experiments/prototype_omip_simulation/globally_distributed_single_column_models.jl rename experiments/prototype_omip_simulation/{omip_atmosphere_and_radiation.jl => omip_atmosphere.jl} (71%) diff --git a/experiments/prototype_omip_simulation/globally_distributed_single_column_models.jl b/experiments/prototype_omip_simulation/globally_distributed_single_column_models.jl new file mode 100644 index 00000000..fd0e7b8c --- /dev/null +++ b/experiments/prototype_omip_simulation/globally_distributed_single_column_models.jl @@ -0,0 +1,212 @@ +using Oceananigans +using Oceananigans.Units +using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity +using Oceananigans.Fields: ConstantField, ZeroField, interpolate! +using Oceananigans.Models.HydrostaticFreeSurfaceModels: ColumnEnsembleSize + +using ClimaOcean +using ClimaOcean.OceanSeaIceModels: TwoStreamDownwellingRadiation, + PrescribedAtmosphere, + SurfaceRadiation + +using ClimaOcean.JRA55: jra55_field_time_series + +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + +using NCDatasets +using GLMakie +using Printf + +using Downloads: download + +temperature_filename = "THETA.1440x720x50.19920102.nc" +salinity_filename = "SALT.1440x720x50.19920102.nc" +ice_thickness_filename = "SIheff.1440x720.19920102.nc" + +# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N + +temperature_url = "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * + "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0" + +salinity_url = "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * + "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0" + +ice_thickness_url = "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/" * + "SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am&dl=0" + +isfile(temperature_filename) || download(temperature_url, temperature_filename) +isfile(salinity_filename) || download(salinity_url, salinity_filename) +isfile(ice_thickness_filename) || download(ice_thickness_url, ice_thickness_filename) + +temperature_ds = Dataset(temperature_filename) +salinity_ds = Dataset(salinity_filename) +ice_thickness_ds = Dataset(ice_thickness_filename) + +# Construct vertical coordinate +depth = temperature_ds["DEPTH_T"][:] +zc = -reverse(depth) + +# Interface depths from cell center depths +zf = (zc[1:end-1] .+ zc[2:end]) ./ 2 +push!(zf, 0) + +Δz = zc[2] - zc[1] +pushfirst!(zf, zf[1] - Δz) + +Tᵢ = temperature_ds["THETA"][:, :, :, 1] +Sᵢ = salinity_ds["SALT"][:, :, :, 1] +ℋᵢ = ice_thickness_ds["SIheff"][:, :, 1] + +Nx′, Ny′, Nz = size(Tᵢ) + +##### +##### Construct the grid +##### + +arch = CPU() + +Nx = 1 +target_longitude = 180 +western_limit = target_longitude +eastern_limit = target_longitude + 1/4 +i₁ = 4 * western_limit +i₂ = i₁ + 1 + +southern_limit = -70 +northern_limit = +55 +j₁ = 4 * (90 + southern_limit) +j₂ = 720 - 4 * (90 - northern_limit) + 1 + +Ny = j₂ - j₁ + 1 + +Tᵢ = Tᵢ[i₁:i₂, j₁:j₂, :] +Sᵢ = Sᵢ[i₁:i₂, j₁:j₂, :] + +Tᵢ = convert(Array{Float32, 3}, Tᵢ) +Sᵢ = convert(Array{Float32, 3}, Sᵢ) +ℋᵢ = convert(Array{Float32, 2}, ℋᵢ) + +Tᵢ = reverse(Tᵢ, dims=3) +Sᵢ = reverse(Sᵢ, dims=3) + +# missing_value = Float32(-9.9e22) + +grid = LatitudeLongitudeGrid(arch, + size = (Nx, Ny, Nz), + halo = (1, 1, 1), + longitude = (western_limit, eastern_limit), + latitude = (southern_limit, northern_limit), + z = zf, + topology = (Periodic, Bounded, Bounded)) + +include("omip_atmosphere.jl") + +column_ensemble_size = ColumnEnsembleSize(Nz=Nz, ensemble=(Nx, Ny)) +column_ensemble_halo_size = ColumnEnsembleSize(Nz=0, Hz=1) + +single_column_grid = RectilinearGrid(arch, + size = column_ensemble_size, + halo = column_ensemble_halo_size, + z = zf, + topology = (Flat, Flat, Bounded)) + +Ω = Oceananigans.Coriolis.Ω_Earth +f(i, j) = 2Ω * sind(φnode(i, j, 1, grid)) +coriolis = [FPlane(f=f(i, j)) for i=1:Nx, j=1:Ny] + +top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(single_column_grid) +top_salt_flux = Fˢ = Field{Center, Center, Nothing}(single_column_grid) +top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(single_column_grid) +top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(single_column_grid) + +ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), + T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) + +# Model construction +teos10 = TEOS10EquationOfState() +buoyancy = SeawaterBuoyancy(equation_of_state=teos10) +closure = CATKEVerticalDiffusivity() + +ocean_model = HydrostaticFreeSurfaceModel(; buoyancy, closure, coriolis, + grid = single_column_grid, + tracers = (:T, :S, :e), + boundary_conditions = ocean_boundary_conditions) + +#= +##### +##### Setup JRA55 atmosphere +##### + +time_indices = 1:10 + +ua_jra55 = jra55_field_time_series(:eastward_velocity; time_indices, architecture=arch) +va_jra55 = jra55_field_time_series(:northward_velocity; time_indices, architecture=arch) +Ta_jra55 = jra55_field_time_series(:temperature; time_indices, architecture=arch) +qa_jra55 = jra55_field_time_series(:relative_humidity; time_indices, architecture=arch) +Fr_jra55 = jra55_field_time_series(:freshwater_rain_flux; time_indices, architecture=arch) +Fs_jra55 = jra55_field_time_series(:freshwater_snow_flux; time_indices, architecture=arch) +Qlw_jra55 = jra55_field_time_series(:downwelling_longwave_radiation; time_indices, architecture=arch) +Qsw_jra55 = jra55_field_time_series(:downwelling_shortwave_radiation; time_indices, architecture=arch) + +times = ua_jra55.times + +u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing)) +v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing)) +c_bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing)) + +ua_jra55 = FieldTimeSeries{Face, Center, Nothing}(grid, times; boundary_conditions=u_bcs) +va_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_conditions=v_bcs) +Ta_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +qa_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Fr_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Fs_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Qlw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Qsw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) + +interpolate!(ua_jra55, u_jra55_native) +interpolate!(va_jra55, v_jra55_native) +interpolate!(Ta_jra55, T_jra55_native) +interpolate!(qa_jra55, q_jra55_native) +interpolate!(Fr_jra55, Fr_jra55_native) +interpolate!(Fs_jra55, Fs_jra55_native) +interpolate!(Qlw_jra55, Qlw_jra55_native) +interpolate!(Qsw_jra55, Qsw_jra55_native) + + ua_scm = FieldTimeSeries{Face, Center, Nothing}(single_column_grid, times) + va_scm = FieldTimeSeries{Center, Face, Nothing}(single_column_grid, times) + Ta_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) + qa_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) + Fr_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) + Fs_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) +Qlw_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) +Qsw_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) + +interior( u_scm, :, :, :) .= interior( u_jra55, :, :, :) +interior( v_scm, :, :, :) .= interior( v_jra55, :, :, :) +interior( T_scm, :, :, :) .= interior( T_jra55, :, :, :) +interior( q_scm, :, :, :) .= interior( q_jra55, :, :, :) +interior( Fr_scm, :, :, :) .= interior( Fr_jra55, :, :, :) +interior( Fs_scm, :, :, :) .= interior( Fs_jra55, :, :, :) +interior(Qlw_scm, :, :, :) .= interior(Qlw_jra55, :, :, :) +interior(Qsw_scm, :, :, :) .= interior(Qsw_jra55, :, :, :) + +velocities = (u = u_scm, v = v_scm) +tracers = (T = T_scm, q = q_scm) +freshwater_flux = (rain = Fr_scm, snow = Fs_scm) +downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_scm, longwave=Qsw_scm) +atmosphere = PrescribedAtmosphere(times; velocities, freshwater_flux, tracers, downwelling_radiation) +=# + +set!(ocean_model, T=Tᵢ, S=Sᵢ) + +surface_radiation = SurfaceRadiation() + +coupled_model = OceanSeaIceModel(ocean; + atmosphere = atmosphere + surface_radiation = surface_radiation) + +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) #stop_time=30days) + +run!(coupled_simulation) diff --git a/experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl b/experiments/prototype_omip_simulation/omip_atmosphere.jl similarity index 71% rename from experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl rename to experiments/prototype_omip_simulation/omip_atmosphere.jl index 77d431cd..1db65447 100644 --- a/experiments/prototype_omip_simulation/omip_atmosphere_and_radiation.jl +++ b/experiments/prototype_omip_simulation/omip_atmosphere.jl @@ -24,22 +24,21 @@ u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing)) v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing)) c_bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing)) -u_jra55 = FieldTimeSeries{Face, Center, Nothing}(grid, times; boundary_conditions=u_bcs) -v_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_conditions=v_bcs) - -T_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -q_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Fr_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Fs_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +u_jra55 = FieldTimeSeries{Face, Center, Nothing}(grid, times; boundary_conditions=u_bcs) +v_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_conditions=v_bcs) +T_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +q_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Fr_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) +Fs_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) Qlw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) Qsw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -interpolate!(u_jra55, u_jra55_native) -interpolate!(v_jra55, v_jra55_native) -interpolate!(T_jra55, T_jra55_native) -interpolate!(q_jra55, q_jra55_native) -interpolate!(Fr_jra55, Fr_jra55_native) -interpolate!(Fs_jra55, Fs_jra55_native) +interpolate!(u_jra55, u_jra55_native) +interpolate!(v_jra55, v_jra55_native) +interpolate!(T_jra55, T_jra55_native) +interpolate!(q_jra55, q_jra55_native) +interpolate!(Fr_jra55, Fr_jra55_native) +interpolate!(Fs_jra55, Fs_jra55_native) interpolate!(Qlw_jra55, Qlw_jra55_native) interpolate!(Qsw_jra55, Qsw_jra55_native) diff --git a/experiments/prototype_omip_simulation/omip_ocean_component.jl b/experiments/prototype_omip_simulation/omip_ocean_component.jl index 9c14b05a..f0bb43d6 100644 --- a/experiments/prototype_omip_simulation/omip_ocean_component.jl +++ b/experiments/prototype_omip_simulation/omip_ocean_component.jl @@ -1,4 +1,3 @@ -ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) @@ -28,10 +27,9 @@ momentum_advection = VectorInvariant(vorticity_scheme = WENO(), ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, tracer_advection, momentum_advection, tracers = (:T, :S, :e), - free_surface = SplitExplicitFreeSurface(cfl=0.2; grid), + free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), boundary_conditions = ocean_boundary_conditions, coriolis = HydrostaticSphericalCoriolis()) -set!(ocean_model, T=Tᵢ, S=Sᵢ) - +#set!(ocean_model, T=Tᵢ, S=Sᵢ) ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) diff --git a/experiments/prototype_omip_simulation/omip_sea_ice_component.jl b/experiments/prototype_omip_simulation/omip_sea_ice_component.jl index c93e2770..fbd2cd83 100644 --- a/experiments/prototype_omip_simulation/omip_sea_ice_component.jl +++ b/experiments/prototype_omip_simulation/omip_sea_ice_component.jl @@ -1,11 +1,13 @@ -ice_grid = LatitudeLongitudeGrid(arch, +sea_ice_grid = LatitudeLongitudeGrid(arch, size = (Nx, Ny), longitude = (0, 360), halo = (7, 7), latitude = (southern_limit, northern_limit), topology = (Periodic, Bounded, Flat)) -ice_grid = ImmersedBoundaryGrid(ice_grid, GridFittedBottom(bottom_height)) +sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBottom(bottom_height)) + +sea_ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) Nz = size(grid, 3) So = ocean_model.tracers.S @@ -17,18 +19,18 @@ ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), v = view(v, :, :, Nz), #interior(v, :, :, Nz), w = ZeroField()) -ice_model = SlabSeaIceModel(ice_grid; - velocities = ocean_surface_velocities, - advection = nothing, - ice_consolidation_thickness = 0.05, - ice_salinity = 4, - internal_heat_flux = ConductiveFlux(conductivity=2), - top_heat_flux = ConstantField(0), # W m⁻² - top_heat_boundary_condition = PrescribedTemperature(0), - bottom_heat_boundary_condition = bottom_bc, - bottom_heat_flux = ice_ocean_heat_flux) +sea_ice_model = SlabSeaIceModel(sea_ice_grid; + velocities = ocean_surface_velocities, + advection = nothing, + ice_consolidation_thickness = 0.05, + ice_salinity = 4, + internal_heat_flux = ConductiveFlux(conductivity=2), + top_heat_flux = ConstantField(0), # W m⁻² + top_heat_boundary_condition = PrescribedTemperature(0), + bottom_heat_boundary_condition = bottom_bc, + bottom_heat_flux = sea_ice_ocean_heat_flux) -set!(ice_model, h=ℋᵢ) +set!(sea_ice_model, h=ℋᵢ) -ice = Simulation(ice_model, Δt=5minutes, verbose=false) +sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 17fa28e3..c5dcc690 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -118,9 +118,12 @@ include("omip_sea_ice_component.jl") # Defines `atmosphere`, a `ClimaOcean.OceanSeaIceModels.PrescribedAtmosphere` # also defines `radiation`, a `ClimaOcean.OceanSeaIceModels.Radiation` -include("omip_atmosphere_and_radiation.jl") +include("omip_atmosphere.jl") -coupled_model = OceanSeaIceModel(ocean, ice, atmosphere; downwelling_radiation) +set!(ocean_model, T=Tᵢ, S=Sᵢ) + +surface_radiation = SurfaceRadiation() +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, surface_radiation) coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) #stop_time=30days) adjust_ice_covered_ocean_temperature!(coupled_model) @@ -149,7 +152,7 @@ coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1 using Oceananigans.Operators: ζ₃ᶠᶠᶜ u, v, w = ocean_model.velocities ζ = KernelFunctionOperation{Face, Face, Center}(ζ₃ᶠᶠᶜ, grid, u, v) -ℋ = ice_model.ice_thickness +ℋ = sea_ice_model.ice_thickness outputs = merge(ocean_model.velocities, ocean_model.tracers, (; ζ, ℋ)) filename = "omip_surface_fields.jld2" @@ -170,9 +173,10 @@ axx = Axis(fig[1, 1]) axy = Axis(fig[2, 1]) axQ = Axis(fig[3, 1]) -τˣ = coupled_model.fluxes.surfaces.ocean.momentum.u -τʸ = coupled_model.fluxes.surfaces.ocean.momentum.v -Jᵀ = coupled_model.fluxes.surfaces.ocean.tracers.T +τˣ = coupled_model.surfaces.ocean.momentum.u +τʸ = coupled_model.surfaces.ocean.momentum.v +Jᵀ = coupled_model.surfaces.ocean.tracers.T +F = coupled_model.surfaces.ocean.tracers.S ρₒ = coupled_model.ocean_reference_density cₚ = coupled_model.ocean_heat_capacity @@ -187,23 +191,17 @@ compute!(Q) τʸ = interior(τʸ, :, :, 1) Q = interior(Q, :, :, 1) -# τˣ ./= ρₒ -# τʸ ./= ρₒ - -land = τˣ .== NaN -τˣ[land] .= 0 - -land = τʸ .== NaN -τʸ[land] .= 0 - Qmax = maximum(abs, Q) τmax = 1.0 #max(maximum(abs, τˣ), maximum(abs, τʸ)) +Fmax = maximum(abs, F) -Qlim = 3Qmax / 4 τlim = 3τmax / 4 +Qlim = 3Qmax / 4 +Flim = 3Fmax / 4 land = Q .== 0 Q[land] .= NaN +F[land] .= NaN land = τˣ .== 0 τˣ[land] .= NaN @@ -211,13 +209,15 @@ land = τˣ .== 0 land = τʸ .== 0 τʸ[land] .= NaN -hmx = heatmap!(axx, λf, φc, τˣ, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) -hmy = heatmap!(axy, λc, φf, τʸ, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) +hmx = heatmap!(axx, λf, φc, ρₒ .* τˣ, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) +hmy = heatmap!(axy, λc, φf, ρₒ .* τʸ, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) hmQ = heatmap!(axQ, λc, φc, Q, colorrange=(-Qlim, Qlim), colormap=:balance, nan_color=:gray) +hmF = heatmap!(axF, λc, φc, F, colorrange=(-Flim, Flim), colormap=:balance, nan_color=:gray) Colorbar(fig[1, 2], hmx, label="Eastward momentum flux (N m⁻²)") Colorbar(fig[2, 2], hmy, label="Northward momentum flux (N m⁻²)") Colorbar(fig[3, 2], hmQ, label="Heat flux (W m⁻²)") +Colorbar(fig[3, 2], hmF, label="Salt flux (m s⁻¹ psu)") display(fig) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 640ad4bb..2cd5f452 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -38,8 +38,11 @@ const SKOFTS = SomeKindOfFieldTimeSeries function surface_velocities end function surface_tracers end - function sea_ice_thickness end +function downwelling_radiation end +function freshwater_flux end +function specific_heat end +function density end ##### ##### Some implementation diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 433a6d31..92768ea5 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -1,12 +1,15 @@ module PrescribedAtmospheres -import ..OceanSeaIceModels: surface_velocities, surface_tracers +import ..OceanSeaIceModels: surface_velocities, surface_tracers, downwelling_radiation, freshwater_flux +import ..OceanSeaIceModels: density, specific_heat -struct PrescribedAtmosphere{U, F, R, C, T} +struct PrescribedAtmosphere{U, F, R, C, ρ, CP, T} velocities :: U freshwater_flux :: F downwelling_radiation :: R tracers :: C + density :: ρ + specific_heat :: CP times :: T end @@ -24,18 +27,25 @@ function PrescribedAtmosphere(times; velocities = nothing, freshwater_flux = nothing, downwelling_radiation = nothing, + density = 1.2, + specific_heat = 1.0005, tracers = nothing) return PrescribedAtmosphere(velocities, freshwater_flux, downwelling_radiation, tracers, + density, + specific_heat, times) end surface_velocities(pa::PrescribedAtmosphere) = pa.velocities surface_tracers(pa::PrescribedAtmosphere) = pa.tracers -freshwater_fluxes(pa::PrescribedAtmosphere) = pa.freshwater_fluxes +freshwater_flux(pa::PrescribedAtmosphere) = pa.freshwater_flux +downwelling_radiation(pa::PrescribedAtmosphere) = pa.downwelling_radiation +density(pa::PrescribedAtmosphere) = pa.density +specific_heat(pa::PrescribedAtmosphere) = pa.specific_heat struct TwoStreamDownwellingRadiation{SW, LW} shortwave :: SW diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index f6964c43..413743e6 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -1,4 +1,5 @@ using Oceananigans.Grids: inactive_node +using Oceananigans.Fields: ConstantField ##### ##### Utilities @@ -7,9 +8,9 @@ using Oceananigans.Grids: inactive_node function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) grid = ocean.model.grid Nz = size(grid, 3) - u = interior(ocean.model.velocities.u, :, :, Nz) - v = interior(ocean.model.velocities.v, :, :, Nz) - w = interior(ocean.model.velocities.w, :, :, Nz+1) + u = view(ocean.model.velocities.u.data, :, :, Nz) + v = view(ocean.model.velocities.v.data, :, :, Nz) + w = view(ocean.model.velocities.w.data, :, :, Nz+1) return (; u, v, w) end @@ -17,9 +18,8 @@ function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) grid = ocean.model.grid Nz = size(grid, 3) tracers = ocean.model.tracers - tracer_names = keys(tracers) - sfc_tracers = NamedTuple(name => interior(tracers[name], :, :, Nz) - for name in tracer_names) + names = keys(tracers) + sfc_tracers = NamedTuple(name => view(tracers[name].data, :, :, Nz) for name in names) return sfc_tracers end @@ -32,6 +32,7 @@ const f = Face() function compute_atmosphere_ocean_fluxes!(coupled_model) ocean = coupled_model.ocean + sea_ice = coupled_model.sea_ice atmosphere = coupled_model.atmosphere # Basic model properties @@ -53,34 +54,36 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) # Fluxes, and flux contributors net_momentum_fluxes = coupled_model.surfaces.ocean.momentum net_tracer_fluxes = coupled_model.surfaces.ocean.tracers - momentum_flux_contributions = coupled_model.fluxes.atmosphere_ocean.momentum - heat_flux_contributions = coupled_model.fluxes.atmosphere_ocean.heat - tracer_flux_contributions = coupled_model.fluxes.atmosphere_ocean.tracers + bulk_momentum_flux_formulae = coupled_model.fluxes.atmosphere_ocean.momentum + bulk_heat_flux_formulae = coupled_model.fluxes.atmosphere_ocean.heat + bulk_tracer_flux_formulae = coupled_model.fluxes.atmosphere_ocean.tracers + bulk_velocity_scale = coupled_model.fluxes.bulk_velocity_scale + surface_radiation = coupled_model.fluxes.surface_radiation - # Parameters? - atmosphere_ocean_parameters = ( - ρₐ = 1.2, # ? - ρₒ = coupled_model.ocean_reference_density, - cₚ = coupled_model.ocean_heat_capacity, - ) + ocean_state = merge(ocean_velocities, ocean_tracers) - surface_radiation = coupled_model.fluxes.surface_radiation + atmosphere_state = (ρ = density(atmosphere), + cₚ = specific_heat(atmosphere)) + + atmosphere_state = merge(atmosphere_velocities, + atmosphere_tracers, + atmosphere_state) launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, grid, clock, net_momentum_fluxes, net_tracer_fluxes, - momentum_flux_contributions, - heat_flux_contributions, - tracer_flux_contributions, - ocean_velocities, - atmosphere_velocities, - ocean_tracers, - atmosphere_tracers, + bulk_velocity_scale, + bulk_momentum_flux_formulae, + bulk_heat_flux_formulae, + bulk_tracer_flux_formulae, + ocean_state, + atmosphere_state, atmosphere_downwelling_radiation, surface_radiation, atmosphere_freshwater_flux, - atmosphere_ocean_parameters, + coupled_model.ocean_reference_density, + coupled_model.ocean_heat_capacity, ice_thickness) return nothing @@ -90,17 +93,17 @@ end clock, net_momentum_fluxes, net_tracer_fluxes, - momentum_flux_contributions, - heat_flux_contributions, - tracer_flux_contributions, - ocean_velocities, - atmosphere_velocities, - ocean_tracers, - atmosphere_tracers, + bulk_velocity, + bulk_momentum_flux_formulae, + bulk_heat_flux_formulae, + bulk_tracer_flux_formulae, + ocean_state, + atmos_state, downwelling_radiation, surface_radiation, - freshwater_flux, - atmosphere_ocean_parameters, + prescribed_freshwater_flux, + ocean_reference_density, + ocean_heat_capacity, ice_thickness) i, j = @index(Global, NTuple) @@ -108,82 +111,80 @@ end time = Time(clock.time) - τˣ = net_momentum_fluxes.u - τʸ = net_momentum_fluxes.v + Jᵘ = net_momentum_fluxes.u + Jᵛ = net_momentum_fluxes.v Jᵀ = net_tracer_fluxes.T Jˢ = net_tracer_fluxes.S - Uₒ = ocean_velocities - Uₐ = atmosphere_velocities - uₐ = Uₐ.u - vₐ = Uₐ.v - uₒ = Uₒ.u - vₒ = Uₒ.v - - Tₒ = ocean_tracers.T + # Note: there could one or more formula(e) + τˣ_formula = bulk_momentum_flux_formulae.u + τʸ_formula = bulk_momentum_flux_formulae.v + Q_formula = bulk_heat_flux_formulae + F_formula = bulk_tracer_flux_formulae.S - ρₐ = atmosphere_ocean_parameters.ρₐ - ρₒ = atmosphere_ocean_parameters.ρₒ - cₚ = atmosphere_ocean_parameters.cₚ + atmos_state_names = keys(atmos_state) + ocean_state_names = keys(atmos_state) - u_formula = momentum_flux_contributions.u.velocity_scale - v_formula = momentum_flux_contributions.v.velocity_scale - cᴰ = momentum_flux_contributions.u.transfer_coefficient + atmos_state_ij = stateindex(atmos_state, i, j, 1, time) + ocean_state_ij = stateindex(ocean_state, i, j, 1, time) # Compute transfer velocity scale - ΔUᶠᶜᶜ = bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, u_formula, Uₐ, Uₒ) - ΔUᶜᶠᶜ = bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, v_formula, Uₐ, Uₒ) - ΔUᶜᶜᶜ = bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, v_formula, Uₐ, Uₒ) + ΔUᶠᶜᶜ = bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) + ΔUᶜᶠᶜ = bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) + ΔUᶜᶜᶜ = bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) # Compute momentum fluxes - Δu = air_sea_difference(i, j, grid, time, u_formula, uₐ, uₒ) - Δv = air_sea_difference(i, j, grid, time, v_formula, vₐ, vₒ) + τˣ = cross_realm_flux(i, j, grid, time, τˣ_formula, ΔUᶠᶜᶜ, atmos_state, ocean_state) + τʸ = cross_realm_flux(i, j, grid, time, τʸ_formula, ΔUᶜᶠᶜ, atmos_state, ocean_state) - atmos_ocean_τˣ = - ρₐ / ρₒ * cᴰ * Δu * ΔUᶠᶜᶜ - atmos_ocean_τʸ = - ρₐ / ρₒ * cᴰ * Δv * ΔUᶜᶠᶜ + # Compute heat fluxes, bulk flux first + Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, surface_radiation) + Qu = net_upwelling_radiation(i, j, grid, time, surface_radiation, ocean_state) - # Compute heat fluxes - # Radiation first - Q = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, surface_radiation) - Q += net_upwelling_radiation(i, j, grid, time, surface_radiation, Tₒ) + Q★ = cross_realm_flux(i, j, grid, time, Q_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) + Q = Q★ + Qd + Qu + + # Compute salinity fluxes, bulk flux first + Fp = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) + F★ = cross_realm_flux(i, j, grid, time, F_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) + F = F★ + Fp # Then the rest of the heat fluxes - atmos_ocean_Jᵀ = Q / (ρₒ * cₚ) + ρₒ = ocean_reference_density + cₚ = ocean_heat_capacity - # Compute salinity fluxes - F = tracer_flux(i, j, grid, time, freshwater_flux) + atmos_ocean_Jᵘ = τˣ / ρₒ + atmos_ocean_Jᵛ = τʸ / ρₒ + atmos_ocean_Jᵀ = Q / (ρₒ * cₚ) atmos_ocean_Jˢ = F @inbounds begin # Set fluxes # TODO: should this be peripheral_node? - τˣ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, f, c, c), zero(grid), atmos_ocean_τˣ) - τʸ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, f, c), zero(grid), atmos_ocean_τʸ) + Jᵘ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, f, c, c), zero(grid), atmos_ocean_Jᵘ) + Jᵛ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, f, c), zero(grid), atmos_ocean_Jᵛ) Jᵀ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jᵀ) Jˢ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jˢ) end end -@inline Δϕt²(i, j, k, grid, ϕ1t, ϕ2, time) = @inbounds (ϕ1t[i, j, k, time] - ϕ2[i, j, k])^2 - @inline function net_downwelling_radiation(i, j, grid, time, downwelling_radiation, surface_radiation) Qˢʷ = downwelling_radiation.shortwave Qˡʷ = downwelling_radiation.longwave - - # Assumes albedo is a constant - α = surface_radiation.reflection.ocean + α = stateindex(surface_radiation.reflection.ocean, i, j, 1, time) return @inbounds - (1 - α) * Qˢʷ[i, j, 1, time] - Qˡʷ[i, j, 1, time] end -@inline function upwelling_radiation(i, j, grid, time, surface_radiation, Tₒ) +@inline function net_upwelling_radiation(i, j, grid, time, surface_radiation, ocean_state) σ = surface_radiation.stefan_boltzmann_constant Tᵣ = surface_radiation.reference_temperature + ϵ = stateindex(surface_radiation.emission.ocean, i, j, 1, time) - # Assumes emissivity is a constant - ϵ = surface_radiation.emission.ocean + # Ocean surface temperature (departure from reference, typically in ᵒC) + Tₒ = @inbounds ocean_state.T[i, j, 1] # Note: positive implies _upward_ heat flux, and therefore cooling. - return @inbounds σ * ϵ * (Tₒ[i, j, 1] + Tᵣ)^4 + return σ * ϵ * (Tₒ + Tᵣ)^4 end diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index c779fd99..cfd1cb5c 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -1,6 +1,9 @@ +using Oceananigans using Oceananigans.Models: update_model_field_time_series! using Oceananigans.TimeSteppers: Clock -using Oceananigans +using Oceananigans.BuoyancyModels: SeawaterBuoyancy + +using SeawaterPolynomials: TEOS10EquationOfState struct OceanSeaIceModel{FT, I, A, O, S, F, PI, PC, C, G} <: AbstractModel{Nothing} clock :: C @@ -30,9 +33,24 @@ prognostic_fields(cm::OSIM) = nothing fields(::OSIM) = NamedTuple() default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) -function OceanSeaIceModel(ocean, sea_ice=nothing, atmosphere=nothing; - downwelling_radiation = nothing, - clock = default_clock(eltype(ocean.model))) +reference_density(ocean::Simulation) = reference_density(ocean.model.buoyancy.model) +reference_density(buoyancy_model::SeawaterBuoyancy) = reference_density(buoyancy_model.equation_of_state) +#reference_density(unsupported) = throw(ArgumentError("Cannot extract reference density from $(typeof(unsupported))")) +#reference_density(eos::TEOS10EquationOfState) = eos.reference_density +reference_density(eos) = eos.reference_density + +heat_capacity(ocean::Simulation) = heat_capacity(ocean.model.buoyancy.model) +heat_capacity(buoyancy_model::SeawaterBuoyancy) = heat_capacity(buoyancy_model.equation_of_state) +#heat_capacity(unsupported) = throw(ArgumentError("Cannot deduce the heat capacity from $(typeof(unsupported))")) +#heat_capacity(eos::TEOS10EquationOfState) = 3991 # get the right value in here eventually +heat_capacity(eos) = 3991 # get the right value in here eventually + +function OceanSeaIceModel(ocean, sea_ice=nothing; + atmosphere = nothing, + surface_radiation = nothing, + ocean_reference_density = reference_density(ocean), + ocean_heat_capacity = heat_capacity(ocean), + clock = deepcopy(ocean.model.clock)) previous_ice_thickness = deepcopy(sea_ice.model.ice_thickness) previous_ice_concentration = deepcopy(sea_ice.model.ice_concentration) @@ -40,13 +58,10 @@ function OceanSeaIceModel(ocean, sea_ice=nothing, atmosphere=nothing; grid = ocean.model.grid ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) ice_ocean_salt_flux = Field{Center, Center, Nothing}(grid) - - ocean_reference_density = 1024 - ocean_heat_capacity = 3991 # Contains information about flux contributions: bulk formula, prescribed # fluxes, etc. - fluxes = OceanSeaIceModelFluxes(eltype(grid); downwelling_radiation) + fluxes = OceanSeaIceModelFluxes(eltype(grid); surface_radiation) # Contains a reference to the Fields holding net surface fluxes: # ocean top surface, and both top and bottom sea ice surfaces @@ -57,7 +72,7 @@ function OceanSeaIceModel(ocean, sea_ice=nothing, atmosphere=nothing; return OceanSeaIceModel(clock, ocean.model.grid, atmosphere, - ice, + sea_ice, ocean, surfaces, fluxes, @@ -73,22 +88,25 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=nothing) ocean = coupled_model.ocean sea_ice = coupled_model.sea_ice - h = sea_ice.model.ice_thickness - fill_halo_regions!(h) - - # Initialization - if coupled_model.clock.iteration == 0 - @info "Initializing coupled model ice thickness..." - h⁻ = coupled_model.previous_ice_thickness - hⁿ = coupled_model.sea_ice.model.ice_thickness - parent(h⁻) .= parent(hⁿ) + # Eventually, split out into OceanOnlyModel + if !isnothing(sea_ice) + h = sea_ice.model.ice_thickness + fill_halo_regions!(h) + + # Initialization + if coupled_model.clock.iteration == 0 + @info "Initializing coupled model ice thickness..." + h⁻ = coupled_model.previous_ice_thickness + hⁿ = coupled_model.sea_ice.model.ice_thickness + parent(h⁻) .= parent(hⁿ) + end + + sea_ice.Δt = Δt + time_step!(sea_ice) end - sea_ice.Δt = Δt ocean.Δt = Δt - time_step!(sea_ice) - # TODO after ice time-step: # - Adjust ocean heat flux if the ice completely melts? @@ -104,10 +122,10 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=nothing) end function update_state!(coupled_model::OceanSeaIceModel, callbacks=nothing) - # update_model_field_time_series!(coupled_model.atmosphere.model) + # update_model_field_time_series!(coupled_model.atmosphere) compute_atmosphere_ocean_fluxes!(coupled_model) # compute_atmosphere_sea_ice_fluxes!(coupled_model) - compute_sea_ice_ocean_fluxes!(coupled_model) + # compute_sea_ice_ocean_fluxes!(coupled_model) return nothing end diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl index aa966096..c56f36cb 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl @@ -5,6 +5,24 @@ using ClimaSeaIce.SlabSeaIceModels: SlabSeaIceModel ##### Utilities ##### +@inline stateindex(a::Number, i, j, k, time) = a +@inline stateindex(a::SKOFTS, i, j, k, time) = a[i, j, k, time] +@inline stateindex(a::AbstractArray, i, j, k, time) = a[i, j, k] +@inline Δϕt²(i, j, k, grid, ϕ1, ϕ2, time) = (stateindex(ϕ1, i, j, k, time) - stateindex(ϕ2, i, j, k, time))^2 + +@inline function stateindex(a::Tuple, i, j, k, time) + N = length(a) + ntuple(Val(N)) do n + stateindex(a[n], i, j, k, time) + end +end + +@inline function stateindex(a::NamedTuple, i, j, k, time) + vals = stateindex(values(a), i, j, k, time) + names = keys(a) + return NamedTuple{names}(vals) +end + function surface_flux(f::Field) top_bc = f.boundary_conditions.top if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} @@ -37,37 +55,52 @@ Base.show(io::IO, osf::CrossRealmFluxes) = print(io, summary(osf)) ##### Container for organizing information related to fluxes ##### -struct RelativeVelocityScale end -struct AtmosphereOnlyVelocityScale end - struct OceanSeaIceModelFluxes{U, R, AO, ASI, SIO} bulk_velocity_scale :: U - downwelling_radiation :: R + surface_radiation :: R atmosphere_ocean :: AO atmosphere_sea_ice :: ASI sea_ice_ocean :: SIO end +function default_atmosphere_ocean_fluxes(FT=Float64, tracers=tuple(:S)) + momentum_transfer_coefficient = 1e-3 + evaporation_transfer_coefficient = 1e-3 + sensible_heat_transfer_coefficient = 1e-3 + + τˣ = BulkFormula(RelativeUVelocity(), momentum_transfer_coefficient) + τʸ = BulkFormula(RelativeVVelocity(), momentum_transfer_coefficient) + momentum_flux_formulae = (u=τˣ, v=τʸ) + + water_vapor_difference = WaterVaporFraction(FT) + evaporation = BulkFormula(WaterVaporFraction(FT), evaporation_transfer_coefficient) + tracer_flux_formulae = (; S = evaporation) + + vaporization_enthalpy = convert(FT, 2.5e-3) + latent_heat_difference = LatentHeat(vapor_difference = water_vapor_difference; vaporization_enthalpy) + latent_heat_formula = BulkFormula(latent_heat_difference, evaporation_transfer_coefficient) + sensible_heat_formula = BulkFormula(SensibleHeat(), sensible_heat_transfer_coefficient) + + heat_flux_formulae = (sensible_heat_formula, latent_heat_formula) + + return CrossRealmFluxes(momentum = momentum_flux_formulae, + heat = heat_flux_formulae, + tracers = tracer_flux_formulae) +end + function OceanSeaIceModelFluxes(FT=Float64; bulk_velocity_scale = RelativeVelocityScale(), - downwelling_radiation = nothing, + surface_radiation = nothing, atmosphere_ocean = nothing, atmosphere_sea_ice = nothing, sea_ice_ocean = nothing) if isnothing(atmosphere_ocean) # defaults - τˣ = BulkFormula(RelativeVelocity(), 1e-3) - τʸ = BulkFormula(RelativeVelocity(), 1e-3) - momentum_flux_formulae = (u=τˣ, v=τʸ) - - evaporation = BulkFormula(SpecificHumidity, 1e-3) - - - atmosphere_ocean = CrossRealmFluxes(momentum = momentum_flux_formulae) + atmosphere_ocean = default_atmosphere_ocean_fluxes(FT) end return OceanSeaIceModelFluxes(bulk_velocity_scale, - downwelling_radiation, + surface_radiation, atmosphere_ocean, atmosphere_sea_ice, sea_ice_ocean) @@ -86,7 +119,7 @@ Base.show(io::IO, crf::OceanSeaIceModelFluxes) = print(io, summary(crf)) The basic structure of a flux `J` computed by a bulk formula is: ```math -J = ρₐ * C * Δc * ΔU +J = - ρₐ * C * Δc * ΔU ``` where `ρₐ` is the density of air, `C` is the `transfer_coefficient`, @@ -97,104 +130,189 @@ struct BulkFormula{F, CD} transfer_coefficient :: CD end -@inline function tracer_flux(i, j, grid, time, formula::BulkFormula, ΔU, atmosphere_state, ocean_state) - ρₐ = atmosphere_state.density +@inline function cross_realm_flux(i, j, grid, time, formula::BulkFormula, ΔU, atmos_state, ocean_state) + ρₐ = stateindex(atmos_state.ρ, i, j, 1, time) C = formula.transfer_coefficient - Δc = air_sea_difference(i, j, grid, time, formula.air_sea_difference, atmosphere_state, ocean_state) - return ρₐ * C * Δc * ΔU + Δc = air_sea_difference(i, j, grid, time, formula.air_sea_difference, atmos_state, ocean_state) + + # Note the sign convention, which corresponds to positive upward fluxes: + return - ρₐ * C * Δc * ΔU end -@inline tracer_flux(i, j, grid, time, flux::NamedTuple, args...) = - tracer_flux(i, j, grid, time, values(flux)) +@inline cross_realm_flux(i, j, grid, time, ::Nothing, args...) = zero(grid) +@inline cross_realm_flux(i, j, grid, time, a::AbstractArray, args...) = stateindex(a, i, j, 1, time) +@inline cross_realm_flux(i, j, grid, time, nt::NamedTuple, args...) = cross_realm_flux(i, j, grid, time, values(nt), args...) + +@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any}, args...) = + cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) -@inline tracer_flux(i, j, grid, time, flux::Tuple{<:Any, <:Any}, args...) = - tracer_flux(i, j, grid, time, flux[1], args...) + - tracer_flux(i, j, grid, time, flux[2], args...) +@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any, <:Any}, args...) = + cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[3], args...) -@inline tracer_flux(i, j, grid, time, fts::SKOFTS, args...) = - @inbounds fts[i, j, 1, time] +@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = + cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[3], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[4], args...) ##### ##### Air-sea differences ##### -struct RelativeVelocity end +@inline air_sea_difference(i, j, grid, time, air, sea) = stateindex(air, i, j, 1, time) - + stateindex(sea, i, j, 1, time) + +struct RelativeUVelocity end +struct RelativeVVelocity end + +@inline function air_sea_difference(i, j, grid, time, ::RelativeUVelocity, atmos_state, ocean_state) + uₐ = atmos_state.u + uₒ = ocean_state.u + return air_sea_difference(i, j, grid, time, uₐ, uₒ) +end + +@inline function air_sea_difference(i, j, grid, time, ::RelativeVVelocity, atmos_state, ocean_state) + vₐ = atmos_state.v + vₒ = ocean_state.v + return air_sea_difference(i, j, grid, time, vₐ, vₒ) +end + +struct SensibleHeat end + +@inline function air_sea_difference(i, j, grid, time, ::SensibleHeat, atmos_state, ocean_state) + cₚ = stateindex(atmos_state.cₚ, i, j, 1, time) + Tₐ = atmos_state.T + Tₒ = ocean_state.T + ΔT = air_sea_difference(i, j, grid, time, Tₐ, Tₒ) -struct MassSpecificHumidity{S} - saturation :: S + return @inbounds cₚ[i, j, 1] * ΔT end -struct LargeYeagerSaturation{FT} - c1 :: FT - c2 :: FT +struct WaterVaporFraction{S} + saturation_vapor_fraction :: S + + @doc """ + WaterVaporFraction(FT = Float64; + saturation_vapor_fraction = LargeYeagerSaturationVaporFraction(FT)) + + """ + function WaterVaporFraction(FT = Float64; + saturation_vapor_fraction = LargeYeagerSaturationVaporFraction(FT)) + S = typeof(saturation_vapor_fraction) + return new{S}(saturation_vapor_fraction) + end +end + +struct LargeYeagerSaturationVaporFraction{FT} + q₀ :: FT + c₁ :: FT + c₂ :: FT reference_temperature:: FT end -function LargeYeagerSaturation(FT=Float64; - c1 = 0.98 * 640380, - c2 = -5107.4, - reference_temperature = 273.15) - return LargeYeagerSaturation(convert(FT, c1), - convert(FT, c2), - convert(FT, reference_temperature)) +""" + LargeYeagerSaturationVaporFraction(FT = Float64; + q₀ = 0.98, + c₁ = 640380, + c₂ = -5107.4, + reference_temperature = 273.15) + +""" +function LargeYeagerSaturationVaporFraction(FT = Float64; + q₀ = 0.98, + c₁ = 640380, + c₂ = -5107.4, + reference_temperature = 273.15) + + return LargeYeagerSaturationVaporFraction(convert(FT, q₀), + convert(FT, c₁), + convert(FT, c₂), + convert(FT, reference_temperature)) end -#= -MassSpecificHumidity(FT=Float64; saturation = LargeYeagerSaturation(FT)) = - MassSpecificHumidity(saturation) - -struct InternalEnergy{C} - atmosphere_specific_heat :: C +@inline function saturation_vapor_fraction(i, j, grid, time, + ratio::LargeYeagerSaturationVaporFraction, + atmos_state, ocean_state) + + Tₒ = stateindex(ocean_state.T, i, j, 1, time) + ρₐ = stateindex(atmos_state.ρ, i, j, 1, time) + Tᵣ = ratio.reference_temperature + q₀ = ratio.q₀ + c₁ = ratio.c₁ + c₂ = ratio.c₂ + + return q₀ * c₁ * exp(-c₂ / (Tₒ + Tᵣ)) end -InternalEnergy(FT::DataType; atmosphere_specific_heat=1000.5) = - InternalEnergy(convert(FT, atmosphere_specific_heat)) -=# +@inline function air_sea_difference(i, j, grid, time, diff::WaterVaporFraction, atmos_state, ocean_state) + vapor_fraction = diff.saturation_vapor_fraction + qₐ = stateindex(atmos_state.q, i, j, 1, time) + qₛ = saturation_vapor_fraction(i, j, grid, time, vapor_fraction, atmos_state, ocean_state) + return qₐ - qₛ +end -@inline function air_sea_difference(i, j, grid, time, ::MassSpecificHumidity, atmos, ocean) - return air_sea_difference(i, j, grid, time, atmos, ocean) +struct LatentHeat{Q, FT} + vapor_difference :: Q + vaporization_enthalpy :: FT end -@inline air_sea_difference(i, j, grid, time, air::SKOFTS, sea::AbstractArray) = - @inbounds air[i, j, 1, time] - sea[i, j, 1] +""" + LatentHeat(FT = Float64; + vaporization_enthalpy = 2.5e3 # J / g + vapor_difference = WaterVaporFraction(FT)) + +""" +function LatentHeat(FT = Float64; + vaporization_enthalpy = 2.5e3, # J / g + vapor_difference = WaterVaporFraction(FT)) + + vaporization_enthalpy = convert(FT, vaporization_enthalpy) + return LatentHeat(vapor_difference, vaporization_enthalpy) +end + +@inline function air_sea_difference(i, j, grid, time, diff::LatentHeat, atmos, ocean) + Δq = air_sea_difference(i, j, grid, time, diff.vapor_difference, atmos, ocean) + Λᵥ = diff.vaporization_enthalpy + return Λᵥ * Δq +end ##### ##### Bulk velocity scales ##### -@inline function bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) - uₐ = Uₐ.u - vₐ = Uₐ.v - uₒ = Uₒ.u - vₒ = Uₒ.v - - Δu = @inbounds uₐ[i, j, 1, time] - uₒ[i, j, 1] +struct RelativeVelocityScale end +# struct AtmosphereOnlyVelocityScale end + +@inline function bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, atmos_state, ocean_state) + uₐ = atmos_state.u + vₐ = atmos_state.v + uₒ = ocean_state.u + vₒ = ocean_state.v + Δu = stateindex(uₐ, i, j, 1, time) - stateindex(uₒ, i, j, 1, time) Δv² = ℑxyᶠᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) - return sqrt(Δu^2 + Δv²) end -@inline function bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) - uₐ = Uₐ.u - vₐ = Uₐ.v - uₒ = Uₒ.u - vₒ = Uₒ.v - +@inline function bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, ::RelativeVelocityScale, atmos_state, ocean_state) + uₐ = atmos_state.u + vₐ = atmos_state.v + uₒ = ocean_state.u + vₒ = ocean_state.v Δu² = ℑxyᶜᶠᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) - Δv = @inbounds vₐ[i, j, 1, time] - vₒ[i, j, 1] - + Δv = stateindex(vₐ, i, j, 1, time) - stateindex(vₒ, i, j, 1, time) return sqrt(Δu² + Δv^2) end -@inline function bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, Uₐ, Uₒ) - uₐ = Uₐ.u - vₐ = Uₐ.v - uₒ = Uₒ.u - vₒ = Uₒ.v - +@inline function bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, atmos_state, ocean_state) + uₐ = atmos_state.u + vₐ = atmos_state.v + uₒ = ocean_state.u + vₒ = ocean_state.v Δu² = ℑxᶜᵃᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) Δv² = ℑyᵃᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) - return sqrt(Δu² + Δv²) end diff --git a/src/OceanSeaIceModels/surface_radiation.jl b/src/OceanSeaIceModels/surface_radiation.jl index 9c9e0a02..e27d9dce 100644 --- a/src/OceanSeaIceModels/surface_radiation.jl +++ b/src/OceanSeaIceModels/surface_radiation.jl @@ -6,17 +6,17 @@ struct SurfaceRadiation{FT, E, R} end function SurfaceRadiation(FT=Float64; - ocean_emissivity = 0.97, - sea_ice_emissivity = 1.0, - ocean_albedo = 0.3, - sea_ice_albedo = 0.7, - reference_temperature = 273.15, - stefan_boltzmann_constant = 5.67e-8) + ocean_emissivity = 0.97, + sea_ice_emissivity = 1.0, + ocean_albedo = 0.3, + sea_ice_albedo = 0.7, + reference_temperature = 273.15, + stefan_boltzmann_constant = 5.67e-8) - ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) - ice_emissivity isa Number && (ice_emissivity = convert(FT, ice_emissivity)) - ocean_albedo isa Number && (ocean_albedo = convert(FT, ocean_albedo)) - ice_albedo isa Number && (ice_albedo = convert(FT, ice_albedo)) + ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) + sea_ice_emissivity isa Number && (sea_ice_emissivity = convert(FT, sea_ice_emissivity)) + ocean_albedo isa Number && (ocean_albedo = convert(FT, ocean_albedo)) + sea_ice_albedo isa Number && (sea_ice_albedo = convert(FT, sea_ice_albedo)) emission = SurfaceProperties(ocean_emissivity, sea_ice_emissivity) reflection = SurfaceProperties(ocean_albedo, sea_ice_albedo) From 4498677f84f3cb61f23e06e8bba2ed4e3c657df1 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 4 Dec 2023 13:31:25 -0700 Subject: [PATCH 047/182] Constant coefficient bulk formula working except evaporation --- .../omip_simulation.jl | 18 +++--- .../ocean_sea_ice_model_fluxes.jl | 63 ++++++++++--------- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index c5dcc690..4b16a142 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -124,7 +124,7 @@ set!(ocean_model, T=Tᵢ, S=Sᵢ) surface_radiation = SurfaceRadiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, surface_radiation) -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) #stop_time=30days) +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=20) adjust_ice_covered_ocean_temperature!(coupled_model) @@ -154,7 +154,12 @@ u, v, w = ocean_model.velocities ζ = KernelFunctionOperation{Face, Face, Center}(ζ₃ᶠᶠᶜ, grid, u, v) ℋ = sea_ice_model.ice_thickness -outputs = merge(ocean_model.velocities, ocean_model.tracers, (; ζ, ℋ)) +τˣ = coupled_model.surfaces.ocean.momentum.u +τʸ = coupled_model.surfaces.ocean.momentum.v +Jᵀ = coupled_model.surfaces.ocean.tracers.T +F = coupled_model.surfaces.ocean.tracers.S +fluxes = (; τˣ, τʸ, Jᵀ, F) +outputs = merge(ocean_model.velocities, ocean_model.tracers, fluxes, (; ζ, ℋ)) filename = "omip_surface_fields.jld2" coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outputs; filename, @@ -164,14 +169,12 @@ coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outp run!(coupled_simulation) -# using ClimaOcean.OceanSeaIceModels: compute_atmosphere_ocean_fluxes! -# compute_atmosphere_ocean_fluxes!(coupled_model) - fig = Figure(resolution=(2400, 1200)) axx = Axis(fig[1, 1]) axy = Axis(fig[2, 1]) axQ = Axis(fig[3, 1]) +axF = Axis(fig[4, 1]) τˣ = coupled_model.surfaces.ocean.momentum.u τʸ = coupled_model.surfaces.ocean.momentum.v @@ -190,10 +193,11 @@ compute!(Q) τˣ = interior(τˣ, :, :, 1) τʸ = interior(τʸ, :, :, 1) Q = interior(Q, :, :, 1) +F = interior(F, :, :, 1) Qmax = maximum(abs, Q) τmax = 1.0 #max(maximum(abs, τˣ), maximum(abs, τʸ)) -Fmax = maximum(abs, F) +Fmax = 1e-4 #maximum(abs, F) τlim = 3τmax / 4 Qlim = 3Qmax / 4 @@ -217,7 +221,7 @@ hmF = heatmap!(axF, λc, φc, F, colorrange=(-Flim, Flim), colormap=:balance, na Colorbar(fig[1, 2], hmx, label="Eastward momentum flux (N m⁻²)") Colorbar(fig[2, 2], hmy, label="Northward momentum flux (N m⁻²)") Colorbar(fig[3, 2], hmQ, label="Heat flux (W m⁻²)") -Colorbar(fig[3, 2], hmF, label="Salt flux (m s⁻¹ psu)") +Colorbar(fig[4, 2], hmF, label="Salt flux (m s⁻¹ psu)") display(fig) diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl index c56f36cb..ad2c3df7 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl @@ -67,18 +67,23 @@ function default_atmosphere_ocean_fluxes(FT=Float64, tracers=tuple(:S)) momentum_transfer_coefficient = 1e-3 evaporation_transfer_coefficient = 1e-3 sensible_heat_transfer_coefficient = 1e-3 + vaporization_enthalpy = 2.5e-3 + + momentum_transfer_coefficient = convert(FT, momentum_transfer_coefficient) + evaporation_transfer_coefficient = convert(FT, evaporation_transfer_coefficient) + sensible_heat_transfer_coefficient = convert(FT, sensible_heat_transfer_coefficient) + vaporization_enthalpy = convert(FT, vaporization_enthalpy) τˣ = BulkFormula(RelativeUVelocity(), momentum_transfer_coefficient) τʸ = BulkFormula(RelativeVVelocity(), momentum_transfer_coefficient) momentum_flux_formulae = (u=τˣ, v=τʸ) - water_vapor_difference = WaterVaporFraction(FT) - evaporation = BulkFormula(WaterVaporFraction(FT), evaporation_transfer_coefficient) + water_specific_humidity_difference = SpecificHumidity(FT) + evaporation = nothing #BulkFormula(SpecificHumidity(FT), evaporation_transfer_coefficient) tracer_flux_formulae = (; S = evaporation) - vaporization_enthalpy = convert(FT, 2.5e-3) - latent_heat_difference = LatentHeat(vapor_difference = water_vapor_difference; vaporization_enthalpy) - latent_heat_formula = BulkFormula(latent_heat_difference, evaporation_transfer_coefficient) + latent_heat_difference = LatentHeat(specific_humidity_difference = water_specific_humidity_difference; vaporization_enthalpy) + latent_heat_formula = nothing #BulkFormula(latent_heat_difference, evaporation_transfer_coefficient) sensible_heat_formula = BulkFormula(SensibleHeat(), sensible_heat_transfer_coefficient) heat_flux_formulae = (sensible_heat_formula, latent_heat_formula) @@ -191,18 +196,18 @@ struct SensibleHeat end return @inbounds cₚ[i, j, 1] * ΔT end -struct WaterVaporFraction{S} - saturation_vapor_fraction :: S +struct SpecificHumidity{S} + saturation_specific_humidity :: S @doc """ - WaterVaporFraction(FT = Float64; - saturation_vapor_fraction = LargeYeagerSaturationVaporFraction(FT)) + SpecificHumidity(FT = Float64; + saturation_specific_humidity = LargeYeagerSaturationVaporFraction(FT)) """ - function WaterVaporFraction(FT = Float64; - saturation_vapor_fraction = LargeYeagerSaturationVaporFraction(FT)) - S = typeof(saturation_vapor_fraction) - return new{S}(saturation_vapor_fraction) + function SpecificHumidity(FT = Float64; + saturation_specific_humidity = LargeYeagerSaturationVaporFraction(FT)) + S = typeof(saturation_specific_humidity) + return new{S}(saturation_specific_humidity) end end @@ -222,18 +227,18 @@ end """ function LargeYeagerSaturationVaporFraction(FT = Float64; - q₀ = 0.98, - c₁ = 640380, - c₂ = -5107.4, - reference_temperature = 273.15) + q₀ = 0.98, + c₁ = 640380, + c₂ = -5107.4, + reference_temperature = 273.15) return LargeYeagerSaturationVaporFraction(convert(FT, q₀), - convert(FT, c₁), - convert(FT, c₂), - convert(FT, reference_temperature)) + convert(FT, c₁), + convert(FT, c₂), + convert(FT, reference_temperature)) end -@inline function saturation_vapor_fraction(i, j, grid, time, +@inline function saturation_specific_humidity(i, j, grid, time, ratio::LargeYeagerSaturationVaporFraction, atmos_state, ocean_state) @@ -247,34 +252,34 @@ end return q₀ * c₁ * exp(-c₂ / (Tₒ + Tᵣ)) end -@inline function air_sea_difference(i, j, grid, time, diff::WaterVaporFraction, atmos_state, ocean_state) - vapor_fraction = diff.saturation_vapor_fraction +@inline function air_sea_difference(i, j, grid, time, diff::SpecificHumidity, atmos_state, ocean_state) + vapor_fraction = diff.saturation_specific_humidity qₐ = stateindex(atmos_state.q, i, j, 1, time) - qₛ = saturation_vapor_fraction(i, j, grid, time, vapor_fraction, atmos_state, ocean_state) + qₛ = saturation_specific_humidity(i, j, grid, time, vapor_fraction, atmos_state, ocean_state) return qₐ - qₛ end struct LatentHeat{Q, FT} - vapor_difference :: Q + specific_humidity_difference :: Q vaporization_enthalpy :: FT end """ LatentHeat(FT = Float64; vaporization_enthalpy = 2.5e3 # J / g - vapor_difference = WaterVaporFraction(FT)) + specific_humidity_difference = SpecificHumidity(FT)) """ function LatentHeat(FT = Float64; vaporization_enthalpy = 2.5e3, # J / g - vapor_difference = WaterVaporFraction(FT)) + specific_humidity_difference = SpecificHumidity(FT)) vaporization_enthalpy = convert(FT, vaporization_enthalpy) - return LatentHeat(vapor_difference, vaporization_enthalpy) + return LatentHeat(specific_humidity_difference, vaporization_enthalpy) end @inline function air_sea_difference(i, j, grid, time, diff::LatentHeat, atmos, ocean) - Δq = air_sea_difference(i, j, grid, time, diff.vapor_difference, atmos, ocean) + Δq = air_sea_difference(i, j, grid, time, diff.specific_humidity_difference, atmos, ocean) Λᵥ = diff.vaporization_enthalpy return Λᵥ * Δq end From cddd224811422c37dad78c3b5fb0cc36fb4d9083 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 5 Dec 2023 22:38:04 -0700 Subject: [PATCH 048/182] Introducing timings into omip script --- Manifest.toml | 6 +- examples/generate_atmos_dataset.jl | 18 ++ .../omip_ocean_component.jl | 2 +- .../omip_simulation.jl | 240 +++++++++--------- src/DataWrangling/JRA55.jl | 25 +- 5 files changed, 165 insertions(+), 126 deletions(-) create mode 100644 examples/generate_atmos_dataset.jl diff --git a/Manifest.toml b/Manifest.toml index 84f4f741..80705084 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -695,9 +695,11 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "7ef7083f3fb79f225c50716bee81265c626ff98d" +git-tree-sha1 = "347699e4ab2d8c401dbe743b4f94579bd8274a7c" +repo-rev = "glw/better-interpolate2" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.1" +version = "0.90.2" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" diff --git a/examples/generate_atmos_dataset.jl b/examples/generate_atmos_dataset.jl new file mode 100644 index 00000000..b4e395bd --- /dev/null +++ b/examples/generate_atmos_dataset.jl @@ -0,0 +1,18 @@ +using ClimaOcean +using Oceananigans +using JLD2 + +time_indices = 1:1 + +qt = ClimaOcean.JRA55.jra55_field_time_series(:specific_humidity; time_indices) +Tt = ClimaOcean.JRA55.jra55_field_time_series(:temperature; time_indices) +pt = ClimaOcean.JRA55.jra55_field_time_series(:sea_level_pressure; time_indices) + +Nx, Ny, Nz = size(qt[1]) + +q = Array(interior(qt[1], 1:4:Nx, 1:4:Ny, 1)) +T = Array(interior(Tt[1], 1:4:Nx, 1:4:Ny, 1)) +p = Array(interior(pt[1], 1:4:Nx, 1:4:Ny, 1)) + +@save "atmospheric_state.jld2" q T p + diff --git a/experiments/prototype_omip_simulation/omip_ocean_component.jl b/experiments/prototype_omip_simulation/omip_ocean_component.jl index f0bb43d6..d911bf75 100644 --- a/experiments/prototype_omip_simulation/omip_ocean_component.jl +++ b/experiments/prototype_omip_simulation/omip_ocean_component.jl @@ -31,5 +31,5 @@ ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, boundary_conditions = ocean_boundary_conditions, coriolis = HydrostaticSphericalCoriolis()) -#set!(ocean_model, T=Tᵢ, S=Sᵢ) ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) + diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 4b16a142..aeb04a44 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -23,6 +23,8 @@ using Printf using Downloads: download +start_time = time_ns() + temperature_filename = "THETA.1440x720x50.19920102.nc" salinity_filename = "SALT.1440x720x50.19920102.nc" ice_thickness_filename = "SIheff.1440x720.19920102.nc" @@ -63,6 +65,10 @@ Sᵢ = salinity_ds["SALT"][:, :, :, 1] Nx, Ny′, Nz = size(Tᵢ) +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + ##### ##### Construct the grid ##### @@ -110,21 +116,44 @@ grid = LatitudeLongitudeGrid(arch, grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) +elapsed = time_ns() - start_time +@info "Grid constructed including evaluation of bottom height from initial condition data. " * + prettytime(elapsed * 1e-9) +start_time = time_ns() + # Defines `ocean`, an `Oceananigans.Simulation` include("omip_ocean_component.jl") +elapsed = time_ns() - start_time +@info "Ocean component built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +ocean_model.clock.time = 0 +ocean_model.clock.iteration = 0 +set!(ocean_model, T=Tᵢ, S=Sᵢ, e=1e-6) + # Defines `sea_ice`, an `Oceananigans.Simulation` include("omip_sea_ice_component.jl") +elapsed = time_ns() - start_time +@info "Sea ice component built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + # Defines `atmosphere`, a `ClimaOcean.OceanSeaIceModels.PrescribedAtmosphere` # also defines `radiation`, a `ClimaOcean.OceanSeaIceModels.Radiation` include("omip_atmosphere.jl") -set!(ocean_model, T=Tᵢ, S=Sᵢ) +elapsed = time_ns() - start_time +@info "Atmosphere built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() surface_radiation = SurfaceRadiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, surface_radiation) -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=20) +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) + +elapsed = time_ns() - start_time +@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() adjust_ice_covered_ocean_temperature!(coupled_model) @@ -147,159 +176,134 @@ function progress(sim) @info msg1 * msg2 * msg3 end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) using Oceananigans.Operators: ζ₃ᶠᶠᶜ u, v, w = ocean_model.velocities ζ = KernelFunctionOperation{Face, Face, Center}(ζ₃ᶠᶠᶜ, grid, u, v) +a = @at (Center, Center, Center) (u^2 + v^2) / 2 ℋ = sea_ice_model.ice_thickness -τˣ = coupled_model.surfaces.ocean.momentum.u -τʸ = coupled_model.surfaces.ocean.momentum.v -Jᵀ = coupled_model.surfaces.ocean.tracers.T -F = coupled_model.surfaces.ocean.tracers.S -fluxes = (; τˣ, τʸ, Jᵀ, F) -outputs = merge(ocean_model.velocities, ocean_model.tracers, fluxes, (; ζ, ℋ)) -filename = "omip_surface_fields.jld2" - -coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outputs; filename, - schedule = TimeInterval(1day), - indices = (:, :, Nz), - overwrite_existing = true) - -run!(coupled_simulation) - -fig = Figure(resolution=(2400, 1200)) - -axx = Axis(fig[1, 1]) -axy = Axis(fig[2, 1]) -axQ = Axis(fig[3, 1]) -axF = Axis(fig[4, 1]) - -τˣ = coupled_model.surfaces.ocean.momentum.u -τʸ = coupled_model.surfaces.ocean.momentum.v +# Build flux outputs +Jᵘ = coupled_model.surfaces.ocean.momentum.u +Jᵛ = coupled_model.surfaces.ocean.momentum.v Jᵀ = coupled_model.surfaces.ocean.tracers.T -F = coupled_model.surfaces.ocean.tracers.S - +F = coupled_model.surfaces.ocean.tracers.S ρₒ = coupled_model.ocean_reference_density cₚ = coupled_model.ocean_heat_capacity -Q = Field(ρₒ * cₚ * Jᵀ) -compute!(Q) - -λf, φc, zc = nodes(τˣ) -λc, φf, zc = nodes(τʸ) -λc, φc, zc = nodes(Q) - -τˣ = interior(τˣ, :, :, 1) -τʸ = interior(τʸ, :, :, 1) -Q = interior(Q, :, :, 1) -F = interior(F, :, :, 1) - -Qmax = maximum(abs, Q) -τmax = 1.0 #max(maximum(abs, τˣ), maximum(abs, τʸ)) -Fmax = 1e-4 #maximum(abs, F) - -τlim = 3τmax / 4 -Qlim = 3Qmax / 4 -Flim = 3Fmax / 4 -land = Q .== 0 -Q[land] .= NaN -F[land] .= NaN +Q = ρₒ * cₚ * Jᵀ +τˣ = ρₒ * Jᵘ +τʸ = ρₒ * Jᵛ -land = τˣ .== 0 -τˣ[land] .= NaN +fluxes = (; τˣ, τʸ, Q, F) -land = τʸ .== 0 -τʸ[land] .= NaN +fields = merge(ocean_model.velocities, ocean_model.tracers, + (; ζ = Field(ζ), ℋ )) -hmx = heatmap!(axx, λf, φc, ρₒ .* τˣ, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) -hmy = heatmap!(axy, λc, φf, ρₒ .* τʸ, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) -hmQ = heatmap!(axQ, λc, φc, Q, colorrange=(-Qlim, Qlim), colormap=:balance, nan_color=:gray) -hmF = heatmap!(axF, λc, φc, F, colorrange=(-Flim, Flim), colormap=:balance, nan_color=:gray) +# Slice fields at the surface +#fields = NamedTuple(name => view(fields[name], :, :, Nz) for name in keys(fields)) +outputs = merge(fields, fluxes) -Colorbar(fig[1, 2], hmx, label="Eastward momentum flux (N m⁻²)") -Colorbar(fig[2, 2], hmy, label="Northward momentum flux (N m⁻²)") -Colorbar(fig[3, 2], hmQ, label="Heat flux (W m⁻²)") -Colorbar(fig[4, 2], hmF, label="Salt flux (m s⁻¹ psu)") +filename = "omip_surface_fields.jld2" -display(fig) +coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outputs; filename, + #schedule = TimeInterval(1day), + schedule = IterationInterval(1), + indices = (:, :, Nz), + overwrite_existing = true) -#= -##### -##### Visualize -##### +run!(coupled_simulation) -using Oceananigans -using GLMakie -filename = "omip_surface_fields.jld2" +τˣt = FieldTimeSeries(filename, "τˣ") +τʸt = FieldTimeSeries(filename, "τʸ") +Qt = FieldTimeSeries(filename, "Q") +Ft = FieldTimeSeries(filename, "F") Tt = FieldTimeSeries(filename, "T") St = FieldTimeSeries(filename, "S") et = FieldTimeSeries(filename, "e") -ℋt = FieldTimeSeries(filename, "ℋ") ζt = FieldTimeSeries(filename, "ζ") -land = interior(Tt[1], :, :, 1) .== 0 -mask = [1 + ℓ * NaN for ℓ in land] +function nan_land!(ψt) + Nt = length(ψt.times) + land = interior(ψt[1], :, :, 1) .== 0 + for n = 2:Nt + ψn = interior(ψt[n], :, :, 1) + ψn[land] .= NaN + end + return nothing +end + +for ψt in (τˣt, τʸt, Qt, Ft, Tt, St, et, ζt) + nan_land!(ψt) +end -grid = Tt.grid -λ, φ, z = nodes(Tt) -h = interior(grid.immersed_boundary.bottom_height, :, :, 1) -h .*= mask -times = Tt.times -Nt = length(times) +λf, φc, zc = nodes(τˣt) +λc, φf, zc = nodes(τʸt) +λc, φc, zc = nodes(Qt) +λf, φf, zc = nodes(ζt) fig = Figure(resolution=(2400, 1200)) -axT = Axis(fig[1, 2], title="Temperature") -axS = Axis(fig[2, 2], title="Salinity") -axh = Axis(fig[3, 2], title="Bottom height") -axe = Axis(fig[1, 3], title="Turbulent kinetic energy") -axZ = Axis(fig[2, 3], title="Vorticity") -axℋ = Axis(fig[3, 3], title="Ice thickness") +Nt = length(Tt.times) +slider = Slider(fig[5, 2:3], range=1:Nt, startvalue=1) +n = slider.value #Observable(1) -slider = Slider(fig[4, 2:3], range=1:Nt, startvalue=1) -n = slider.value +τˣn = @lift interior(τˣt[$n], :, :, 1) +τʸn = @lift interior(τʸt[$n], :, :, 1) +Qn = @lift interior(Qt[$n], :, :, 1) +Fn = @lift interior(Ft[$n], :, :, 1) -title = @lift string("OMIP simulation ", prettytime(times[$n]), " after Jan 1 1992") -Label(fig[0, 2:3], title) +Tn = @lift interior(Tt[$n], :, :, 1) +Sn = @lift interior(St[$n], :, :, 1) +en = @lift interior(et[$n], :, :, 1) +ζn = @lift interior(ζt[$n], :, :, 1) -Tn = @lift mask .* interior(Tt[$n], :, :, 1) -Sn = @lift mask .* interior(St[$n], :, :, 1) -en = @lift mask .* interior(et[$n], :, :, 1) -ζn = @lift interior(ζt[$n], :, :, 1) -ℋn = @lift mask .* interior(ℋt[$n], :, :, 1) -Δℋn = @lift mask .* (interior(ℋt[$n], :, :, 1) .- interior(ℋt[1], :, :, 1)) +Qmax = 1000 +τmax = 1.0 +Fmax = 1e-4 -hm = heatmap!(axT, λ, φ, Tn, nan_color=:gray, colorrange=(-1, 25), colormap=:thermal) -Colorbar(fig[1, 1], hm, flipaxis=false) +Tmax = 32 +Tmin = -2 +Smax = 35 +Smin = 20 +elim = 1e-2 +ζlim = 1e-4 -hm = heatmap!(axS, λ, φ, Sn, nan_color=:gray, colorrange=(28, 35), colormap=:haline) -Colorbar(fig[2, 1], hm, flipaxis=false) +τlim = 3τmax / 4 +Qlim = 3Qmax / 4 +Flim = 3Fmax / 4 -hm = heatmap!(axh, λ, φ, h, nan_color=:gray, colormap=:viridis) -Colorbar(fig[3, 1], hm, flipaxis=false) +axx = Axis(fig[1, 2]) +axy = Axis(fig[2, 2]) +axQ = Axis(fig[3, 2]) +axF = Axis(fig[4, 2]) -hm = heatmap!(axe, λ, φ, en, nan_color=:gray, colorrange=(0, 2e-6), colormap=:solar) -Colorbar(fig[1, 4], hm) +axT = Axis(fig[1, 3]) +axS = Axis(fig[2, 3]) +axe = Axis(fig[3, 3]) +axz = Axis(fig[4, 3]) -hm = heatmap!(axZ, λ, φ, ζn, nan_color=:gray, colorrange=(-2e-5, 2e-5), colormap=:redblue) -Colorbar(fig[2, 4], hm) +hmx = heatmap!(axx, λf, φc, τˣn, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) +hmy = heatmap!(axy, λc, φf, τʸn, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) +hmQ = heatmap!(axQ, λc, φc, Qn, colorrange=(-Qlim, Qlim), colormap=:balance, nan_color=:gray) +hmF = heatmap!(axF, λc, φc, Fn, colorrange=(-Flim, Flim), colormap=:balance, nan_color=:gray) -hm = heatmap!(axℋ, λ, φ, ℋn, nan_color=:gray, colorrange=(0, 1), colormap=:blues) -Colorbar(fig[3, 4], hm) +Colorbar(fig[1, 1], hmx, flipaxis=false, label="Eastward momentum flux (N m⁻²)") +Colorbar(fig[2, 1], hmy, flipaxis=false, label="Northward momentum flux (N m⁻²)") +Colorbar(fig[3, 1], hmQ, flipaxis=false, label="Heat flux (W m⁻²)") +Colorbar(fig[4, 1], hmF, flipaxis=false, label="Salt flux (m s⁻¹ psu)") -# hm = heatmap!(axℋ, λ, φ, Δℋn, nan_color=:gray, colorrange=(-0.5, 0.5), colormap=:balance) -# Colorbar(fig[3, 4], hm) +hmT = heatmap!(axT, λf, φc, Tn, colorrange=(Tmin, Tmax), colormap=:thermal, nan_color=:gray) +hmS = heatmap!(axS, λc, φf, Sn, colorrange=(Smin, Smax), colormap=:haline, nan_color=:gray) +hme = heatmap!(axe, λc, φc, en, colorrange=(0, elim), colormap=:solar, nan_color=:gray) +hmz = heatmap!(axz, λf, φf, ζn, colorrange=(-ζlim, ζlim), colormap=:balance, nan_color=:gray) -display(fig) +Colorbar(fig[1, 4], hmx, label="Temperature (ᵒC)") +Colorbar(fig[2, 4], hmy, label="Salinity (psu)") +Colorbar(fig[3, 4], hmQ, label="Turbulent kinetic energy (m² s⁻²)") +Colorbar(fig[4, 4], hmF, label="Vorticity (s⁻¹)") -#= -record(fig, "omip_simulation.mp4", 1:Nt, framerate=24) do nn - @info "Drawing frame $nn of $Nt..." - n[] = nn -end -=# +display(fig) -=# diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 3868e698..e42e6ad7 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -19,7 +19,7 @@ jra55_variable_names = (:freshwater_river_flux, :eastward_velocity, :northward_velocity) -file_names = Dict( +filenames = Dict( :freshwater_river_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers :freshwater_rain_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall :freshwater_snow_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall @@ -95,7 +95,7 @@ urls = Dict( architecture = CPU(), time_indices = :, url = urls[name], - filename = file_names[variable_name], + filename = filenames[variable_name], short_name = short_names[variable_name]) Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, @@ -145,9 +145,24 @@ Keyword arguments function jra55_field_time_series(variable_name; architecture = CPU(), time_indices = :, - url = urls[variable_name], - filename = file_names[variable_name], - short_name = short_names[variable_name]) + url = nothing, + filename = nothing, + short_name = nothing) + + if isnothing(filename) && !(variable_name ∈ jra55_variable_names) + variable_strs = Tuple(" - :$name \n" for name in jra55_variable_names) + variables_msg = prod(variable_strs) + + msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', + "The variables provided by the JRA55-do dataset are:", '\n', + variables_msg) + + throw(ArgumentError(msg)) + end + + isnothing(url) && (url = urls[variable_name]) + isnothing(filename) && (filename = filenames[variable_name]) + isnothing(short_name) && (short_name = short_names[variable_name]) isfile(filename) || download(url, filename) From 21f54e10b867f5aa4606d044d65f6b12199dc310 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 6 Dec 2023 01:17:34 -0500 Subject: [PATCH 049/182] GPU-friendly copyto! --- src/DataWrangling/JRA55.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index e42e6ad7..b0731473 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -212,8 +212,8 @@ function jra55_field_time_series(variable_name; boundary_conditions = FieldBoundaryConditions(grid, (Center, Center, Nothing)) fts = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions) - # Fill the data - interior(fts, :, :, 1, :) .= data[:, :, :] + # Fill the data in a GPU-friendly manner + copyto!(interior(fts, :, :, 1, :), data[:, :, :]) # Fill halo regions so we can interpolate to finer grids Nt = length(times) From b155626d8b5f7d283c6c3293ff68e7e0b93ddaa5 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 12 Dec 2023 17:53:46 -0700 Subject: [PATCH 050/182] Its a lot of progress --- .../prototype_omip_simulation/ecco2_stuff.jl | 36 +++ .../omip_atmosphere.jl | 94 +++---- .../omip_simulation.jl | 4 + .../single_column_omip_ocean_component.jl | 50 ++++ .../single_column_omip_simulation.jl | 237 ++++++++++++++++++ src/ClimaOcean.jl | 2 +- src/DataWrangling/DataWrangling.jl | 2 + src/DataWrangling/ECCO2.jl | 136 ++++++++++ src/DataWrangling/JRA55.jl | 179 ++++++++++--- .../PrescribedAtmospheres.jl | 2 +- .../atmosphere_sea_ice_fluxes.jl | 4 +- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 9 +- src/OceanSimulations/OceanSimulations.jl | 81 ++++++ 13 files changed, 741 insertions(+), 95 deletions(-) create mode 100644 experiments/prototype_omip_simulation/ecco2_stuff.jl create mode 100644 experiments/prototype_omip_simulation/single_column_omip_ocean_component.jl create mode 100644 experiments/prototype_omip_simulation/single_column_omip_simulation.jl create mode 100644 src/DataWrangling/ECCO2.jl create mode 100644 src/OceanSimulations/OceanSimulations.jl diff --git a/experiments/prototype_omip_simulation/ecco2_stuff.jl b/experiments/prototype_omip_simulation/ecco2_stuff.jl new file mode 100644 index 00000000..6ef611de --- /dev/null +++ b/experiments/prototype_omip_simulation/ecco2_stuff.jl @@ -0,0 +1,36 @@ +temperature_filename = "THETA.1440x720x50.19920102.nc" +salinity_filename = "SALT.1440x720x50.19920102.nc" + +# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N +temperature_url = "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * + "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0" + +salinity_url = "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * + "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0" + +isfile(temperature_filename) || download(temperature_url, temperature_filename) +isfile(salinity_filename) || download(salinity_url, salinity_filename) + +temperature_ds = Dataset(temperature_filename) +salinity_ds = Dataset(salinity_filename) + +# Construct vertical coordinate +depth = temperature_ds["DEPTH_T"][:] +zc = -reverse(depth) + +# Interface depths from cell center depths +zf = (zc[1:end-1] .+ zc[2:end]) ./ 2 +push!(zf, 0) + +Δz = zc[2] - zc[1] +pushfirst!(zf, zf[1] - Δz) + +Tᵢ = temperature_ds["THETA"][:, :, :, 1] +Sᵢ = salinity_ds["SALT"][:, :, :, 1] + +Tᵢ = convert(Array{Float32, 3}, Tᵢ) +Sᵢ = convert(Array{Float32, 3}, Sᵢ) + +Tᵢ = reverse(Tᵢ, dims=3) +Sᵢ = reverse(Sᵢ, dims=3) + diff --git a/experiments/prototype_omip_simulation/omip_atmosphere.jl b/experiments/prototype_omip_simulation/omip_atmosphere.jl index 1db65447..b7bab00e 100644 --- a/experiments/prototype_omip_simulation/omip_atmosphere.jl +++ b/experiments/prototype_omip_simulation/omip_atmosphere.jl @@ -1,56 +1,40 @@ -##### -##### Setup JRA55 atmosphere -##### - -time_indices = 1:10 - -u_jra55_native = jra55_field_time_series(:eastward_velocity; time_indices, architecture=arch) -v_jra55_native = jra55_field_time_series(:northward_velocity; time_indices, architecture=arch) - -T_jra55_native = jra55_field_time_series(:temperature; time_indices, architecture=arch) -q_jra55_native = jra55_field_time_series(:relative_humidity; time_indices, architecture=arch) - -Fr_jra55_native = jra55_field_time_series(:freshwater_rain_flux; time_indices, architecture=arch) -Fs_jra55_native = jra55_field_time_series(:freshwater_snow_flux; time_indices, architecture=arch) -#Fv_jra55_native = jra55_field_time_series(:freshwater_river_flux; time_indices, architecture=arch) -#Fi_jra55_native = jra55_field_time_series(:freshwater_iceberg_flux; time_indices, architecture=arch) - -Qlw_jra55_native = jra55_field_time_series(:downwelling_longwave_radiation; time_indices, architecture=arch) -Qsw_jra55_native = jra55_field_time_series(:downwelling_shortwave_radiation; time_indices, architecture=arch) - -times = u_jra55_native.times - -u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing)) -v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing)) -c_bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing)) - -u_jra55 = FieldTimeSeries{Face, Center, Nothing}(grid, times; boundary_conditions=u_bcs) -v_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_conditions=v_bcs) -T_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -q_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Fr_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Fs_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Qlw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Qsw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) - -interpolate!(u_jra55, u_jra55_native) -interpolate!(v_jra55, v_jra55_native) -interpolate!(T_jra55, T_jra55_native) -interpolate!(q_jra55, q_jra55_native) -interpolate!(Fr_jra55, Fr_jra55_native) -interpolate!(Fs_jra55, Fs_jra55_native) -interpolate!(Qlw_jra55, Qlw_jra55_native) -interpolate!(Qsw_jra55, Qsw_jra55_native) - -velocities = (u = u_jra55, - v = v_jra55) - -tracers = (T = T_jra55, - q = q_jra55) - -freshwater_flux = (rain = Fr_jra55, - snow = Fs_jra55) - -downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qsw_jra55) -atmosphere = PrescribedAtmosphere(times; velocities, freshwater_flux, tracers, downwelling_radiation) +using Oceananigans.Fields: interpolate! +using ClimaOcean.JRA55: jra55_field_time_series + +using ClimaOcean.OceanSeaIceModels: + PrescribedAtmosphere, + TwoStreamDownwellingRadiation + +function prescribed_jra55_atmosphere(grid, time_indices=:) + architecture = Oceananigans.architecture(grid) + + u_jra55 = jra55_field_time_series(:eastward_velocity, grid; time_indices, architecture, location=(Face, Center)) + v_jra55 = jra55_field_time_series(:northward_velocity, grid; time_indices, architecture, location=(Center, Face)) + T_jra55 = jra55_field_time_series(:temperature, grid; time_indices, architecture) + q_jra55 = jra55_field_time_series(:specific_humidity, grid; time_indices, architecture) + Fr_jra55 = jra55_field_time_series(:freshwater_rain_flux, grid; time_indices, architecture) + Fs_jra55 = jra55_field_time_series(:freshwater_snow_flux, grid; time_indices, architecture) + Fv_jra55 = jra55_field_time_series(:freshwater_river_flux, grid; time_indices, architecture) + Fi_jra55 = jra55_field_time_series(:freshwater_iceberg_flux, grid; time_indices, architecture) + Qlw_jra55 = jra55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) + Qsw_jra55 = jra55_field_time_series(:downwelling_shortwave_radiation, grid; time_indices, architecture) + + times = u_jra55.times + + velocities = (u = u_jra55, + v = v_jra55) + + tracers = (T = T_jra55, + q = q_jra55) + + freshwater_flux = (rain = Fr_jra55, + snow = Fs_jra55, + rivers = Fv_jra55, + icebergs = Fi_jra55) + + downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qsw_jra55) + atmosphere = PrescribedAtmosphere(times; velocities, freshwater_flux, tracers, downwelling_radiation) + + return atmosphere +end diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index aeb04a44..3affb45e 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -28,6 +28,7 @@ start_time = time_ns() temperature_filename = "THETA.1440x720x50.19920102.nc" salinity_filename = "SALT.1440x720x50.19920102.nc" ice_thickness_filename = "SIheff.1440x720.19920102.nc" +#= # Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N @@ -214,6 +215,9 @@ coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outp overwrite_existing = true) run!(coupled_simulation) +=# + +filename = "omip_surface_fields.jld2" τˣt = FieldTimeSeries(filename, "τˣ") τʸt = FieldTimeSeries(filename, "τʸ") diff --git a/experiments/prototype_omip_simulation/single_column_omip_ocean_component.jl b/experiments/prototype_omip_simulation/single_column_omip_ocean_component.jl new file mode 100644 index 00000000..ebd6b56c --- /dev/null +++ b/experiments/prototype_omip_simulation/single_column_omip_ocean_component.jl @@ -0,0 +1,50 @@ +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: + CATKEVerticalDiffusivity, + MixingLength, + TurbulentKineticEnergyEquation + +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + +function omip_ocean_component(grid) + + top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) + top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) + top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) + top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(grid) + + ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), + T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) + + # Model construction + teos10 = TEOS10EquationOfState() + buoyancy = SeawaterBuoyancy(equation_of_state=teos10) + + Nx, Ny, Nz = size(grid) + + if Nx == Ny == 1 + tracer_advection = nothing + momentum_advection = nothing + else + tracer_advection = WENO() + momentum_advection = VectorInvariant(vorticity_scheme = WENO(), + divergence_scheme = WENO(), + vertical_scheme = WENO()) + end + + mixing_length = MixingLength(Cᵇ=0.01) + turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) + + ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, + tracer_advection, momentum_advection, + tracers = (:T, :S, :e), + free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), + boundary_conditions = ocean_boundary_conditions, + coriolis = HydrostaticSphericalCoriolis()) + + ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) + + return ocean +end diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl new file mode 100644 index 00000000..0577c347 --- /dev/null +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -0,0 +1,237 @@ +using Oceananigans +using Oceananigans.Units + +using ClimaOcean +using ClimaOcean.OceanSeaIceModels: SurfaceRadiation +using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +using NCDatasets +using GLMakie +using Printf + +using Downloads: download + +start_time = time_ns() + +include("single_column_omip_ocean_component.jl") + +Tᵢ = ecco2_field(:temperature) +Sᵢ = ecco2_field(:salinity) + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +z = znodes(Tᵢ) + +arch = CPU() + +Δ = 1/4 # resolution in degrees +φ₁ = -90 + Δ/2 +φ₂ = +90 - Δ/2 +λ₁ = 0 + Δ/2 +λ₂ = 360 - Δ/2 +φe = φ₁:Δ:φ₂ +λe = λ₁:Δ:λ₂ + +land = interior(Tᵢ) .< -10 +interior(Tᵢ)[land] .= NaN +interior(Sᵢ)[land] .= NaN + +Nz = size(Tᵢ, 3) +fig = Figure(resolution=(1200, 1200)) +map = Axis(fig[1, 1:2], xlabel="λ (degrees)", ylabel="φ (degrees)") +hm = heatmap!(map, λe, φe, interior(Tᵢ, :, :, Nz), colorrange=(0, 30), nan_color=:gray) +Colorbar(fig[1, 3], hm, label="Surface temperature (ᵒC)") + +axT = Axis(fig[2, 1], ylabel="z (m)", xlabel="Temperature (ᵒC)") +axS = Axis(fig[2, 2], ylabel="z (m)", xlabel="Salinity (psu)") + +φs = [50, 55, 0, -30] +λs = [215, 310, 210, 160] +Nc = length(φs) + +for n = 1:Nc + local φ★ + local λ★ + local i★ + local j★ + + φ★ = φs[n] + λ★ = λs[n] + + i★ = searchsortedfirst(λe, λ★) + j★ = searchsortedfirst(φe, φ★) + + scatter!(map, λ★, φ★, strokewidth=4, strokecolor=:black, + color=:pink, markersize=20) + + label = string("λ = ", λ★, ", φ = ", φ★) + scatterlines!(axT, interior(Tᵢ, i★, j★, :), z; label) + scatterlines!(axS, interior(Sᵢ, i★, j★, :), z; label) +end + +xlims!(axT, 0, 30) +xlims!(axS, 32, 36) +ylims!(axT, -2000, 30) +ylims!(axS, -2000, 30) +axislegend(axT, position=:rb) + +display(fig) + +φ★ = 50 # degrees latitude +λ★ = 180 + 35 # degrees longitude (?) + +i★ = searchsortedfirst(λe, λ★) +j★ = searchsortedfirst(φe, φ★) + +longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) +latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) + +# Column +Tc = interior(Tᵢ, i★:i★, j★:j★, :) +Sc = interior(Sᵢ, i★:i★, j★:j★, :) + +# Find bottom +zf = znodes(Tᵢ.grid, Face()) +kb = findlast(T -> T < -20, Tc[1, 1, :]) +km = findlast(z -> z < -2000, zf) +k★ = isnothing(kb) ? km : max(kb, km) + +Nz = size(Tc, 3) +kf = k★:Nz+1 +kc = k★:Nz +zf = zf[kf] +Tc = Tc[:, :, kc] +Sc = Sc[:, :, kc] +Nz′ = length(kc) + +grid = LatitudeLongitudeGrid(arch; longitude, latitude, + size = (1, 1, Nz′), + z = zf, + topology = (Periodic, Periodic, Bounded)) + +elapsed = time_ns() - start_time +@info "Grid constructed. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +ocean = omip_ocean_component(grid) +elapsed = time_ns() - start_time +@info "Ocean component built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +ocean.model.clock.time = 0 +ocean.model.clock.iteration = 0 +set!(ocean.model, T=Tc, S=Sc, e=1e-6) + +days = 30 +Nt = 8days +atmosphere = jra55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) +elapsed = time_ns() - start_time +@info "Atmosphere built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +times = ua.times + +fig = Figure() +axu = Axis(fig[1, 1]) +axT = Axis(fig[2, 1]) +axq = Axis(fig[3, 1]) + +lines!(axu, times ./ day, interior(ua, 1, 1, 1, :)) +lines!(axu, times ./ day, interior(va, 1, 1, 1, :)) +lines!(axT, times ./ day, interior(Ta, 1, 1, 1, :)) +lines!(axq, times ./ day, interior(qa, 1, 1, 1, :)) + +display(fig) + +sea_ice = nothing +surface_radiation = SurfaceRadiation() +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, surface_radiation) +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=30days) + +elapsed = time_ns() - start_time +@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +wall_clock = Ref(time_ns()) + +function progress(sim) + msg1 = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg2 = string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg3 = @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + e = sim.model.ocean.model.tracers.e + Nz = size(T, 3) + msg4 = @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) + msg5 = @sprintf(", S₀: %.2f psu", first(interior(S, 1, 1, Nz))) + msg6 = @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) + + @info msg1 * msg2 * msg3 * msg4 * msg5 * msg6 +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +# Build flux outputs +Jᵘ = coupled_model.surfaces.ocean.momentum.u +Jᵛ = coupled_model.surfaces.ocean.momentum.v +Jᵀ = coupled_model.surfaces.ocean.tracers.T +F = coupled_model.surfaces.ocean.tracers.S +ρₒ = coupled_model.ocean_reference_density +cₚ = coupled_model.ocean_heat_capacity + +Q = ρₒ * cₚ * Jᵀ +τˣ = ρₒ * Jᵘ +τʸ = ρₒ * Jᵛ + +fluxes = (; τˣ, τʸ, Q, F) +fields = merge(ocean.model.velocities, ocean.model.tracers) + +# Slice fields at the surface +outputs = merge(fields, fluxes) + +filename = "single_column_omip_surface_fields.jld2" + +coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean.model, outputs; filename, + schedule = TimeInterval(1hour), + overwrite_existing = true) + +run!(coupled_simulation) + +Tt = FieldTimeSeries(filename, "T") +St = FieldTimeSeries(filename, "S") +Qt = FieldTimeSeries(filename, "Q") +Ft = FieldTimeSeries(filename, "F") +τˣt = FieldTimeSeries(filename, "τˣ") +τʸt = FieldTimeSeries(filename, "τʸ") + +times = Qt.times + +fig = Figure() +axτ = Axis(fig[1, 1]) +axQ = Axis(fig[2, 1]) +axF = Axis(fig[3, 1]) + +lines!(axτ, times, interior(τˣt, 1, 1, 1, :)) +lines!(axτ, times, interior(τʸt, 1, 1, 1, :)) +lines!(axQ, times, interior(Qt, 1, 1, 1, :)) +lines!(axF, times, interior(Ft, 1, 1, 1, :)) + +display(fig) + diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index dfc29d8e..706477e5 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -60,13 +60,13 @@ end @inline u_immersed_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * spᶠᶜᶜ(i, j, k, grid, Φ) @inline v_immersed_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) +include("OceanSeaIceModels/OceanSeaIceModels.jl") include("VerticalGrids.jl") include("DataWrangling/DataWrangling.jl") include("Bathymetry.jl") include("InitialConditions.jl") include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") -include("OceanSeaIceModels/OceanSeaIceModels.jl") using .DataWrangling: JRA55 using .OceanSeaIceModels: OceanSeaIceModel diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index d008a8c5..9ccbc324 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -108,7 +108,9 @@ function save_field_time_series!(fts; path, name, overwrite_existing=false) end include("JRA55.jl") +include("ECCO2.jl") using .JRA55 +using .ECCO2 end # module diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl new file mode 100644 index 00000000..11f398de --- /dev/null +++ b/src/DataWrangling/ECCO2.jl @@ -0,0 +1,136 @@ +module ECCO2 + +using Oceananigans +using Oceananigans.BoundaryConditions: fill_halo_regions! + +using NCDatasets + +const ECCO2_Nx = 1440 +const ECCO2_Ny = 720 +const ECCO2_Nz = 50 + +# Vertical coordinate +const ECCO2_z = [ + -6128.75, + -5683.75, + -5250.25, + -4839.75, + -4452.25, + -4087.75, + -3746.25, + -3427.75, + -3132.25, + -2859.75, + -2610.25, + -2383.74, + -2180.13, + -1999.09, + -1839.64, + -1699.66, + -1575.64, + -1463.12, + -1357.68, + -1255.87, + -1155.72, + -1056.53, + -958.45, + -862.10, + -768.43, + -678.57, + -593.72, + -515.09, + -443.70, + -380.30, + -325.30, + -278.70, + -240.09, + -208.72, + -183.57, + -163.43, + -147.11, + -133.45, + -121.51, + -110.59, + -100.20, + -90.06, + -80.01, + -70.0, + -60.0, + -50.0, + -40.0, + -30.0, + -20.0, + -10.0, + 0.0, +] + +filenames = Dict( + :temperature => "THETA.1440x720x50.19920102.nc", + :salinity => "SALT.1440x720x50.19920102.nc", + :sea_ice_thickness => "SIheff.1440x720.19920102.nc", +) + +shortnames = Dict( + :temperature => "THETA", + :salinity => "SALT", + :sea_ice_thickness => "SIheff", +) + +depthnames = Dict( + :temperature => "DEPTH_T", + :salinity => "DEPTH_S", + :sea_ice_thickness => nothing, +) + +# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N +# These files are just for Jan 2, 1992. +urls = Dict( + :temperature => "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * + "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0", + + :salinity => "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * + "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0", + + :sea_ice_thickness => "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/" * + "SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am&dl=0", +) + +surface_variable(variable_name) = variable_name == :sea_ice_thickness + +function ecco2_field(variable_name; + architecture = CPU(), + filename = filenames[variable_name], + shortname = shortnames[variable_name], + depthname = depthnames[variable_name], + url = urls[variable_name]) + + isfile(filename) || download(url, filename) + + ds = Dataset(filename) + + grid = LatitudeLongitudeGrid(architecture, + size = (ECCO2_Nx, ECCO2_Ny, ECCO2_Nz), + longitude = (0, 360), + latitude = (-90, 90), + z = ECCO2_z, + halo = (1, 1, 1), + topology = (Periodic, Bounded, Bounded)) + + if surface_variable(variable_name) + field = Field{Center, Center, Nothing}(grid) + data = ds[shortname][:, :, 1] + data = convert(Array{Float32, 2}, data) + else + field = CenterField(grid) # u, v not supported + data = ds[shortname][:, :, :, 1] + data = convert(Array{Float32, 3}, data) + data = reverse(data, dims=3) + end + + set!(field, data) + fill_halo_regions!(field) + + return field +end + +end # module diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index e42e6ad7..d8612279 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -2,7 +2,15 @@ module JRA55 using Oceananigans using Oceananigans.Units + using Oceananigans.BoundaryConditions: fill_halo_regions! +using Oceananigans.Grids: λnodes, φnodes +using Oceananigans.Fields: interpolate! + +using ClimaOcean.OceanSeaIceModels: + PrescribedAtmosphere, + TwoStreamDownwellingRadiation + using NCDatasets # A list of all variables provided in the JRA55 dataset: @@ -34,7 +42,7 @@ filenames = Dict( :northward_velocity => "RYF.vas.1990_1991.nc", # Northward near-surface wind ) -short_names = Dict( +shortnames = Dict( :freshwater_river_flux => "friver", # Freshwater fluxes from rivers :freshwater_rain_flux => "prra", # Freshwater flux from rainfall :freshwater_snow_flux => "prsn", # Freshwater flux from snowfall @@ -96,7 +104,7 @@ urls = Dict( time_indices = :, url = urls[name], filename = filenames[variable_name], - short_name = short_names[variable_name]) + shortname = shortnames[variable_name]) Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, which describes one of the variables in the "repeat year forcing" dataset derived @@ -106,7 +114,7 @@ For more information about the derivation of the repeat year forcing dataset, se "Stewart et al., JRA55-do-based repeat year forcing datasets for driving ocean–sea-ice models", Ocean Modelling, 2020, https://doi.org/10.1016/j.ocemod.2019.101557. -The `variable_name`s (and their `short_name`s used in NetCDF files) +The `variable_name`s (and their `shortname`s used in NetCDF files) available from the JRA55-do are: - `:freshwater_river_flux` ("friver") @@ -139,15 +147,16 @@ Keyword arguments - `filename`: The name of the downloaded file. Default: `ClimaOcean.JRA55.filenames[variable_name]`. - - `short_name`: The "short name" of `variable_name` inside its NetCDF file. - Default: `ClimaOcean.JRA55.short_names[variable_name]`. + - `shortname`: The "short name" of `variable_name` inside its NetCDF file. + Default: `ClimaOcean.JRA55.shortnames[variable_name]`. """ -function jra55_field_time_series(variable_name; +function jra55_field_time_series(variable_name, grid=nothing; architecture = CPU(), + location = nothing, time_indices = :, url = nothing, filename = nothing, - short_name = nothing) + shortname = nothing) if isnothing(filename) && !(variable_name ∈ jra55_variable_names) variable_strs = Tuple(" - :$name \n" for name in jra55_variable_names) @@ -160,12 +169,19 @@ function jra55_field_time_series(variable_name; throw(ArgumentError(msg)) end - isnothing(url) && (url = urls[variable_name]) - isnothing(filename) && (filename = filenames[variable_name]) - isnothing(short_name) && (short_name = short_names[variable_name]) + isnothing(url) && (url = urls[variable_name]) + isnothing(filename) && (filename = filenames[variable_name]) + isnothing(shortname) && (shortname = shortnames[variable_name]) isfile(filename) || download(url, filename) + # Get location + if isnothing(location) + LX = LY = Center + else + LX, LY = location + end + ds = Dataset(filename) # Note that each file should have the variables @@ -174,53 +190,148 @@ function jra55_field_time_series(variable_name; # ds["lat"]: latitude at the location of the variable # ds["lon_bnds"]: bounding longitudes between which variables are averaged # ds["lat_bnds"]: bounding latitudes between which variables are averaged - # ds[short_name]: the variable data + # ds[shortname]: the variable data - # Extract variable data - data = ds[short_name][:, :, time_indices] + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] - # Make the JRA55 grid - λ = ds["lon_bnds"][1, :] - φ = ds["lat_bnds"][1, :] - times = ds["time"][time_indices] - - close(ds) + # Interfaces for the "native" JRA55 grid + λn = ds["lon_bnds"][1, :] + φn = ds["lat_bnds"][1, :] # The .nc coordinates lon_bnds and lat_bnds do not include # the last interface, so we push them here. - push!(φ, 90) - push!(λ, λ[1] + 360) + push!(φn, 90) + push!(λn, λn[1] + 360) + + times = ds["time"][time_indices] - Nx = length(λ) - 1 - Ny = length(φ) - 1 + Nx = length(λc) + Ny = length(φc) + + if isnothing(grid) + i₁, i₂ = (1, Nx) + j₁, j₂ = (1, Ny) + TX = Periodic + else # only load the data we need + # Nodes where we need to find data + λg = λnodes(grid, LX()) + φg = φnodes(grid, LY()) + + λ₁, λ₂ = extrema(λg) + φ₁, φ₂ = extrema(φg) + + # The following should work. If ᵒ are the extrema of nodes we want to + # interpolate to, and the following is a sketch of the JRA55 native grid, + # + # 1 2 3 4 5 + # | | | | | | + # | x ᵒ | x | x | x ᵒ | x | + # | | | | | | + # 1 2 3 4 5 6 + # + # then for example, we should find that (iᵢ, i₂) = (1, 5). + # So we want to reduce the first index by one, and limit them + # both by the available data. There could be some mismatch due + # to the use of different coordinate systems (ie whether λ ∈ (0, 360) + # which we may also need to handle separately. + + i₁ = searchsortedfirst(λc, λ₁) + j₁ = searchsortedfirst(φc, φ₁) + + i₂ = searchsortedfirst(λc, λ₂) + j₂ = searchsortedfirst(φc, φ₂) + + i₁ = max(1, i₁ - 1) + j₁ = max(1, j₁ - 1) + + i₂ = min(Nx, i₂) + j₂ = min(Ny, j₂) + + TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded + end - grid = LatitudeLongitudeGrid(architecture, - size = (Nx, Ny); - longitude = λ, - latitude = φ, - topology = (Periodic, Bounded, Flat)) + # Extract variable data + data = ds[shortname][i₁:i₂, j₁:j₂, time_indices] + λr = λn[i₁:i₂+1] + φr = φn[j₁:j₂+1] + Nrx, Nry, Nt = size(data) + + close(ds) # Hack together the `times` for the JRA55 dataset we are currently using. # We might want to use the acutal dates instead though. - # So the following code maybe should change. + # So the following code might need to change. Δt = 3hours # just what it is Nt = length(times) start_time = 0 # Note: the forcing start at Jan 1 of the repeat year. stop_time = Δt * (Nt - 1) times = start_time:Δt:stop_time - boundary_conditions = FieldBoundaryConditions(grid, (Center, Center, Nothing)) - fts = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions) + jra55_native_grid = LatitudeLongitudeGrid(architecture, + size = (Nrx, Nry); + longitude = λr, + latitude = φr, + topology = (TX, Bounded, Flat)) + + boundary_conditions = FieldBoundaryConditions(jra55_native_grid, (Center, Center, Nothing)) + native_fts = FieldTimeSeries{Center, Center, Nothing}(jra55_native_grid, times; boundary_conditions) # Fill the data - interior(fts, :, :, 1, :) .= data[:, :, :] + copyto!(interior(native_fts, :, :, 1, :), data[:, :, :]) # Fill halo regions so we can interpolate to finer grids Nt = length(times) - fill_halo_regions!(fts) + fill_halo_regions!(native_fts) + + if isnothing(grid) + return native_fts + else # make a new FieldTimeSeries and interpolate native data onto it. + + boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) + fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; boundary_conditions) + + interpolate!(fts, native_fts) + + return fts + end +end + +# TODO: allow the user to pass dates +function jra55_prescribed_atmosphere(grid, time_indices=:) + architecture = Oceananigans.architecture(grid) + + u_jra55 = jra55_field_time_series(:eastward_velocity, grid; time_indices, architecture, location=(Face, Center)) + v_jra55 = jra55_field_time_series(:northward_velocity, grid; time_indices, architecture, location=(Center, Face)) + T_jra55 = jra55_field_time_series(:temperature, grid; time_indices, architecture) + q_jra55 = jra55_field_time_series(:specific_humidity, grid; time_indices, architecture) + Fr_jra55 = jra55_field_time_series(:freshwater_rain_flux, grid; time_indices, architecture) + Fs_jra55 = jra55_field_time_series(:freshwater_snow_flux, grid; time_indices, architecture) + Fv_jra55 = jra55_field_time_series(:freshwater_river_flux, grid; time_indices, architecture) + Fi_jra55 = jra55_field_time_series(:freshwater_iceberg_flux, grid; time_indices, architecture) + Qlw_jra55 = jra55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) + Qsw_jra55 = jra55_field_time_series(:downwelling_shortwave_radiation, grid; time_indices, architecture) + + times = u_jra55.times + + velocities = (u = u_jra55, + v = v_jra55) + + tracers = (T = T_jra55, + q = q_jra55) + + freshwater_flux = (rain = Fr_jra55, + snow = Fs_jra55, + rivers = Fv_jra55, + icebergs = Fi_jra55) + + downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qsw_jra55) + atmosphere = PrescribedAtmosphere(times; velocities, freshwater_flux, tracers, downwelling_radiation) - return fts + return atmosphere end + end # module diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 92768ea5..91447710 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -61,6 +61,6 @@ or sea ice. """ TwoStreamDownwellingRadiation(; shortwave=nothing, longwave=nothing) = TwoStreamDownwellingRadiation(shortwave, longwave) - + end # module diff --git a/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl index 444360d5..5035e0f4 100644 --- a/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl +++ b/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl @@ -1,6 +1,6 @@ using ClimaSeaIce: SlabSeaIceModel -sea_ice_thickness(sea_ice::Simulation{<:SlabSeaIceModel}) = - sea_ice.model.ice_thickness +sea_ice_thickness(sea_ice::Simulation{<:SlabSeaIceModel}) = sea_ice.model.ice_thickness +sea_ice_thickness(::Nothing) = nothing # Nothing yet... diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index cfd1cb5c..ce1e632d 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -52,8 +52,13 @@ function OceanSeaIceModel(ocean, sea_ice=nothing; ocean_heat_capacity = heat_capacity(ocean), clock = deepcopy(ocean.model.clock)) - previous_ice_thickness = deepcopy(sea_ice.model.ice_thickness) - previous_ice_concentration = deepcopy(sea_ice.model.ice_concentration) + if isnothing(sea_ice) + previous_ice_thickness = nothing + previous_ice_concentration = nothing + else + previous_ice_thickness = deepcopy(sea_ice.model.ice_thickness) + previous_ice_concentration = deepcopy(sea_ice.model.ice_concentration) + end grid = ocean.model.grid ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl new file mode 100644 index 00000000..5e995a45 --- /dev/null +++ b/src/OceanSimulations/OceanSimulations.jl @@ -0,0 +1,81 @@ +module OceanSimulations + +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: + CATKEVerticalDiffusivity, + MixingLength, + TurbulentKineticEnergyEquation + +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + +using Oceananigans.BuoyancyModels: g_Earth +using Oceananigans.Coriolis: Ω_Earth + +# Some defualts +default_free_surface(grid) = SplitExplicitFreeSurface(cfl=0.7; grid) + +function default_ocean_closure() + mixing_length = MixingLength(Cᵇ=0.01) + turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + return CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) +end + +# TODO: Specify the grid to a grid on the sphere; otherwise we can provide a different +# function that requires latitude and longitude etc for computing coriolis=FPlane... +function ocean_simulation(grid; + closure = default_ocean_closure(), + free_surface = default_free_surface(grid), + reference_density = 1020, + rotation_rate = Ω_Earth, + gravitational_acceleration = g_Earth) + + # Set up boundary conditions using Field + top_zonal_momentum_flux = Jᵘ = Field{Face, Center, Nothing}(grid) + top_meridional_momentum_flux = Jᵛ = Field{Center, Face, Nothing}(grid) + top_ocean_heat_flux = Jᵀ = Field{Center, Center, Nothing}(grid) + top_salt_flux = Jˢ = Field{Center, Center, Nothing}(grid) + + ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵘ)), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵛ)), + T = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Jˢ))) + + # Use the TEOS10 equation of state + teos10 = TEOS10EquationOfState(; reference_density) + buoyancy = SeawaterBuoyancy(; gravitational_acceleration, equation_of_state=teos10) + + # Minor simplifications for single column grids + Nx, Ny, Nz = size(grid) + if Nx == Ny == 1 # single column grid + tracer_advection = nothing + momentum_advection = nothing + else + # TODO: better advection scheme + tracer_advection = WENO() + momentum_advection = VectorInvariant(vorticity_scheme = WENO(), + divergence_scheme = WENO(), + vertical_scheme = WENO()) + end + + tracers = (:T, :S) + if closure isa CATKEVerticalDiffusivity + tracers = tuple(tracers..., :e) + end + + coriolis = HydrostaticSphericalCoriolis(; rotation_rate) + + ocean_model = HydrostaticFreeSurfaceModel(; grid, + buoyancy, + closure, + tracer_advection, + momentum_advection, + tracers, + free_surface, + coriolis, + boundary_conditions = ocean_boundary_conditions) + + ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) + + return ocean +end + +end # module From 01c1a519dbac8d685c26a44c31997a85f42792ac Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 13 Dec 2023 11:14:45 -0700 Subject: [PATCH 051/182] Updates --- .../single_column_omip_simulation.jl | 139 ++++++++++++++---- src/DataWrangling/ECCO2.jl | 8 +- src/DataWrangling/JRA55.jl | 16 +- .../compute_atmosphere_ocean_fluxes.jl | 5 +- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 9 +- .../ocean_sea_ice_model_fluxes.jl | 35 +++-- 6 files changed, 162 insertions(+), 50 deletions(-) diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 0577c347..f687bdfd 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -19,6 +19,18 @@ include("single_column_omip_ocean_component.jl") Tᵢ = ecco2_field(:temperature) Sᵢ = ecco2_field(:salinity) +land = interior(Tᵢ) .< -10 +interior(Tᵢ)[land] .= NaN +interior(Sᵢ)[land] .= NaN + +using Oceananigans.BuoyancyModels: buoyancy_frequency +teos10 = TEOS10EquationOfState() +buoyancy = SeawaterBuoyancy(equation_of_state=teos10) +tracers = (T=Tᵢ, S=Sᵢ) +N²_op = buoyancy_frequency(buoyancy, Tᵢ.grid, tracers) +N² = Field(N²_op) +compute!(N²) + elapsed = time_ns() - start_time @info "Initial condition built. " * prettytime(elapsed * 1e-9) start_time = time_ns() @@ -27,7 +39,8 @@ start_time = time_ns() ##### Construct the grid ##### -z = znodes(Tᵢ) +zc = znodes(Tᵢ) +zf = znodes(N²) arch = CPU() @@ -39,21 +52,25 @@ arch = CPU() φe = φ₁:Δ:φ₂ λe = λ₁:Δ:λ₂ -land = interior(Tᵢ) .< -10 -interior(Tᵢ)[land] .= NaN -interior(Sᵢ)[land] .= NaN - Nz = size(Tᵢ, 3) fig = Figure(resolution=(1200, 1200)) -map = Axis(fig[1, 1:2], xlabel="λ (degrees)", ylabel="φ (degrees)") +map = Axis(fig[1, 1:3], xlabel="λ (degrees)", ylabel="φ (degrees)") hm = heatmap!(map, λe, φe, interior(Tᵢ, :, :, Nz), colorrange=(0, 30), nan_color=:gray) -Colorbar(fig[1, 3], hm, label="Surface temperature (ᵒC)") +Colorbar(fig[1, 4], hm, label="Surface temperature (ᵒC)") axT = Axis(fig[2, 1], ylabel="z (m)", xlabel="Temperature (ᵒC)") axS = Axis(fig[2, 2], ylabel="z (m)", xlabel="Salinity (psu)") +axN = Axis(fig[2, 3], ylabel="z (m)", xlabel="Buoyancy frequency (s⁻²)") + +φs = [50, 55, 0, -30, -65, 34] +λs = [215, 310, 210, 160, 160, 34] + +λs = [34, 33, 5, 20, 30] +φs = [34, 32, 38, 35, 33] + +#φs = [-30] +#s = [160] -φs = [50, 55, 0, -30] -λs = [215, 310, 210, 160] Nc = length(φs) for n = 1:Nc @@ -72,18 +89,20 @@ for n = 1:Nc color=:pink, markersize=20) label = string("λ = ", λ★, ", φ = ", φ★) - scatterlines!(axT, interior(Tᵢ, i★, j★, :), z; label) - scatterlines!(axS, interior(Sᵢ, i★, j★, :), z; label) + scatterlines!(axT, interior(Tᵢ, i★, j★, :), zc; label) + scatterlines!(axS, interior(Sᵢ, i★, j★, :), zc; label) + scatterlines!(axN, interior(N², i★, j★, :), zf; label) end -xlims!(axT, 0, 30) -xlims!(axS, 32, 36) +xlims!(axT, -2, 30) +xlims!(axS, 32, 40) ylims!(axT, -2000, 30) ylims!(axS, -2000, 30) axislegend(axT, position=:rb) display(fig) +#= φ★ = 50 # degrees latitude λ★ = 180 + 35 # degrees longitude (?) @@ -125,24 +144,24 @@ elapsed = time_ns() - start_time @info "Ocean component built. " * prettytime(elapsed * 1e-9) start_time = time_ns() -ocean.model.clock.time = 0 -ocean.model.clock.iteration = 0 -set!(ocean.model, T=Tc, S=Sc, e=1e-6) - -days = 30 -Nt = 8days +Ndays = 90 +Nt = 8 * Ndays atmosphere = jra55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() +ocean.model.clock.time = 0 +ocean.model.clock.iteration = 0 +set!(ocean.model, T=Tc, S=Sc, e=1e-6) + ua = atmosphere.velocities.u va = atmosphere.velocities.v Ta = atmosphere.tracers.T qa = atmosphere.tracers.q times = ua.times -fig = Figure() +fig = Figure(resolution=(1200, 1800)) axu = Axis(fig[1, 1]) axT = Axis(fig[2, 1]) axq = Axis(fig[3, 1]) @@ -157,7 +176,7 @@ display(fig) sea_ice = nothing surface_radiation = SurfaceRadiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, surface_radiation) -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=30days) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=30day) elapsed = time_ns() - start_time @info "Coupled simulation built. " * prettytime(elapsed * 1e-9) @@ -212,26 +231,92 @@ coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean.model, outp schedule = TimeInterval(1hour), overwrite_existing = true) +@show coupled_simulation.stop_time run!(coupled_simulation) Tt = FieldTimeSeries(filename, "T") +ut = FieldTimeSeries(filename, "u") +vt = FieldTimeSeries(filename, "v") St = FieldTimeSeries(filename, "S") Qt = FieldTimeSeries(filename, "Q") Ft = FieldTimeSeries(filename, "F") τˣt = FieldTimeSeries(filename, "τˣ") τʸt = FieldTimeSeries(filename, "τʸ") +Nz = size(Tt, 3) times = Qt.times -fig = Figure() -axτ = Axis(fig[1, 1]) -axQ = Axis(fig[2, 1]) -axF = Axis(fig[3, 1]) +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +Qlw = atmosphere.downwelling_radiation.longwave +Qsw = atmosphere.downwelling_radiation.shortwave + +using Oceananigans.Units: Time + +Nt = length(times) +uat = zeros(Nt) +vat = zeros(Nt) +Tat = zeros(Nt) +qat = zeros(Nt) +Qswt = zeros(Nt) +Qlwt = zeros(Nt) + +for n = 1:Nt + t = times[n] + uat[n] = ua[1, 1, 1, Time(t)] + vat[n] = va[1, 1, 1, Time(t)] + Tat[n] = Ta[1, 1, 1, Time(t)] + qat[n] = qa[1, 1, 1, Time(t)] + Qswt[n] = Qsw[1, 1, 1, Time(t)] + Qlwt[n] = Qlw[1, 1, 1, Time(t)] +end + +fig = Figure(resolution=(2400, 1800)) + +axu = Axis(fig[1, 1], xlabel="Time (days)", ylabel="Velocities (m s⁻¹)") +axτ = Axis(fig[2, 1], xlabel="Time (days)", ylabel="Wind stress (N m⁻²)") +axT = Axis(fig[3, 1], xlabel="Time (days)", ylabel="Temperature (K)") +axQ = Axis(fig[4, 1], xlabel="Time (days)", ylabel="Heat flux (W m⁻²)") +axF = Axis(fig[5, 1], xlabel="Time (days)", ylabel="Salt flux (...)") + +axTz = Axis(fig[1:5, 2], xlabel="Temperature (K)", ylabel="z (m)") +axSz = Axis(fig[1:5, 3], xlabel="Salinity (psu)", ylabel="z (m)") + +slider = Slider(fig[6, 1:3], range=1:Nt, startvalue=1) +n = slider.value + +tn = @lift times[$n] + +lines!(axu, times, uat, color=:royalblue) +lines!(axu, times, interior(ut, 1, 1, Nz, :), color=:royalblue, linestyle=:dash) +vlines!(axu, tn) + +lines!(axu, times, vat, color=:seagreen) +lines!(axu, times, interior(vt, 1, 1, Nz, :), color=:seagreen, linestyle=:dash) lines!(axτ, times, interior(τˣt, 1, 1, 1, :)) lines!(axτ, times, interior(τʸt, 1, 1, 1, :)) -lines!(axQ, times, interior(Qt, 1, 1, 1, :)) +vlines!(axτ, tn) + +lines!(axT, times, Tat, color=:royalblue) +lines!(axT, times, interior(Tt, 1, 1, Nz, :) .+ 273.15, color=:royalblue, linestyle=:dash) +vlines!(axT, tn) + +lines!(axQ, times, interior(Qt, 1, 1, 1, :), linestyle=:dash) +lines!(axQ, times, - Qswt, color=:seagreen, linewidth=3) +lines!(axQ, times, - Qlwt, color=:royalblue, linewidth=3) +vlines!(axQ, tn) + lines!(axF, times, interior(Ft, 1, 1, 1, :)) +vlines!(axF, tn) -display(fig) +z = znodes(Tt) +Tn = @lift interior(Tt[$n], 1, 1, :) +Sn = @lift interior(St[$n], 1, 1, :) +lines!(axTz, Tn, z) +lines!(axSz, Sn, z) +display(fig) +=# diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 11f398de..1fc4a7bc 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -5,6 +5,12 @@ using Oceananigans.BoundaryConditions: fill_halo_regions! using NCDatasets +# Data from +# +# https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N +# +# These files are just for Jan 2, 1992. + const ECCO2_Nx = 1440 const ECCO2_Ny = 720 const ECCO2_Nz = 50 @@ -82,8 +88,6 @@ depthnames = Dict( :sea_ice_thickness => nothing, ) -# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N -# These files are just for Jan 2, 1992. urls = Dict( :temperature => "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0", diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index b70b7b90..eb837644 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -308,11 +308,14 @@ function jra55_prescribed_atmosphere(grid, time_indices=:) q_jra55 = jra55_field_time_series(:specific_humidity, grid; time_indices, architecture) Fr_jra55 = jra55_field_time_series(:freshwater_rain_flux, grid; time_indices, architecture) Fs_jra55 = jra55_field_time_series(:freshwater_snow_flux, grid; time_indices, architecture) - Fv_jra55 = jra55_field_time_series(:freshwater_river_flux, grid; time_indices, architecture) - Fi_jra55 = jra55_field_time_series(:freshwater_iceberg_flux, grid; time_indices, architecture) Qlw_jra55 = jra55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) Qsw_jra55 = jra55_field_time_series(:downwelling_shortwave_radiation, grid; time_indices, architecture) + # NOTE: these have a different frequency than 3 hours so some changes are needed to + # jra55_field_time_series to support them. + # Fv_jra55 = jra55_field_time_series(:freshwater_river_flux, grid; time_indices, architecture) + # Fi_jra55 = jra55_field_time_series(:freshwater_iceberg_flux, grid; time_indices, architecture) + times = u_jra55.times velocities = (u = u_jra55, @@ -322,11 +325,12 @@ function jra55_prescribed_atmosphere(grid, time_indices=:) q = q_jra55) freshwater_flux = (rain = Fr_jra55, - snow = Fs_jra55, - rivers = Fv_jra55, - icebergs = Fi_jra55) + snow = Fs_jra55) + + # rivers = Fv_jra55, + # icebergs = Fi_jra55) - downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qsw_jra55) + downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qlw_jra55) atmosphere = PrescribedAtmosphere(times; velocities, freshwater_flux, tracers, downwelling_radiation) return atmosphere diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index 413743e6..4b6b34b0 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -139,15 +139,16 @@ end # Compute heat fluxes, bulk flux first Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, surface_radiation) + Qu = net_upwelling_radiation(i, j, grid, time, surface_radiation, ocean_state) - Q★ = cross_realm_flux(i, j, grid, time, Q_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) Q = Q★ + Qd + Qu + #Q = Qd + Qu # Compute salinity fluxes, bulk flux first Fp = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) F★ = cross_realm_flux(i, j, grid, time, F_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) - F = F★ + Fp + F = 0 #F★ + Fp # Then the rest of the heat fluxes ρₒ = ocean_reference_density diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index ce1e632d..5e1681af 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -89,10 +89,13 @@ end time(coupled_model::OceanSeaIceModel) = coupled_model.clock.time -function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=nothing) +function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean sea_ice = coupled_model.sea_ice + # Be paranoid and update state at iteration 0 + coupled_model.clock.iteration == 0 && update_state!(coupled_model, callbacks) + # Eventually, split out into OceanOnlyModel if !isnothing(sea_ice) h = sea_ice.model.ice_thickness @@ -120,13 +123,13 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=nothing) # TODO: # - Store fractional ice-free / ice-covered _time_ for more # accurate flux computation? - tick!(coupled_model.clock, Δt) + update_state!(coupled_model, callbacks; compute_tendencies) return nothing end -function update_state!(coupled_model::OceanSeaIceModel, callbacks=nothing) +function update_state!(coupled_model::OceanSeaIceModel, callbacks=[]; compute_tendencies=false) # update_model_field_time_series!(coupled_model.atmosphere) compute_atmosphere_ocean_fluxes!(coupled_model) # compute_atmosphere_sea_ice_fluxes!(coupled_model) diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl index ad2c3df7..05cf7f41 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl @@ -64,6 +64,8 @@ struct OceanSeaIceModelFluxes{U, R, AO, ASI, SIO} end function default_atmosphere_ocean_fluxes(FT=Float64, tracers=tuple(:S)) + # Note: we are constantly coping with the fact that the ocean is ᵒC. + ocean_reference_temperature = 273.15 momentum_transfer_coefficient = 1e-3 evaporation_transfer_coefficient = 1e-3 sensible_heat_transfer_coefficient = 1e-3 @@ -78,13 +80,16 @@ function default_atmosphere_ocean_fluxes(FT=Float64, tracers=tuple(:S)) τʸ = BulkFormula(RelativeVVelocity(), momentum_transfer_coefficient) momentum_flux_formulae = (u=τˣ, v=τʸ) + # Note: reference temperature comes in here water_specific_humidity_difference = SpecificHumidity(FT) evaporation = nothing #BulkFormula(SpecificHumidity(FT), evaporation_transfer_coefficient) tracer_flux_formulae = (; S = evaporation) latent_heat_difference = LatentHeat(specific_humidity_difference = water_specific_humidity_difference; vaporization_enthalpy) latent_heat_formula = nothing #BulkFormula(latent_heat_difference, evaporation_transfer_coefficient) - sensible_heat_formula = BulkFormula(SensibleHeat(), sensible_heat_transfer_coefficient) + + sensible_heat_difference = SensibleHeat(FT; ocean_reference_temperature) + sensible_heat_formula = BulkFormula(sensible_heat_difference, sensible_heat_transfer_coefficient) heat_flux_formulae = (sensible_heat_formula, latent_heat_formula) @@ -185,12 +190,22 @@ end return air_sea_difference(i, j, grid, time, vₐ, vₒ) end -struct SensibleHeat end +struct SensibleHeat{FT} + ocean_reference_temperature :: FT +end + +SensibleHeat(FT::DataType=Float64; ocean_reference_temperature=273.15) = + SensibleHeat(convert(FT, ocean_reference_temperature)) -@inline function air_sea_difference(i, j, grid, time, ::SensibleHeat, atmos_state, ocean_state) +@inline function air_sea_difference(i, j, grid, time, Qs::SensibleHeat, atmos_state, ocean_state) cₚ = stateindex(atmos_state.cₚ, i, j, 1, time) Tₐ = atmos_state.T - Tₒ = ocean_state.T + + # Compute ocean temperature in degrees K + Tᵣ = Qs.ocean_reference_temperature + Tₒᵢ = stateindex(ocean_state.T, i, j, 1, time) + Tₒ = Tₒᵢ + Tᵣ + ΔT = air_sea_difference(i, j, grid, time, Tₐ, Tₒ) return @inbounds cₚ[i, j, 1] * ΔT @@ -205,7 +220,7 @@ struct SpecificHumidity{S} """ function SpecificHumidity(FT = Float64; - saturation_specific_humidity = LargeYeagerSaturationVaporFraction(FT)) + saturation_specific_humidity = LargeYeagerSaturationVaporFraction(FT)) S = typeof(saturation_specific_humidity) return new{S}(saturation_specific_humidity) end @@ -215,15 +230,15 @@ struct LargeYeagerSaturationVaporFraction{FT} q₀ :: FT c₁ :: FT c₂ :: FT - reference_temperature:: FT + reference_temperature :: FT end """ LargeYeagerSaturationVaporFraction(FT = Float64; - q₀ = 0.98, - c₁ = 640380, - c₂ = -5107.4, - reference_temperature = 273.15) + q₀ = 0.98, + c₁ = 640380, + c₂ = -5107.4, + reference_temperature = 273.15) """ function LargeYeagerSaturationVaporFraction(FT = Float64; From 29e0b352ededa6614bc7a7256b2710c731b576e8 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 8 Jan 2024 07:59:10 -0700 Subject: [PATCH 052/182] Massive rearrangement --- Manifest.toml | 224 ++++++++++-------- Project.toml | 7 +- examples/surface_flux_computation.jl | 102 ++++++++ .../prototype_omip_simulation/Manifest.toml | 34 ++- .../prototype_omip_simulation/Project.toml | 1 + .../analyze_omip_columns.jl | 106 +++++++++ .../single_column_omip_simulation.jl | 146 +++++------- .../PrescribedAtmospheres.jl | 0 src/DataWrangling/ECCO2.jl | 90 +++++-- .../CrossRealmFluxes/CrossRealmFluxes.jl | 52 ++++ .../atmosphere_ocean_momentum_flux.jl | 0 .../atmosphere_sea_ice_fluxes.jl | 0 .../ocean_sea_ice_surface_fluxes.jl} | 119 ++++------ .../ocean_sea_ice_surfaces.jl | 0 .../sea_ice_ocean_fluxes.jl | 0 .../similarity_theory_surface_fluxes.jl | 212 +++++++++++++++++ .../surface_radiation.jl | 0 src/OceanSeaIceModels/OceanSeaIceModels.jl | 32 +-- .../compute_atmosphere_ocean_fluxes.jl | 7 +- src/OceanSeaIceModels/getflux.jl | 0 src/OceanSeaIceModels/ocean_sea_ice_model.jl | 51 ++-- 21 files changed, 840 insertions(+), 343 deletions(-) create mode 100644 examples/surface_flux_computation.jl create mode 100644 experiments/prototype_omip_simulation/analyze_omip_columns.jl rename {src/OceanSeaIceModels => sandbox}/PrescribedAtmospheres/PrescribedAtmospheres.jl (100%) create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl rename src/OceanSeaIceModels/{ => CrossRealmFluxes}/atmosphere_ocean_momentum_flux.jl (100%) rename src/OceanSeaIceModels/{ => CrossRealmFluxes}/atmosphere_sea_ice_fluxes.jl (100%) rename src/OceanSeaIceModels/{ocean_sea_ice_model_fluxes.jl => CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl} (83%) rename src/OceanSeaIceModels/{ => CrossRealmFluxes}/ocean_sea_ice_surfaces.jl (100%) rename src/OceanSeaIceModels/{ => CrossRealmFluxes}/sea_ice_ocean_fluxes.jl (100%) create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl rename src/OceanSeaIceModels/{ => CrossRealmFluxes}/surface_radiation.jl (100%) delete mode 100644 src/OceanSeaIceModels/getflux.jl diff --git a/Manifest.toml b/Manifest.toml index 80705084..bac266fb 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0-beta3" manifest_format = "2.0" -project_hash = "ab7e5657c408d5d87054d02bc9a355c40379d5d8" +project_hash = "5d2ac82a7066017c63d34437c6eed8b514474918" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -17,9 +17,9 @@ weakdeps = ["ChainRulesCore", "Test"] [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "02f731463748db57cc2ebfbd9fbc9ce8280d3433" +git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.7.1" +version = "3.7.2" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] @@ -31,9 +31,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "16267cf279190ca7c1b30d020758ced95db89cd0" +git-tree-sha1 = "bbec08a37f8722786d87bedf84eae19c020c4efa" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.5.1" +version = "7.7.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -81,9 +81,9 @@ uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" version = "1.0.8+0" [[deps.CEnum]] -git-tree-sha1 = "eb4cb44a499229b3b8426dcfb5dd85333951ff90" +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.4.2" +version = "0.5.0" [[deps.CFTime]] deps = ["Dates", "Printf"] @@ -91,11 +91,17 @@ git-tree-sha1 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" uuid = "179af706-886a-5703-950a-314cd64e0468" version = "0.1.2" +[[deps.CLIMAParameters]] +deps = ["DocStringExtensions", "TOML", "Test"] +git-tree-sha1 = "a085251dfe4b0f732fe2b65d5354e6af91a8e931" +uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" +version = "0.7.26" + [[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", "Statistics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "64461b0e9df3069248979113ce8ab6d11bd371cf" +git-tree-sha1 = "76582ae19006b1186e87dadd781747f76cead72c" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.1.0" +version = "5.1.1" weakdeps = ["ChainRulesCore", "SpecialFunctions"] [deps.CUDA.extensions] @@ -104,9 +110,9 @@ weakdeps = ["ChainRulesCore", "SpecialFunctions"] [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "1e42ef1bdb45487ff28de16182c0df4920181dc3" +git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.7.0+0" +version = "0.7.0+1" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] @@ -116,15 +122,15 @@ version = "0.2.2" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "92394521ec4582c11d089a3b15b76ef2cb850994" +git-tree-sha1 = "9704e50c9158cf8896c2776b8dbc5edd136caf80" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.10.0+1" +version = "0.10.1+0" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "e0af648f0692ec1691b5d094b8724ba1346281cf" +git-tree-sha1 = "2118cb2765f8197b08e5958cdd17c165427425ee" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.18.0" +version = "1.19.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -132,7 +138,7 @@ weakdeps = ["SparseArrays"] [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "78982f15ee938f6bffe3f7bb67d52b51f46e4541" +git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" repo-rev = "main" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" @@ -175,9 +181,9 @@ version = "0.3.0" [[deps.Compat]] deps = ["UUIDs"] -git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" +git-tree-sha1 = "886826d76ea9e72b35fcd000e535588f7b60f21d" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.10.0" +version = "4.10.1" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -244,9 +250,9 @@ version = "1.6.1" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" +git-tree-sha1 = "ac67408d9ddf207de5cfa9a97e114352430f01ed" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.15" +version = "0.18.16" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -277,9 +283,9 @@ version = "0.3.22" [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.10" +version = "0.10.11" weakdeps = ["ChainRulesCore", "SparseArrays"] [deps.Distances.extensions] @@ -308,9 +314,9 @@ version = "1.0.1" [[deps.ExceptionUnwrapping]] deps = ["Test"] -git-tree-sha1 = "e90caa41f5a86296e014e148ee061bd6c3edec96" +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" -version = "0.1.9" +version = "0.1.10" [[deps.ExprTools]] git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" @@ -319,9 +325,9 @@ version = "0.1.10" [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "b4fbdd20c889804969571cc589900803edda16b7" +git-tree-sha1 = "ec22cbbcd01cba8f41eecd7d44aac1f23ee985e3" uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.7.1" +version = "1.7.2" [[deps.FFTW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -331,9 +337,9 @@ version = "3.3.10+0" [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "299dc33549f68299137e51e6d49a13b5b1da9673" +git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc" uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.1" +version = "1.16.2" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" @@ -389,15 +395,15 @@ 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 = "5eab648309e2e060198b45820af1a37182de3cce" +git-tree-sha1 = "abbbb9ec3afd783a7cbd82ef01dcd088ea051398" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.0" +version = "1.10.1" [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8ecb0b34472a3c98f945e3c75fc7d5428d165511" +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.9.3+0" +version = "2.10.0+0" [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" @@ -417,10 +423,10 @@ uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" version = "1.4.0" [[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ad37c091f7d7daf900963171600d7c1c5c3ede32" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2023.2.0+0" +version = "2024.0.2+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -449,9 +455,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "9bbb5130d3b4fa52846546bca4791ecbdfb52730" +git-tree-sha1 = "e65d2bd5754885e97407ff686da66a58b1e20df8" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.38" +version = "0.4.41" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -461,9 +467,15 @@ version = "1.5.0" [[deps.JSON3]] deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] -git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -version = "1.13.2" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -473,9 +485,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "95063c5bc98ba0c47e75e05ae71f1fed4deac6f6" +git-tree-sha1 = "653e0824fc9ab55b3beec67a6dbbe514a65fb954" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.12" +version = "0.9.15" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -485,9 +497,9 @@ version = "0.9.12" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "c879e47398a7ab671c782e02b51a4456794a7fa3" +git-tree-sha1 = "cb4619f7353fc62a1a22ffa3d7ed9791cfb47ad8" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.4.0" +version = "6.4.2" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -495,9 +507,9 @@ weakdeps = ["BFloat16s"] [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "a84f8f1e8caaaa4e3b4c101306b9e801d3883ace" +git-tree-sha1 = "98eaee04d96d973e79c25d49167668c5c8fb50e2" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.27+0" +version = "0.0.27+1" [[deps.LLVMLoopInfo]] git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" @@ -505,10 +517,10 @@ uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" version = "1.0.0" [[deps.LLVMOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f689897ccbe049adb19a065c495e75f372ecd42b" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "15.0.4+0" +version = "15.0.7+0" [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" @@ -582,10 +594,10 @@ uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" version = "1.0.3" [[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "eb006abbd7041c28e0d16260e50a24f8f9104913" +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2023.2.0+0" +version = "2024.0.0+0" [[deps.MPI]] deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] @@ -603,9 +615,9 @@ version = "0.20.16" [[deps.MPICH_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "8a5b4d2220377d1ece13f49438d71ad20cf1ba83" +git-tree-sha1 = "2ee75365ca243c1a39d467e35ffd3d4d32eef11e" uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.1.2+0" +version = "4.1.2+1" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] @@ -615,15 +627,15 @@ version = "0.1.10" [[deps.MPItrampoline_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "6979eccb6a9edbbb62681e158443e79ecc0d056a" +git-tree-sha1 = "8eeb3c73bbc0ca203d0dc8dad4008350bbe5797b" uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.3.1+0" +version = "5.3.1+1" [[deps.MacroTools]] deps = ["Markdown", "Random"] -git-tree-sha1 = "9ee1618cbf5240e6d4e0371d6f24065083f60c48" +git-tree-sha1 = "b211c553c199c111d998ecdaf7623d1b89b69f93" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.11" +version = "0.5.12" [[deps.Markdown]] deps = ["Base64"] @@ -631,9 +643,9 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "f512dc13e64e96f703fd92ce617755ee6b5adf0f" +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.8" +version = "1.1.9" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] @@ -661,9 +673,9 @@ version = "2023.1.10" [[deps.NCDatasets]] deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "7fcb4378f9c648a186bcb996fa29acc929a179ed" +git-tree-sha1 = "173a378f357e9bb24b22019efb5e4778223ce8cf" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.13.1" +version = "0.13.2" [[deps.NVTX]] deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] @@ -695,11 +707,11 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "347699e4ab2d8c401dbe743b4f94579bd8274a7c" +git-tree-sha1 = "eeca396589a53c957bcf5a9847e02c2eb915fe29" repo-rev = "glw/better-interpolate2" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.2" +version = "0.90.4" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -708,10 +720,13 @@ version = "0.90.2" EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" [[deps.OffsetArrays]] -deps = ["Adapt"] -git-tree-sha1 = "2ac17d29c523ce1cd38e27785a7d23024853a4bb" +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.12.10" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] @@ -725,9 +740,9 @@ version = "0.8.1+2" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] -git-tree-sha1 = "694458ae803b684f09c07f90459cb79655fb377d" +git-tree-sha1 = "1d1421618bab0e820bdc7ae1a2b46ce576981273" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.0+0" +version = "5.0.1+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] @@ -748,9 +763,9 @@ uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.5+0" [[deps.OrderedCollections]] -git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.2" +version = "1.6.3" [[deps.PMIx_jll]] deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] @@ -766,15 +781,15 @@ weakdeps = ["Requires", "TOML"] [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "a935806434c9d4c506ba941871b327b96d41f2bf" +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.0" +version = "2.8.1" [[deps.PencilArrays]] deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] -git-tree-sha1 = "1a473d028436947e08436275ff3fcc2f3e9c5b06" +git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.2" +version = "0.19.3" [deps.PencilArrays.extensions] PencilArraysDiffEqExt = ["DiffEqBase"] @@ -820,10 +835,10 @@ uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.1" [[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "6842ce83a836fbbc0cfeca0b5a4de1a4dcbdb8d1" +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.2.8" +version = "2.3.1" [[deps.Printf]] deps = ["Unicode"] @@ -837,9 +852,9 @@ version = "1.5.1" [[deps.Quaternions]] deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "da095158bdc8eaccb7890f9884048555ab771019" +git-tree-sha1 = "9a46862d248ea548e340e30e2894118749dc7f51" uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.4" +version = "0.7.5" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] @@ -851,9 +866,9 @@ uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[deps.Random123]] deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "552f30e847641591ba3f39fd1bed559b9deb0ef3" +git-tree-sha1 = "c860e84651f58ce240dd79e5d9e055d55234c35a" uuid = "74087812-796a-5b5d-8853-05524746bad3" -version = "1.6.1" +version = "1.6.2" [[deps.RandomNumbers]] deps = ["Random", "Requires"] @@ -925,9 +940,11 @@ uuid = "6c6a2e73-6563-6170-7368-637461726353" version = "1.2.1" [[deps.SeawaterPolynomials]] -git-tree-sha1 = "958ba75b90c7c8a117d041d33184134201cf8c0f" +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +repo-rev = "glw/heat-capacity" +repo-url = "https://github.com/CliMA/SeawaterPolynomials.jl.git" uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" -version = "0.3.2" +version = "0.3.4" [[deps.SentinelArrays]] deps = ["Dates", "Random"] @@ -954,9 +971,9 @@ uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "5165dfb9fd131cf0c6957a3a7605dede376e7b63" +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.0" +version = "1.2.1" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] @@ -981,9 +998,9 @@ version = "0.8.8" [[deps.StaticArrayInterface]] deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] -git-tree-sha1 = "03fec6800a986d191f64f5c0996b59ed526eda25" +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.4.1" +version = "1.5.0" weakdeps = ["OffsetArrays", "StaticArrays"] [deps.StaticArrayInterface.extensions] @@ -991,13 +1008,14 @@ weakdeps = ["OffsetArrays", "StaticArrays"] StaticArrayInterfaceStaticArraysExt = "StaticArrays" [[deps.StaticArrays]] -deps = ["LinearAlgebra", "Random", "StaticArraysCore"] -git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "4e17a790909b17f7bf1496e3aec138cf01b60b3b" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.6.5" -weakdeps = ["Statistics"] +version = "1.9.0" +weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" StaticArraysStatisticsExt = "Statistics" [[deps.StaticArraysCore]] @@ -1029,9 +1047,9 @@ version = "2.0.4" [[deps.StridedViews]] deps = ["LinearAlgebra", "PackageExtensionCompat"] -git-tree-sha1 = "cf857ff7de76f39e5daef6d032e8a74279ddff6a" +git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" -version = "0.2.1" +version = "0.2.2" weakdeps = ["CUDA"] [deps.StridedViews.extensions] @@ -1064,6 +1082,12 @@ deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.0+1" +[[deps.SurfaceFluxes]] +deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] +path = "/Users/gregorywagner/Projects/SurfaceFluxes.jl" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.8.0" + [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" @@ -1088,9 +1112,9 @@ version = "1.10.0" [[deps.TaylorSeries]] deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] -git-tree-sha1 = "50718b4fc1ce20cecf28d85215028c78b4d875c2" +git-tree-sha1 = "9138fdc8ee4e3b8839eca696a76d15e16c9c7af0" uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.15.2" +version = "0.15.4" [deps.TaylorSeries.extensions] TaylorSeriesIAExt = "IntervalArithmetic" @@ -1102,6 +1126,12 @@ version = "0.15.2" deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Printf", "Random", "RootSolvers"] +path = "/Users/gregorywagner/Projects/Thermodynamics.jl" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.11.2" + [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" @@ -1152,9 +1182,9 @@ version = "1.3.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "24b81b59bd35b3c42ab84fa589086e19be919916" +git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.11.5+0" +version = "2.12.2+0" [[deps.Zlib_jll]] deps = ["Libdl"] diff --git a/Project.toml b/Project.toml index 1e2322ed..c9a2f81d 100644 --- a/Project.toml +++ b/Project.toml @@ -6,10 +6,12 @@ version = "0.1.0" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" CubicSplines = "9c784101-8907-5a6d-9be6-98f00873c89b" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" @@ -17,7 +19,10 @@ NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +SurfaceFluxes = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" [compat] CUDA = "4, 5" @@ -26,8 +31,8 @@ DataDeps = "0.7" Downloads = "1.6" JLD2 = "0.4" KernelAbstractions = "0.9" -Oceananigans = "0.90" NCDatasets = "0.12, 0.13" +Oceananigans = "0.90" SeawaterPolynomials = "0.3" Statistics = "1.9" julia = "1.9" diff --git a/examples/surface_flux_computation.jl b/examples/surface_flux_computation.jl new file mode 100644 index 00000000..33cbf85d --- /dev/null +++ b/examples/surface_flux_computation.jl @@ -0,0 +1,102 @@ + using SurfaceFluxes + using Thermodynamics + using StaticArrays + using ClimaOcean + + import CLIMAParameters + + using Thermodynamics: q_vap_saturation_from_density, partial_pressure_vapor + using SurfaceFluxes.Parameters: SurfaceFluxesParameters + using ClimaOcean.OceanSeaIceModels: + default_universal_function_parameters, + default_surface_flux_parameters + + const CP = CLIMAParameters + + function extrapolate_surface_density(params, atmos_state, surface_temperature) + Tₛ = surface_temperature + Tₐ = air_temperature(params, atmos_state) + Rmₐ = gas_constant_air(params, atmos_state) + ρₐ = air_density(params, atmos_state) + κ = cv_m(params, atmos_state) / Rmₐ + return ρₐ * (Tₛ / Tₐ)^κ +end + +function surface_saturation_specific_humidity(params, surface_temperature, atmos_state) + Tₛ = surface_temperature + ρₛ = atmos_state.ρ #extrapolate_surface_density(thermo_params, atmos_state, Tₛ) + + @show p★ = saturation_vapor_pressure(params, Tₛ, Liquid()) + + q = PhasePartition(thermo_params, atmos_thermo_state) + @show q + + @show pᵥ = partial_pressure_vapor(params, atmos_state.p, q) + @show p★ₐ = saturation_vapor_pressure(params, atmos_state.T, Liquid()) + @show q★ₐ = q_vap_saturation_from_density(params, atmos_state.T, atmos_state.ρ, p★ₐ) + @show pᵥ / p★ₐ + + q★ = q_vap_saturation_from_density(params, Tₛ, ρₛ, p★) + @show q★ + @show q + + return q★ +end + +FT = Float64 +thermo_params = Thermodynamics.Parameters.HierarchicalThermodynamicsParameters(FT) +businger_params = default_universal_function_parameters(FT) +surface_flux_parameters = default_surface_flux_parameters(thermo_params) + +#= +include(joinpath(pkgdir(SurfaceFluxes), "parameters", "create_parameters.jl")) +toml_dict = CP.create_toml_dict(FT; dict_type = "alias") +uf_type = SurfaceFluxes.UniversalFunctions.BusingerType() +param_set = create_parameters(toml_dict, uf_type) +thermo_params = SurfaceFluxes.Parameters.thermodynamics_params(param_set) +=# + +h = 2.0 # height at which measurements are made, in m +surface_velocity = SVector(0.0, 0.0) +atmos_velocity = SVector(4.0, 0.0) + +atmos_pressure = 101350.0 +atmos_temperature = 298.15 +atmos_specific_humidity = 0.03 + +atmos_thermo_state = Thermodynamics.PhaseEquil_pTq(thermo_params, + atmos_pressure, + atmos_temperature, + atmos_specific_humidity) + + +surface_temperature = Tₛ = 297.15 + +q₀ = 0.98 +c₁ = 640380 +c₂ = 5107.4 +qLY = q₀ * c₁ * exp(-c₂ / Tₛ) + +q★ = surface_saturation_specific_humidity(thermo_params, surface_temperature, atmos_thermo_state) +surface_thermo_state = Thermodynamics.PhaseEquil_pTq(thermo_params, + atmos_pressure, + surface_temperature, + q★) + + +# State at z=0, eg the "surface" +surface_dynamic_state = SurfaceFluxes.StateValues(0.0, surface_velocity, surface_thermo_state) + +# State at z=h, eg the "atmosphere" +atmos_dynamic_state = SurfaceFluxes.StateValues(h, atmos_velocity, atmos_thermo_state) + +momentum_roughness_length = 0.01 +buoyancy_roughness_length = 0.001 + +values = SurfaceFluxes.ValuesOnly(atmos_dynamic_state, + surface_dynamic_state, + momentum_roughness_length, + buoyancy_roughness_length) + +conditions = SurfaceFluxes.surface_conditions(surface_flux_parameters, values) + diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 16dbf360..28f2786b 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0-beta3" manifest_format = "2.0" -project_hash = "883b87502c4a6df1ec75ae2bd27194c9ff4c7796" +project_hash = "7c534a264b9c4e557224dee6d48b112d23aa3745" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -125,6 +125,12 @@ git-tree-sha1 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" uuid = "179af706-886a-5703-950a-314cd64e0468" version = "0.1.2" +[[deps.CLIMAParameters]] +deps = ["DocStringExtensions", "TOML", "Test"] +git-tree-sha1 = "a085251dfe4b0f732fe2b65d5354e6af91a8e931" +uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" +version = "0.7.26" + [[deps.CRC32c]] uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" @@ -192,14 +198,16 @@ weakdeps = ["SparseArrays"] ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.ClimaOcean]] -deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "Statistics"] +deps = ["Adapt", "CLIMAParameters", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] path = "../.." uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" version = "0.1.0" [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -path = "/Users/gregorywagner/Projects/ClimaSeaIce.jl" +git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" +repo-rev = "main" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" @@ -1247,7 +1255,7 @@ version = "0.5.5" 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"] path = "/Users/gregorywagner/Projects/Oceananigans.jl" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.2" +version = "0.90.4" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -1653,9 +1661,11 @@ uuid = "6c6a2e73-6563-6170-7368-637461726353" version = "1.2.1" [[deps.SeawaterPolynomials]] -git-tree-sha1 = "958ba75b90c7c8a117d041d33184134201cf8c0f" +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +repo-rev = "glw/heat-capacity" +repo-url = "https://github.com/CliMA/SeawaterPolynomials.jl.git" uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" -version = "0.3.2" +version = "0.3.4" [[deps.SentinelArrays]] deps = ["Dates", "Random"] @@ -1887,6 +1897,12 @@ deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.0+1" +[[deps.SurfaceFluxes]] +deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] +path = "../../../SurfaceFluxes.jl" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.8.0" + [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" @@ -1929,6 +1945,12 @@ version = "0.1.1" deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Printf", "Random", "RootSolvers"] +path = "../../../Thermodynamics.jl" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.11.2" + [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml index 8a6e0746..15628622 100644 --- a/experiments/prototype_omip_simulation/Project.toml +++ b/experiments/prototype_omip_simulation/Project.toml @@ -1,6 +1,7 @@ [deps] ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" diff --git a/experiments/prototype_omip_simulation/analyze_omip_columns.jl b/experiments/prototype_omip_simulation/analyze_omip_columns.jl new file mode 100644 index 00000000..6bfe3ca8 --- /dev/null +++ b/experiments/prototype_omip_simulation/analyze_omip_columns.jl @@ -0,0 +1,106 @@ +using Oceananigans +using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency + +using ClimaOcean +using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +using GLMakie +using Printf +using Dates + +start_time = time_ns() + +include("single_column_omip_ocean_component.jl") + +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 01) +start_seconds = Second(date - epoch).value +uᵢ = ecco2_field(:u_velocity, date) +vᵢ = ecco2_field(:v_velocity, date) +Tᵢ = ecco2_field(:temperature, date) +Sᵢ = ecco2_field(:salinity, date) + +land = interior(Tᵢ) .< -10 +interior(Tᵢ)[land] .= NaN +interior(Sᵢ)[land] .= NaN + +teos10 = TEOS10EquationOfState() +buoyancy = SeawaterBuoyancy(equation_of_state=teos10) +tracers = (T=Tᵢ, S=Sᵢ) +N²_op = buoyancy_frequency(buoyancy, Tᵢ.grid, tracers) +N² = Field(N²_op) +compute!(N²) + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +zc = znodes(Tᵢ) +zf = znodes(N²) + +arch = CPU() + +Δ = 1/4 # resolution in degrees +φ₁ = -90 + Δ/2 +φ₂ = +90 - Δ/2 +λ₁ = 0 + Δ/2 +λ₂ = 360 - Δ/2 +φe = φ₁:Δ:φ₂ +λe = λ₁:Δ:λ₂ + +Nz = size(Tᵢ, 3) +fig = Figure(resolution=(1200, 1200)) +map = Axis(fig[1, 1:3], xlabel="λ (degrees)", ylabel="φ (degrees)") +hm = heatmap!(map, λe, φe, interior(Tᵢ, :, :, Nz), colorrange=(0, 30), nan_color=:gray) +Colorbar(fig[1, 4], hm, label="Surface temperature (ᵒC)") + +axT = Axis(fig[2, 1], ylabel="z (m)", xlabel="Temperature (ᵒC)") +axS = Axis(fig[2, 2], ylabel="z (m)", xlabel="Salinity (g/kg)") +axN = Axis(fig[2, 3], ylabel="z (m)", xlabel="Buoyancy frequency (s⁻²)") + +φs = [50, 55, 0, -30, -65, 34] +λs = [215, 310, 210, 160, 160, 34] + +# Mediterranean locations +# λs = [34, 33, 5, 20, 30] +# φs = [34, 32, 38, 35, 33] + +Nc = length(φs) + +for n = 1:Nc + local φ★ + local λ★ + local i★ + local j★ + + φ★ = φs[n] + λ★ = λs[n] + + i★ = searchsortedfirst(λe, λ★) + j★ = searchsortedfirst(φe, φ★) + + scatter!(map, λ★, φ★, strokewidth=4, strokecolor=:black, + color=:pink, markersize=20) + + label = string("λ = ", λ★, ", φ = ", φ★) + scatterlines!(axT, interior(Tᵢ, i★, j★, :), zc; label) + scatterlines!(axS, interior(Sᵢ, i★, j★, :), zc; label) + scatterlines!(axN, interior(N², i★, j★, :), zf; label) +end + +zm = -500 + +xlims!(axT, -2, 30) +xlims!(axS, 32, 40) +ylims!(axT, zm, 30) +ylims!(axS, zm, 30) +axislegend(axT, position=:rb) + +display(fig) + diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index f687bdfd..49378b3b 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -1,29 +1,32 @@ using Oceananigans using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency using ClimaOcean using ClimaOcean.OceanSeaIceModels: SurfaceRadiation using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere using ClimaOcean.DataWrangling.ECCO2: ecco2_field -using NCDatasets using GLMakie using Printf - -using Downloads: download +using Dates start_time = time_ns() include("single_column_omip_ocean_component.jl") -Tᵢ = ecco2_field(:temperature) -Sᵢ = ecco2_field(:salinity) +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 01) +start_seconds = Second(date - epoch).value +uᵢ = ecco2_field(:u_velocity, date) +vᵢ = ecco2_field(:v_velocity, date) +Tᵢ = ecco2_field(:temperature, date) +Sᵢ = ecco2_field(:salinity, date) land = interior(Tᵢ) .< -10 interior(Tᵢ)[land] .= NaN interior(Sᵢ)[land] .= NaN -using Oceananigans.BuoyancyModels: buoyancy_frequency teos10 = TEOS10EquationOfState() buoyancy = SeawaterBuoyancy(equation_of_state=teos10) tracers = (T=Tᵢ, S=Sᵢ) @@ -52,57 +55,6 @@ arch = CPU() φe = φ₁:Δ:φ₂ λe = λ₁:Δ:λ₂ -Nz = size(Tᵢ, 3) -fig = Figure(resolution=(1200, 1200)) -map = Axis(fig[1, 1:3], xlabel="λ (degrees)", ylabel="φ (degrees)") -hm = heatmap!(map, λe, φe, interior(Tᵢ, :, :, Nz), colorrange=(0, 30), nan_color=:gray) -Colorbar(fig[1, 4], hm, label="Surface temperature (ᵒC)") - -axT = Axis(fig[2, 1], ylabel="z (m)", xlabel="Temperature (ᵒC)") -axS = Axis(fig[2, 2], ylabel="z (m)", xlabel="Salinity (psu)") -axN = Axis(fig[2, 3], ylabel="z (m)", xlabel="Buoyancy frequency (s⁻²)") - -φs = [50, 55, 0, -30, -65, 34] -λs = [215, 310, 210, 160, 160, 34] - -λs = [34, 33, 5, 20, 30] -φs = [34, 32, 38, 35, 33] - -#φs = [-30] -#s = [160] - -Nc = length(φs) - -for n = 1:Nc - local φ★ - local λ★ - local i★ - local j★ - - φ★ = φs[n] - λ★ = λs[n] - - i★ = searchsortedfirst(λe, λ★) - j★ = searchsortedfirst(φe, φ★) - - scatter!(map, λ★, φ★, strokewidth=4, strokecolor=:black, - color=:pink, markersize=20) - - label = string("λ = ", λ★, ", φ = ", φ★) - scatterlines!(axT, interior(Tᵢ, i★, j★, :), zc; label) - scatterlines!(axS, interior(Sᵢ, i★, j★, :), zc; label) - scatterlines!(axN, interior(N², i★, j★, :), zf; label) -end - -xlims!(axT, -2, 30) -xlims!(axS, 32, 40) -ylims!(axT, -2000, 30) -ylims!(axS, -2000, 30) -axislegend(axT, position=:rb) - -display(fig) - -#= φ★ = 50 # degrees latitude λ★ = 180 + 35 # degrees longitude (?) @@ -113,19 +65,24 @@ longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) # Column +uc = interior(uᵢ, i★:i★, j★:j★, :) +vc = interior(vᵢ, i★:i★, j★:j★, :) Tc = interior(Tᵢ, i★:i★, j★:j★, :) Sc = interior(Sᵢ, i★:i★, j★:j★, :) # Find bottom +zm = -400 zf = znodes(Tᵢ.grid, Face()) kb = findlast(T -> T < -20, Tc[1, 1, :]) -km = findlast(z -> z < -2000, zf) +km = findlast(z -> z < zm, zf) k★ = isnothing(kb) ? km : max(kb, km) Nz = size(Tc, 3) kf = k★:Nz+1 kc = k★:Nz zf = zf[kf] +uc = uc[:, :, kc] +vc = vc[:, :, kc] Tc = Tc[:, :, kc] Sc = Sc[:, :, kc] Nz′ = length(kc) @@ -144,14 +101,14 @@ elapsed = time_ns() - start_time @info "Ocean component built. " * prettytime(elapsed * 1e-9) start_time = time_ns() -Ndays = 90 +Ndays = 365 Nt = 8 * Ndays atmosphere = jra55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() -ocean.model.clock.time = 0 +ocean.model.clock.time = start_seconds ocean.model.clock.iteration = 0 set!(ocean.model, T=Tc, S=Sc, e=1e-6) @@ -161,22 +118,26 @@ Ta = atmosphere.tracers.T qa = atmosphere.tracers.q times = ua.times +#= fig = Figure(resolution=(1200, 1800)) axu = Axis(fig[1, 1]) axT = Axis(fig[2, 1]) axq = Axis(fig[3, 1]) -lines!(axu, times ./ day, interior(ua, 1, 1, 1, :)) -lines!(axu, times ./ day, interior(va, 1, 1, 1, :)) -lines!(axT, times ./ day, interior(Ta, 1, 1, 1, :)) -lines!(axq, times ./ day, interior(qa, 1, 1, 1, :)) +lines!(axu, times ./ days, interior(ua, 1, 1, 1, :)) +lines!(axu, times ./ days, interior(va, 1, 1, 1, :)) +lines!(axT, times ./ days, interior(Ta, 1, 1, 1, :)) +lines!(axq, times ./ days, interior(qa, 1, 1, 1, :)) display(fig) +=# sea_ice = nothing surface_radiation = SurfaceRadiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, surface_radiation) -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=30day) + +#= +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 90days) elapsed = time_ns() - start_time @info "Coupled simulation built. " * prettytime(elapsed * 1e-9) @@ -199,13 +160,13 @@ function progress(sim) e = sim.model.ocean.model.tracers.e Nz = size(T, 3) msg4 = @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) - msg5 = @sprintf(", S₀: %.2f psu", first(interior(S, 1, 1, Nz))) + msg5 = @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) msg6 = @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) @info msg1 * msg2 * msg3 * msg4 * msg5 * msg6 end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) # Build flux outputs Jᵘ = coupled_model.surfaces.ocean.momentum.u @@ -228,16 +189,16 @@ outputs = merge(fields, fluxes) filename = "single_column_omip_surface_fields.jld2" coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean.model, outputs; filename, - schedule = TimeInterval(1hour), + schedule = TimeInterval(1hours), overwrite_existing = true) -@show coupled_simulation.stop_time run!(coupled_simulation) -Tt = FieldTimeSeries(filename, "T") ut = FieldTimeSeries(filename, "u") vt = FieldTimeSeries(filename, "v") +Tt = FieldTimeSeries(filename, "T") St = FieldTimeSeries(filename, "S") +et = FieldTimeSeries(filename, "e") Qt = FieldTimeSeries(filename, "Q") Ft = FieldTimeSeries(filename, "F") τˣt = FieldTimeSeries(filename, "τˣ") @@ -275,48 +236,59 @@ end fig = Figure(resolution=(2400, 1800)) -axu = Axis(fig[1, 1], xlabel="Time (days)", ylabel="Velocities (m s⁻¹)") -axτ = Axis(fig[2, 1], xlabel="Time (days)", ylabel="Wind stress (N m⁻²)") -axT = Axis(fig[3, 1], xlabel="Time (days)", ylabel="Temperature (K)") -axQ = Axis(fig[4, 1], xlabel="Time (days)", ylabel="Heat flux (W m⁻²)") -axF = Axis(fig[5, 1], xlabel="Time (days)", ylabel="Salt flux (...)") +axu = Axis(fig[1, 1:4], xlabel="Time (days)", ylabel="Velocities (m s⁻¹)") +axτ = Axis(fig[2, 1:4], xlabel="Time (days)", ylabel="Wind stress (N m⁻²)") +axT = Axis(fig[3, 1:4], xlabel="Time (days)", ylabel="Temperature (K)") +axQ = Axis(fig[4, 1:4], xlabel="Time (days)", ylabel="Heat flux (W m⁻²)") +axF = Axis(fig[5, 1:4], xlabel="Time (days)", ylabel="Salt flux (...)") -axTz = Axis(fig[1:5, 2], xlabel="Temperature (K)", ylabel="z (m)") -axSz = Axis(fig[1:5, 3], xlabel="Salinity (psu)", ylabel="z (m)") +axuz = Axis(fig[6, 1], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") +axTz = Axis(fig[6, 2], xlabel="Temperature (K)", ylabel="z (m)") +axSz = Axis(fig[6, 3], xlabel="Salinity (g/kg)", ylabel="z (m)") +axez = Axis(fig[6, 4], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)") -slider = Slider(fig[6, 1:3], range=1:Nt, startvalue=1) +slider = Slider(fig[7, 1:4], range=1:Nt, startvalue=1) n = slider.value +times ./= days tn = @lift times[$n] -lines!(axu, times, uat, color=:royalblue) -lines!(axu, times, interior(ut, 1, 1, Nz, :), color=:royalblue, linestyle=:dash) +colors = Makie.wong_colors() + +lines!(axu, times, uat, color=colors[1]) +lines!(axu, times, interior(ut, 1, 1, Nz, :), color=colors[1], linestyle=:dash) vlines!(axu, tn) -lines!(axu, times, vat, color=:seagreen) -lines!(axu, times, interior(vt, 1, 1, Nz, :), color=:seagreen, linestyle=:dash) +lines!(axu, times, vat, color=colors[2]) +lines!(axu, times, interior(vt, 1, 1, Nz, :), color=colors[2], linestyle=:dash) lines!(axτ, times, interior(τˣt, 1, 1, 1, :)) lines!(axτ, times, interior(τʸt, 1, 1, 1, :)) vlines!(axτ, tn) -lines!(axT, times, Tat, color=:royalblue) -lines!(axT, times, interior(Tt, 1, 1, Nz, :) .+ 273.15, color=:royalblue, linestyle=:dash) +lines!(axT, times, Tat, color=colors[1]) +lines!(axT, times, interior(Tt, 1, 1, Nz, :) .+ 273.15, color=colors[1], linestyle=:dash) vlines!(axT, tn) -lines!(axQ, times, interior(Qt, 1, 1, 1, :), linestyle=:dash) -lines!(axQ, times, - Qswt, color=:seagreen, linewidth=3) -lines!(axQ, times, - Qlwt, color=:royalblue, linewidth=3) +lines!(axQ, times, interior(Qt, 1, 1, 1, :), color=colors[1], linestyle=:dash) +lines!(axQ, times, - Qswt, color=colors[2], linewidth=3) +lines!(axQ, times, - Qlwt, color=colors[3], linewidth=3) vlines!(axQ, tn) lines!(axF, times, interior(Ft, 1, 1, 1, :)) vlines!(axF, tn) z = znodes(Tt) +un = @lift interior(ut[$n], 1, 1, :) +vn = @lift interior(vt[$n], 1, 1, :) Tn = @lift interior(Tt[$n], 1, 1, :) Sn = @lift interior(St[$n], 1, 1, :) +en = @lift interior(et[$n], 1, 1, :) +lines!(axuz, un, z) +lines!(axuz, vn, z) lines!(axTz, Tn, z) lines!(axSz, Sn, z) +lines!(axez, en, z) display(fig) =# diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres/PrescribedAtmospheres.jl b/sandbox/PrescribedAtmospheres/PrescribedAtmospheres.jl similarity index 100% rename from src/OceanSeaIceModels/PrescribedAtmospheres/PrescribedAtmospheres.jl rename to sandbox/PrescribedAtmospheres/PrescribedAtmospheres.jl diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 1fc4a7bc..a41ebffc 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -1,5 +1,7 @@ module ECCO2 +using Dates + using Oceananigans using Oceananigans.BoundaryConditions: fill_halo_regions! @@ -70,45 +72,79 @@ const ECCO2_z = [ 0.0, ] -filenames = Dict( - :temperature => "THETA.1440x720x50.19920102.nc", - :salinity => "SALT.1440x720x50.19920102.nc", - :sea_ice_thickness => "SIheff.1440x720.19920102.nc", +filenames_19920102 = Dict( + :temperature => "THETA.1440x720x50.19920102.nc", + :salinity => "SALT.1440x720x50.19920102.nc", + :sea_ice_thickness => "SIheff.1440x720.19920102.nc", + :sea_ice_area_fraction => "SIarea.1440x720.19920102.nc", + :u_velocity => "UVEL.1440x720.19920102.nc", + :v_velocity => "VVEL.1440x720.19920102.nc", ) -shortnames = Dict( - :temperature => "THETA", - :salinity => "SALT", - :sea_ice_thickness => "SIheff", +filenames_19921001 = Dict( + :temperature => "THETA.1440x720x50.19921001.nc", + :salinity => "SALT.1440x720x50.19921001.nc", + :sea_ice_thickness => "SIheff.1440x720.19921001.nc", + :sea_ice_area_fraction => "SIarea.1440x720.19921001.nc", + :u_velocity => "UVEL.1440x720.19921001.nc", + :v_velocity => "VVEL.1440x720.19921001.nc", ) -depthnames = Dict( - :temperature => "DEPTH_T", - :salinity => "DEPTH_S", - :sea_ice_thickness => nothing, +urls_19920102 = Dict( + :temperature => "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs", + :salinity => "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw", + :sea_ice_thickness => "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am", + :sea_ice_area_fraction => "https://www.dropbox.com/scl/fi/q14moq3201zicppu8ff8h/SIarea.1440x720.19920102.nc?rlkey=pt7pt80gr7r6mmjm9e0u4f5n1", + :u_velocity => "https://www.dropbox.com/scl/fi/myur9kpanc5mprrf5ge32/UVEL.1440x720x50.19920102.nc?rlkey=7a5dpvfgoc87yr6q5ktrqwndu", + :v_velocity => "https://www.dropbox.com/scl/fi/buic35gssyeyfqohenkeo/VVEL.1440x720x50.19920102.nc?rlkey=fau48w4t5ruop4s6gm8t7z0a0", ) -urls = Dict( - :temperature => "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * - "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0", +urls_19921001 = Dict( + :temperature => "https://www.dropbox.com/scl/fi/169f3981460uhk9h69k0f/THETA.1440x720x50.19921001.nc?rlkey=mgal3xt0qy2c59y395ybio11v", + :salinity => "https://www.dropbox.com/scl/fi/f9zfm34vqz732jrrhjrg3/SALT.1440x720x50.19921001.nc?rlkey=y5dv0s41gb6f9guvu0iorw28p", + :sea_ice_thickness => "https://www.dropbox.com/scl/fi/mtmziurepom8kpjn82d07/SIheff.1440x720.19921001.nc?rlkey=9uhuxg2n9iw6894afj4t53drv", + :sea_ice_area_fraction => "https://www.dropbox.com/scl/fi/ntflhyrmsnit9vco402co/SIarea.1440x720.19921001.nc?rlkey=eakzc788btql1q6ndj9l8cr2q", + #:u_velocity => "https://www.dropbox.com/scl/fi/e6s9c013r2ddift4f8ugi/UVEL.1440x720x50.19921001.nc?rlkey=fpd7mv1zv3fkmyg8w11b94sbp&dl=0", + :u_velocity => "https://www.dropbox.com/scl/fi/e6s9c013r2ddift4f8ugi/UVEL.1440x720x50.19921001.nc?rlkey=fpd7mv1zv3fkmyg8w11b94sbp&dl=0", + :v_velocity => "https://www.dropbox.com/scl/fi/nxuohvhvdu0ig552osf1d/VVEL.1440x720x50.19921001.nc?rlkey=vz4ttp3myxhertdxvt1lyjp1d", +) - :salinity => "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * - "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0", +filenames = Dict( + "1992-01-02" => filenames_19920102, + "1992-10-01" => filenames_19921001, +) - :sea_ice_thickness => "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/" * - "SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am&dl=0", +urls = Dict( + "1992-01-02" => urls_19920102, + "1992-10-01" => urls_19921001, ) +shortnames = Dict( + :temperature => "THETA", + :salinity => "SALT", + :sea_ice_thickness => "SIheff", + :sea_ice_area_fraction => "SIarea", + :u_velocity => "UVEL", + :v_velocity => "VVEL", +) + + + surface_variable(variable_name) = variable_name == :sea_ice_thickness -function ecco2_field(variable_name; +function ecco2_field(variable_name, date=Date(1992, 01, 01); architecture = CPU(), - filename = filenames[variable_name], - shortname = shortnames[variable_name], - depthname = depthnames[variable_name], - url = urls[variable_name]) + filename = filenames[string(date)][variable_name], + url = urls[string(date)][variable_name], + shortname = shortnames[variable_name]) - isfile(filename) || download(url, filename) + if !isfile(filename) + print("Downloading $filename...") + start_time = time_ns() + download(url, filename) + elapsed = time_ns() - start_time + print(" done (", prettytime(elapsed * 1e-9), ").", '\n') + end ds = Dataset(filename) @@ -120,12 +156,13 @@ function ecco2_field(variable_name; halo = (1, 1, 1), topology = (Periodic, Bounded, Bounded)) + # TODO: figure out what's going on with the locations if surface_variable(variable_name) field = Field{Center, Center, Nothing}(grid) data = ds[shortname][:, :, 1] data = convert(Array{Float32, 2}, data) else - field = CenterField(grid) # u, v not supported + field = CenterField(grid) data = ds[shortname][:, :, :, 1] data = convert(Array{Float32, 3}, data) data = reverse(data, dims=3) @@ -138,3 +175,4 @@ function ecco2_field(variable_name; end end # module + diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl new file mode 100644 index 00000000..b52ccabb --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -0,0 +1,52 @@ +module CrossRealmFluxes + +using Oceananigans + +export SurfaceRadiation, + OceanSeaIceSurfaceFluxes + +using ..OceanSeaIceModels: SKOFTS + +##### +##### Utilities +##### + +@inline stateindex(a::Number, i, j, k, time) = a +@inline stateindex(a::SKOFTS, i, j, k, time) = @inbounds a[i, j, k, time] +@inline stateindex(a::AbstractArray, i, j, k, time) = @inbounds a[i, j, k] +@inline Δϕt²(i, j, k, grid, ϕ1, ϕ2, time) = (stateindex(ϕ1, i, j, k, time) - stateindex(ϕ2, i, j, k, time))^2 + +@inline function stateindex(a::Tuple, i, j, k, time) + N = length(a) + ntuple(Val(N)) do n + stateindex(a[n], i, j, k, time) + end +end + +@inline function stateindex(a::NamedTuple, i, j, k, time) + vals = stateindex(values(a), i, j, k, time) + names = keys(a) + return NamedTuple{names}(vals) +end + +function surface_flux(f::Field) + top_bc = f.boundary_conditions.top + if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} + return top_bc.condition + else + return nothing + end +end + +include("surface_radiation.jl") +include("similarity_theory_surface_fluxes.jl") +include("ocean_sea_ice_surface_fluxes.jl") + +# include("ocean_sea_ice_model_fluxes.jl") +# include("ocean_sea_ice_surfaces.jl") +# include("atmosphere_sea_ice_fluxes.jl") +# include("atmosphere_ocean_momentum_flux.jl") +# include("sea_ice_ocean_fluxes.jl") + +end # module + diff --git a/src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_momentum_flux.jl similarity index 100% rename from src/OceanSeaIceModels/atmosphere_ocean_momentum_flux.jl rename to src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_momentum_flux.jl diff --git a/src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_sea_ice_fluxes.jl similarity index 100% rename from src/OceanSeaIceModels/atmosphere_sea_ice_fluxes.jl rename to src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_sea_ice_fluxes.jl diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl similarity index 83% rename from src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl rename to src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 05cf7f41..5486361b 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -2,73 +2,40 @@ using Oceananigans.Models.HydrostaticFreeSurfaceModels: HydrostaticFreeSurfaceMo using ClimaSeaIce.SlabSeaIceModels: SlabSeaIceModel ##### -##### Utilities -##### - -@inline stateindex(a::Number, i, j, k, time) = a -@inline stateindex(a::SKOFTS, i, j, k, time) = a[i, j, k, time] -@inline stateindex(a::AbstractArray, i, j, k, time) = a[i, j, k] -@inline Δϕt²(i, j, k, grid, ϕ1, ϕ2, time) = (stateindex(ϕ1, i, j, k, time) - stateindex(ϕ2, i, j, k, time))^2 - -@inline function stateindex(a::Tuple, i, j, k, time) - N = length(a) - ntuple(Val(N)) do n - stateindex(a[n], i, j, k, time) - end -end - -@inline function stateindex(a::NamedTuple, i, j, k, time) - vals = stateindex(values(a), i, j, k, time) - names = keys(a) - return NamedTuple{names}(vals) -end - -function surface_flux(f::Field) - top_bc = f.boundary_conditions.top - if top_bc isa BoundaryCondition{<:Oceananigans.BoundaryConditions.Flux} - return top_bc.condition - else - return nothing - end -end - -##### -##### Convenience containers for surface fluxes -##### -##### "Cross realm fluxes" can refer to the flux _data_ (ie, fields representing -##### the total flux for a given variable), or to the flux _components_ / formula. +##### Container for organizing information related to fluxes ##### -struct CrossRealmFluxes{M, H, T} - momentum :: M - heat :: H - tracers :: T +struct OceanSeaIceSurfaceFluxes{C, R, T, P} + total :: C + emitted_radiation :: R + turbulent :: T + prescribed :: P end -CrossRealmFluxes(; momentum=nothing, heat=nothing, tracers=nothing) = - CrossRealmFluxes(momentum, heat, tracers) +Base.summary(crf::OceanSeaIceSurfaceFluxes) = "OceanSeaIceSurfaceFluxes" +Base.show(io::IO, crf::OceanSeaIceSurfaceFluxes) = print(io, summary(crf)) -Base.summary(osf::CrossRealmFluxes) = "CrossRealmFluxes" -Base.show(io::IO, osf::CrossRealmFluxes) = print(io, summary(osf)) +function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; + atmosphere = nothing, + surface_radiation = nothing) -##### -##### Container for organizing information related to fluxes -##### + FT = eltype(ocean.model.grid) + turbulent_fluxes = SimilarityTheoryTurbulentFluxes(FT) + prescribed_fluxes = nothing -struct OceanSeaIceModelFluxes{U, R, AO, ASI, SIO} - bulk_velocity_scale :: U - surface_radiation :: R - atmosphere_ocean :: AO - atmosphere_sea_ice :: ASI - sea_ice_ocean :: SIO + return OceanSeaIceSurfaceFluxes(nothing, + surface_radiation, + turbulent_fluxes, + prescribed_fluxes) end +#= function default_atmosphere_ocean_fluxes(FT=Float64, tracers=tuple(:S)) # Note: we are constantly coping with the fact that the ocean is ᵒC. ocean_reference_temperature = 273.15 - momentum_transfer_coefficient = 1e-3 + momentum_transfer_coefficient = 5e-3 evaporation_transfer_coefficient = 1e-3 - sensible_heat_transfer_coefficient = 1e-3 + sensible_heat_transfer_coefficient = 2e-3 vaporization_enthalpy = 2.5e-3 momentum_transfer_coefficient = convert(FT, momentum_transfer_coefficient) @@ -97,28 +64,9 @@ function default_atmosphere_ocean_fluxes(FT=Float64, tracers=tuple(:S)) heat = heat_flux_formulae, tracers = tracer_flux_formulae) end +=# -function OceanSeaIceModelFluxes(FT=Float64; - bulk_velocity_scale = RelativeVelocityScale(), - surface_radiation = nothing, - atmosphere_ocean = nothing, - atmosphere_sea_ice = nothing, - sea_ice_ocean = nothing) - - if isnothing(atmosphere_ocean) # defaults - atmosphere_ocean = default_atmosphere_ocean_fluxes(FT) - end - - return OceanSeaIceModelFluxes(bulk_velocity_scale, - surface_radiation, - atmosphere_ocean, - atmosphere_sea_ice, - sea_ice_ocean) -end - -Base.summary(crf::OceanSeaIceModelFluxes) = "OceanSeaIceModelFluxes" -Base.show(io::IO, crf::OceanSeaIceModelFluxes) = print(io, summary(crf)) - +#= ##### ##### Bulk formula ##### @@ -336,3 +284,24 @@ end return sqrt(Δu² + Δv²) end +##### +##### Convenience containers for surface fluxes +##### +##### "Cross realm fluxes" can refer to the flux _data_ (ie, fields representing +##### the total flux for a given variable), or to the flux _components_ / formula. +##### + +struct CrossRealmFluxes{M, H, T} + momentum :: M + heat :: H + tracers :: T +end + +CrossRealmFluxes(; momentum=nothing, heat=nothing, tracers=nothing) = + CrossRealmFluxes(momentum, heat, tracers) + +Base.summary(osf::CrossRealmFluxes) = "CrossRealmFluxes" +Base.show(io::IO, osf::CrossRealmFluxes) = print(io, summary(osf)) + +=# + diff --git a/src/OceanSeaIceModels/ocean_sea_ice_surfaces.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surfaces.jl similarity index 100% rename from src/OceanSeaIceModels/ocean_sea_ice_surfaces.jl rename to src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surfaces.jl diff --git a/src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl similarity index 100% rename from src/OceanSeaIceModels/sea_ice_ocean_fluxes.jl rename to src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl new file mode 100644 index 00000000..f105311b --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl @@ -0,0 +1,212 @@ +using Oceananigans.Utils: prettysummary + +using CLIMAParameters +using CLIMAParameters: AliasParamDict + +using SurfaceFluxes.Parameters: SurfaceFluxesParameters, AbstractSurfaceFluxesParameters +using SurfaceFluxes.UniversalFunctions: BusingerParams + +using Thermodynamics.Parameters: AbstractThermodynamicsParameters + +# TODO: write parameter meaning here +import Thermodynamics.Parameters: + gas_constant, + molmass_dryair, + molmass_water, + kappa_d, + LH_v0, + LH_s0, + cp_v, + cp_l, + cp_i, + T_freeze, + T_triple, + T_icenuc, + press_triple, + T_0 + +##### +##### Similarity Theory bulk turbulent fluxes +##### + +struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP} <: AbstractSurfaceFluxesParameters + gravitational_acceleration :: FT + von_karman_constant :: FT + bulk_velocity_scale :: ΔU + universal_function :: UF + thermodynamics_parameters :: TP +end + +Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" + +function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) + print(io, summary(fluxes), '\n', + "├── gravitational_acceleration: ", prettysummary(fluxes.gravitational_acceleration), '\n', + "├── von_karman_constant: ", prettysummary(fluxes.von_karman_constant), '\n', + "├── bulk_velocity_scale: ", summary(fluxes.bulk_velocity_scale), '\n', + "├── universal_function: ", summary(fluxes.universal_function), '\n', + "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) +end + +function SimilarityTheoryTurbulentFluxes(FT = Float64; + gravitational_acceleration = 9.80665, + bulk_velocity_scale = nothing, + von_karman_constant = 0.4, + universal_function = default_universal_function_parameters(FT), + thermodynamics_parameters = HierarchicalThermodynamicsParameters(FT)) + + return SimilarityTheoryTurbulentFluxes(gravitational_acceleration, + von_karman_constant, + bulk_velocity_scale, + universal_function, + thermodynamics_parameters) +end + +##### +##### Thermodynamics parameters +##### + +struct ConstitutiveParameters{FT} <: AbstractThermodynamicsParameters{FT} + gas_constant :: FT + dry_air_molar_mass :: FT + water_molar_mass :: FT +end + +""" + ConstitutiveParameters(FT; gas_constant = 8.3144598, + dry_air_molar_mass = 0.02897, + water_molar_mass = 0.018015) + +Construct a set of parameters that define the density of moist air, + +```math +ρ = p / Rᵐ(q) T, +``` + +where ``p`` is pressure, ``T`` is temperature, ``q`` defines the partition +of total mass into vapor, liqiud, and ice mass fractions, and +``Rᵐ`` is the effective specific gas constant for the mixture, + +```math +Rᵐ(q) = +``` + +where + +For more information see [reference docs]. +""" +function ConstitutiveParameters(FT = Float64; + gas_constant = 8.3144598, + dry_air_molar_mass = 0.02897, + water_molar_mass = 0.018015) + + return ConstitutiveParameters(convert(FT, gas_constant), + convert(FT, dry_air_molar_mass), + convert(FT, water_molar_mass)) +end + +const CP = ConstitutiveParameters + +gas_constant(p::CP) = p.gas_constant +molmass_dryair(p::CP) = p.dry_air_molar_mass +molmass_water(p::CP) = p.water_molar_mass + +struct HeatCapacityParameters{FT} <: AbstractThermodynamicsParameters{FT} + dry_air_adiabatic_exponent :: FT + water_vapor_heat_capacity :: FT + liquid_water_heat_capacity :: FT + ice_heat_capacity :: FT +end + +function HeatCapacityParameters(FT = Float64; + dry_air_adiabatic_exponent = 2/7, + water_vapor_heat_capacity = 1859, + liquid_water_heat_capacity = 4181, + ice_heat_capacity = 2100) + + return HeatCapacityParameters(convert(FT, dry_air_adiabatic_exponent), + convert(FT, water_vapor_heat_capacity), + convert(FT, liquid_water_heat_capacity), + convert(FT, ice_heat_capacity)) +end + +const HCP = HeatCapacityParameters +cp_v(p::HCP) = p.water_vapor_heat_capacity +cp_l(p::HCP) = p.liquid_water_heat_capacity +cp_i(p::HCP) = p.ice_heat_capacity +kappa_d(p::HCP) = p.dry_air_adiabatic_exponent + +struct PhaseTransitionParameters{FT} <: AbstractThermodynamicsParameters{FT} + reference_vaporization_enthalpy :: FT + reference_sublimation_enthalpy :: FT + reference_temperature :: FT + triple_point_temperature :: FT + triple_point_pressure :: FT + water_freezing_temperature :: FT + ice_nucleation_temperature :: FT +end + +function PhaseTransitionParameters(FT = Float64; + reference_vaporization_enthalpy = 2500800, + reference_sublimation_enthalpy = 2834400, + reference_temperature = 273.16, + triple_point_temperature = 273.16, + triple_point_pressure = 611.657, + water_freezing_temperature = 273.16, + ice_nucleation_temperature = 233) + + return PhaseTransitionParameters(convert(FT, reference_vaporization_enthalpy), + convert(FT, reference_sublimation_enthalpy), + convert(FT, reference_temperature), + convert(FT, triple_point_temperature), + convert(FT, triple_point_pressure), + convert(FT, water_freezing_temperature), + convert(FT, ice_nucleation_temperature)) +end + +const PTP = PhaseTransitionParameters +LH_v0(p::PTP) = p.reference_vaporization_enthalpy +LH_s0(p::PTP) = p.reference_sublimation_enthalpy +T_freeze(p::PTP) = p.water_freezing_temperature +T_triple(p::PTP) = p.triple_point_temperature +T_icenuc(p::PTP) = p.ice_nucleation_temperature +press_triple(p::PTP) = p.triple_point_pressure +T_0(p::PTP) = p.reference_temperature + +struct HierarchicalThermodynamicsParameters{FT} <: AbstractThermodynamicsParameters{FT} + constitutive :: ConstitutiveParameters{FT} + phase_transitions :: PhaseTransitionParameters{FT} + heat_capacity :: HeatCapacityParameters{FT} +end + +function HierarchicalThermodynamicsParameters(FT = Float64; + constitutive = ConstitutiveParameters(FT), + phase_transitions = PhaseTransitionParameters(FT), + heat_capacity = HeatCapacityParameters(FT)) + + return HierarchicalThermodynamicsParameters(constitutive, phase_transitions, heat_capacity) +end + +const HTP = HierarchicalThermodynamicsParameters + +gas_constant(p::HTP) = gas_constant(p.constitutive) +molmass_dryair(p::HTP) = molmass_dryair(p.constitutive) +molmass_water(p::HTP) = molmass_water(p.constitutive) +kappa_d(p::HTP) = kappa_d(p.heat_capacity) +LH_v0(p::HTP) = LH_v0(p.phase_transitions) +LH_s0(p::HTP) = LH_s0(p.phase_transitions) +cp_v(p::HTP) = cp_v(p.heat_capacity) +cp_l(p::HTP) = cp_l(p.heat_capacity) +cp_i(p::HTP) = cp_i(p.heat_capacity) +T_freeze(p::HTP) = T_freeze(p.phase_transitions) +T_triple(p::HTP) = T_triple(p.phase_transitions) +T_icenuc(p::HTP) = T_icenuc(p.phase_transitions) +press_triple(p::HTP) = press_triple(p.phase_transitions) +T_0(p::HTP) = T_0(p.phase_transitions) + +default_universal_function_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), + a_m = convert(FT, 4.7), + a_h = convert(FT, 4.7), + ζ_a = convert(FT, 2.5), + γ = convert(FT, 4.42)) + diff --git a/src/OceanSeaIceModels/surface_radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/surface_radiation.jl similarity index 100% rename from src/OceanSeaIceModels/surface_radiation.jl rename to src/OceanSeaIceModels/CrossRealmFluxes/surface_radiation.jl diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 2cd5f452..5e0e2b54 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -1,12 +1,17 @@ module OceanSeaIceModels +using Oceananigans +using SeawaterPolynomials + using Oceananigans.Operators +using Oceananigans.Utils: launch!, Time using Oceananigans.Architectures: architecture using Oceananigans.BoundaryConditions: fill_halo_regions!, BoundaryCondition -using Oceananigans.Models: AbstractModel +using Oceananigans.Grids: architecture using Oceananigans.TimeSteppers: tick! -using Oceananigans.Utils: launch! +using Oceananigans.Models: AbstractModel +using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll @@ -20,17 +25,6 @@ import Oceananigans.Simulations: reset!, initialize!, iteration import Oceananigans.TimeSteppers: time_step!, update_state!, time import Oceananigans.Utils: prettytime -# We should not declare these; they need to be settable. -# const ℒₑ = 2.5e6 # J/kg Latent heat of evaporation -# const σᴮ = 5.67e-8 # W/m²/K⁴ Stefan-Boltzmann constant - -using Oceananigans -using Oceananigans.Utils: Time -using Oceananigans.Grids: architecture -using Oceananigans.Models: AbstractModel - -using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries - const SomeKindOfFieldTimeSeries = Union{FieldTimeSeries, GPUAdaptedFieldTimeSeries} @@ -41,20 +35,18 @@ function surface_tracers end function sea_ice_thickness end function downwelling_radiation end function freshwater_flux end -function specific_heat end +function heat_capacity end function density end ##### ##### Some implementation ##### -include("ocean_sea_ice_model_fluxes.jl") -include("ocean_sea_ice_surfaces.jl") -include("surface_radiation.jl") -include("atmosphere_sea_ice_fluxes.jl") -include("atmosphere_ocean_momentum_flux.jl") +include("CrossRealmFluxes/CrossRealmFluxes.jl") + +using .CrossRealmFluxes + include("compute_atmosphere_ocean_fluxes.jl") -include("sea_ice_ocean_fluxes.jl") include("ocean_sea_ice_model.jl") include("ocean_only_model.jl") diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl index 4b6b34b0..cf77dd30 100644 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl @@ -143,12 +143,11 @@ end Qu = net_upwelling_radiation(i, j, grid, time, surface_radiation, ocean_state) Q★ = cross_realm_flux(i, j, grid, time, Q_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) Q = Q★ + Qd + Qu - #Q = Qd + Qu # Compute salinity fluxes, bulk flux first Fp = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) F★ = cross_realm_flux(i, j, grid, time, F_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) - F = 0 #F★ + Fp + F = F★ + Fp # Then the rest of the heat fluxes ρₒ = ocean_reference_density @@ -157,7 +156,9 @@ end atmos_ocean_Jᵘ = τˣ / ρₒ atmos_ocean_Jᵛ = τʸ / ρₒ atmos_ocean_Jᵀ = Q / (ρₒ * cₚ) - atmos_ocean_Jˢ = F + + S = ocean_state_ij.S + atmos_ocean_Jˢ = S * F @inbounds begin # Set fluxes diff --git a/src/OceanSeaIceModels/getflux.jl b/src/OceanSeaIceModels/getflux.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 5e1681af..d8b3851f 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -5,13 +5,12 @@ using Oceananigans.BuoyancyModels: SeawaterBuoyancy using SeawaterPolynomials: TEOS10EquationOfState -struct OceanSeaIceModel{FT, I, A, O, S, F, PI, PC, C, G} <: AbstractModel{Nothing} +struct OceanSeaIceModel{FT, I, A, O, F, PI, PC, C, G} <: AbstractModel{Nothing} clock :: C - grid :: G # TODO: make it so Oceananigans.Ssimulation does not require this + grid :: G # TODO: make it so Oceananigans.Simulation does not require this atmosphere :: A sea_ice :: I ocean :: O - surfaces :: S fluxes :: F previous_ice_thickness :: PI previous_ice_concentration :: PC @@ -22,28 +21,31 @@ end const OSIM = OceanSeaIceModel -Base.summary(::OSIM) = "OceanSeaIceModel" -prettytime(model::OSIM) = prettytime(model.clock.time) -iteration(model::OSIM) = model.clock.iteration -timestepper(::OSIM) = nothing -reset!(::OSIM) = nothing -initialize!(::OSIM) = nothing +Base.summary(::OSIM) = "OceanSeaIceModel" +prettytime(model::OSIM) = prettytime(model.clock.time) +iteration(model::OSIM) = model.clock.iteration +timestepper(::OSIM) = nothing +reset!(::OSIM) = nothing +initialize!(::OSIM) = nothing default_included_properties(::OSIM) = tuple() -prognostic_fields(cm::OSIM) = nothing -fields(::OSIM) = NamedTuple() -default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) +prognostic_fields(cm::OSIM) = nothing +fields(::OSIM) = NamedTuple() +default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) + +reference_density(unsupported) = throw(ArgumentError("Cannot extract reference density from $(typeof(unsupported))")) +heat_capacity(unsupported) = throw(ArgumentError("Cannot deduce the heat capacity from $(typeof(unsupported))")) reference_density(ocean::Simulation) = reference_density(ocean.model.buoyancy.model) reference_density(buoyancy_model::SeawaterBuoyancy) = reference_density(buoyancy_model.equation_of_state) -#reference_density(unsupported) = throw(ArgumentError("Cannot extract reference density from $(typeof(unsupported))")) -#reference_density(eos::TEOS10EquationOfState) = eos.reference_density -reference_density(eos) = eos.reference_density +reference_density(eos::TEOS10EquationOfState) = eos.reference_density heat_capacity(ocean::Simulation) = heat_capacity(ocean.model.buoyancy.model) heat_capacity(buoyancy_model::SeawaterBuoyancy) = heat_capacity(buoyancy_model.equation_of_state) -#heat_capacity(unsupported) = throw(ArgumentError("Cannot deduce the heat capacity from $(typeof(unsupported))")) -#heat_capacity(eos::TEOS10EquationOfState) = 3991 # get the right value in here eventually -heat_capacity(eos) = 3991 # get the right value in here eventually + +function heat_capacity(eos::TEOS10EquationOfState{FT}) where FT + cₚ⁰ = SeawaterPolynomials.TEOS10.teos10_reference_heat_capacity + return convert(FT, cₚ⁰) +end function OceanSeaIceModel(ocean, sea_ice=nothing; atmosphere = nothing, @@ -60,17 +62,11 @@ function OceanSeaIceModel(ocean, sea_ice=nothing; previous_ice_concentration = deepcopy(sea_ice.model.ice_concentration) end - grid = ocean.model.grid - ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) - ice_ocean_salt_flux = Field{Center, Center, Nothing}(grid) - # Contains information about flux contributions: bulk formula, prescribed # fluxes, etc. - fluxes = OceanSeaIceModelFluxes(eltype(grid); surface_radiation) - - # Contains a reference to the Fields holding net surface fluxes: - # ocean top surface, and both top and bottom sea ice surfaces - surfaces = OceanSeaIceSurfaces(ocean, sea_ice) + fluxes = OceanSeaIceSurfaceFluxes(ocean, sea_ice; + atmosphere, + surface_radiation) FT = eltype(ocean.model.grid) @@ -79,7 +75,6 @@ function OceanSeaIceModel(ocean, sea_ice=nothing; atmosphere, sea_ice, ocean, - surfaces, fluxes, previous_ice_thickness, previous_ice_concentration, From 8c9ac2408060036910f86a9bf22791210934091c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 9 Jan 2024 20:36:17 -0700 Subject: [PATCH 053/182] Fluxes coming together --- .../prototype_omip_simulation/Manifest.toml | 4 +- .../omip_atmosphere.jl | 17 +- .../single_column_omip_simulation.jl | 6 +- src/DataWrangling/JRA55.jl | 15 +- .../CrossRealmFluxes/CrossRealmFluxes.jl | 26 +- .../compute_atmosphere_ocean_fluxes.jl | 0 .../ocean_sea_ice_surface_fluxes.jl | 445 ++++++++++++++++-- .../CrossRealmFluxes/radiation.jl | 37 ++ .../similarity_theory_surface_fluxes.jl | 202 ++------ .../CrossRealmFluxes/surface_radiation.jl | 37 -- src/OceanSeaIceModels/OceanSeaIceModels.jl | 41 +- .../PrescribedAtmospheres.jl | 277 ++++++++++- .../compute_atmosphere_ocean_fluxes.jl | 192 -------- src/OceanSeaIceModels/ocean_only_model.jl | 2 +- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 114 ++--- .../time_step_ocean_sea_ice_model.jl | 50 ++ 16 files changed, 877 insertions(+), 588 deletions(-) create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/compute_atmosphere_ocean_fluxes.jl create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl delete mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/surface_radiation.jl delete mode 100644 src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl create mode 100644 src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 28f2786b..58cf6a36 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1253,7 +1253,9 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -path = "/Users/gregorywagner/Projects/Oceananigans.jl" +git-tree-sha1 = "eeca396589a53c957bcf5a9847e02c2eb915fe29" +repo-rev = "glw/better-interpolate2" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.4" diff --git a/experiments/prototype_omip_simulation/omip_atmosphere.jl b/experiments/prototype_omip_simulation/omip_atmosphere.jl index b7bab00e..83ed8749 100644 --- a/experiments/prototype_omip_simulation/omip_atmosphere.jl +++ b/experiments/prototype_omip_simulation/omip_atmosphere.jl @@ -6,12 +6,15 @@ using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, TwoStreamDownwellingRadiation -function prescribed_jra55_atmosphere(grid, time_indices=:) +function prescribed_jra55_atmosphere(grid, time_indices=:; + reference_height = 2) # meters + architecture = Oceananigans.architecture(grid) - u_jra55 = jra55_field_time_series(:eastward_velocity, grid; time_indices, architecture, location=(Face, Center)) - v_jra55 = jra55_field_time_series(:northward_velocity, grid; time_indices, architecture, location=(Center, Face)) + u_jra55 = jra55_field_time_series(:eastward_velocity, grid; time_indices, architecture) + v_jra55 = jra55_field_time_series(:northward_velocity, grid; time_indices, architecture) T_jra55 = jra55_field_time_series(:temperature, grid; time_indices, architecture) + p_jra55 = jra55_field_time_series(:surface_pressure, grid; time_indices, architecture) q_jra55 = jra55_field_time_series(:specific_humidity, grid; time_indices, architecture) Fr_jra55 = jra55_field_time_series(:freshwater_rain_flux, grid; time_indices, architecture) Fs_jra55 = jra55_field_time_series(:freshwater_snow_flux, grid; time_indices, architecture) @@ -34,7 +37,13 @@ function prescribed_jra55_atmosphere(grid, time_indices=:) icebergs = Fi_jra55) downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qsw_jra55) - atmosphere = PrescribedAtmosphere(times; velocities, freshwater_flux, tracers, downwelling_radiation) + + atmosphere = PrescribedAtmosphere(times; velocities, + freshwater_flux, + tracers, + downwelling_radiation, + reference_height, + pressure = p_jra55) return atmosphere end diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 49378b3b..8a862b1c 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -3,7 +3,7 @@ using Oceananigans.Units using Oceananigans.BuoyancyModels: buoyancy_frequency using ClimaOcean -using ClimaOcean.OceanSeaIceModels: SurfaceRadiation +using ClimaOcean.OceanSeaIceModels: Radiation using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere using ClimaOcean.DataWrangling.ECCO2: ecco2_field @@ -133,8 +133,8 @@ display(fig) =# sea_ice = nothing -surface_radiation = SurfaceRadiation() -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, surface_radiation) +radiation = Radiation() +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) #= coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 90days) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index eb837644..fe234d99 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -299,13 +299,14 @@ function jra55_field_time_series(variable_name, grid=nothing; end # TODO: allow the user to pass dates -function jra55_prescribed_atmosphere(grid, time_indices=:) +function jra55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # meters architecture = Oceananigans.architecture(grid) u_jra55 = jra55_field_time_series(:eastward_velocity, grid; time_indices, architecture, location=(Face, Center)) v_jra55 = jra55_field_time_series(:northward_velocity, grid; time_indices, architecture, location=(Center, Face)) T_jra55 = jra55_field_time_series(:temperature, grid; time_indices, architecture) q_jra55 = jra55_field_time_series(:specific_humidity, grid; time_indices, architecture) + p_jra55 = jra55_field_time_series(:sea_level_pressure, grid; time_indices, architecture) Fr_jra55 = jra55_field_time_series(:freshwater_rain_flux, grid; time_indices, architecture) Fs_jra55 = jra55_field_time_series(:freshwater_snow_flux, grid; time_indices, architecture) Qlw_jra55 = jra55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) @@ -326,12 +327,20 @@ function jra55_prescribed_atmosphere(grid, time_indices=:) freshwater_flux = (rain = Fr_jra55, snow = Fs_jra55) - # rivers = Fv_jra55, # icebergs = Fi_jra55) + + pressure = p_jra55 downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qlw_jra55) - atmosphere = PrescribedAtmosphere(times; velocities, freshwater_flux, tracers, downwelling_radiation) + + atmosphere = PrescribedAtmosphere(times, eltype(grid); + velocities, + freshwater_flux, + tracers, + downwelling_radiation, + reference_height, + pressure) return atmosphere end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index b52ccabb..4a6cd6de 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -2,11 +2,14 @@ module CrossRealmFluxes using Oceananigans -export SurfaceRadiation, +export Radiation, OceanSeaIceSurfaceFluxes using ..OceanSeaIceModels: SKOFTS +import ..OceanSeaIceModels: surface_velocities, + surface_tracers + ##### ##### Utilities ##### @@ -38,9 +41,28 @@ function surface_flux(f::Field) end end -include("surface_radiation.jl") +function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + u = view(ocean.model.velocities.u.data, :, :, Nz) + v = view(ocean.model.velocities.v.data, :, :, Nz) + w = view(ocean.model.velocities.w.data, :, :, Nz+1) + return (; u, v, w) +end + +function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + tracers = ocean.model.tracers + names = keys(tracers) + sfc_tracers = NamedTuple(name => view(tracers[name].data, :, :, Nz) for name in names) + return sfc_tracers +end + +include("radiation.jl") include("similarity_theory_surface_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") +include("compute_atmosphere_ocean_fluxes.jl") # include("ocean_sea_ice_model_fluxes.jl") # include("ocean_sea_ice_surfaces.jl") diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/compute_atmosphere_ocean_fluxes.jl new file mode 100644 index 00000000..e69de29b diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 5486361b..ea318039 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -1,15 +1,39 @@ -using Oceananigans.Models.HydrostaticFreeSurfaceModels: HydrostaticFreeSurfaceModel -using ClimaSeaIce.SlabSeaIceModels: SlabSeaIceModel +using StaticArrays +using Thermodynamics +using SurfaceFluxes + +using ..OceanSeaIceModels: reference_density, + heat_capacity, + sea_ice_thickness, + downwelling_radiation, + freshwater_flux + +using ClimaSeaIce: SlabSeaIceModel + +using Oceananigans: HydrostaticFreeSurfaceModel, architecture +using Oceananigans.Grids: inactive_node +using Oceananigans.BoundaryConditions: fill_halo_regions! +using Oceananigans.Fields: ConstantField +using Oceananigans.Utils: launch!, Time + +using Oceananigans.Operators: ℑxᶜᵃᵃ, ℑyᵃᶜᵃ + +using KernelAbstractions: @kernel, @index ##### ##### Container for organizing information related to fluxes ##### -struct OceanSeaIceSurfaceFluxes{C, R, T, P} - total :: C - emitted_radiation :: R +struct OceanSeaIceSurfaceFluxes{T, P, C, R, PI, PC, FT} turbulent :: T prescribed :: P + total :: C + radiation :: R + previous_ice_thickness :: PI + previous_ice_concentration :: PC + # The ocean is Boussinesq, so these are _only_ coupled properties: + ocean_reference_density :: FT + ocean_heat_capacity :: FT end Base.summary(crf::OceanSeaIceSurfaceFluxes) = "OceanSeaIceSurfaceFluxes" @@ -17,18 +41,359 @@ Base.show(io::IO, crf::OceanSeaIceSurfaceFluxes) = print(io, summary(crf)) function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; atmosphere = nothing, - surface_radiation = nothing) + radiation = nothing, + ocean_reference_density = reference_density(ocean), + ocean_heat_capacity = heat_capacity(ocean)) FT = eltype(ocean.model.grid) - turbulent_fluxes = SimilarityTheoryTurbulentFluxes(FT) + + ocean_reference_density = convert(FT, ocean_reference_density) + ocean_heat_capacity = convert(FT, ocean_heat_capacity) + + # It's the "thermodynamics gravitational acceleration" + # (as opposed to the one used for the free surface) + g = ocean.model.buoyancy.model.gravitational_acceleration + turbulent_fluxes = SimilarityTheoryTurbulentFluxes(FT, gravitational_acceleration=g) + prescribed_fluxes = nothing - return OceanSeaIceSurfaceFluxes(nothing, - surface_radiation, - turbulent_fluxes, - prescribed_fluxes) + if isnothing(sea_ice) + previous_ice_thickness = nothing + previous_ice_concentration = nothing + else + previous_ice_thickness = deepcopy(sea_ice.model.ice_thickness) + previous_ice_concentration = deepcopy(sea_ice.model.ice_concentration) + end + + ocean_grid = ocean.model.grid + ρₒ = ocean_reference_density + Jᵘ = surface_flux(ocean.model.velocities.u) + Jᵛ = surface_flux(ocean.model.velocities.v) + Jᵘᶜᶜᶜ = Field{Center, Center, Nothing}(ocean_grid) + Jᵛᶜᶜᶜ = Field{Center, Center, Nothing}(ocean_grid) + + ocean_momentum_fluxes = (u = Jᵘ, # fluxes used in the model + v = Jᵛ, # + τˣ = ρₒ * Jᵘ, # momentum fluxes multiplied by reference density + τʸ = ρₒ * Jᵛ, # + uᶜᶜᶜ = Jᵘᶜᶜᶜ, # fluxes computed by bulk formula at cell centers + vᶜᶜᶜ = Jᵛᶜᶜᶜ) + + tracers = ocean.model.tracers + ocean_tracer_fluxes = NamedTuple(name => surface_flux(tracers[name]) for name in keys(tracers)) + + cₚ = ocean_heat_capacity + ocean_heat_flux = ρₒ * cₚ * ocean_tracer_fluxes.T + + total_ocean_fluxes = (momentum = ocean_momentum_fluxes, + tracers = ocean_tracer_fluxes, + heat = ocean_heat_flux) + + total_fluxes = (; ocean=total_ocean_fluxes) + + return OceanSeaIceSurfaceFluxes(turbulent_fluxes, + prescribed_fluxes, + total_fluxes, + radiation, + previous_ice_thickness, + previous_ice_concentration, + ocean_reference_density, + ocean_heat_capacity) end +##### +##### Surface flux computation +##### + +const c = Center() +const f = Face() + +function compute_atmosphere_ocean_fluxes!(coupled_model) + ocean = coupled_model.ocean + sea_ice = coupled_model.sea_ice + atmosphere = coupled_model.atmosphere + + # Basic model properties + grid = ocean.model.grid + arch = architecture(grid) + clock = ocean.model.clock + + # Ocean, atmosphere, and sea ice state + ocean_velocities = surface_velocities(ocean) + ocean_tracers = surface_tracers(ocean) + + atmosphere_velocities = atmosphere.velocities + atmosphere_tracers = atmosphere.tracers + atmosphere_pressure = atmosphere.pressure + atmosphere_downwelling_radiation = atmosphere.downwelling_radiation + atmosphere_freshwater_flux = atmosphere.freshwater_flux + + ice_thickness = sea_ice_thickness(sea_ice) + + # Fluxes, and flux contributors + centered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.uᶜᶜᶜ, + v = coupled_model.fluxes.total.ocean.momentum.vᶜᶜᶜ) + + staggered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.u, + v = coupled_model.fluxes.total.ocean.momentum.v) + + net_tracer_fluxes = coupled_model.fluxes.total.ocean.tracers + turbulent_fluxes = coupled_model.fluxes.turbulent + prescribed_fluxes = coupled_model.fluxes.prescribed + radiation_properties = coupled_model.fluxes.radiation + + ocean_state = merge(ocean_velocities, ocean_tracers) + atmosphere_state = merge(atmosphere_velocities, atmosphere_tracers, (; p=atmosphere_pressure)) + + launch!(arch, grid, :xy, compute_atmosphere_ocean_turbulent_fluxes!, + grid, clock, + centered_velocity_fluxes, + net_tracer_fluxes, + turbulent_fluxes, + atmosphere_freshwater_flux, + atmosphere_downwelling_radiation, + radiation_properties, + ocean_state, + atmosphere_state, + atmosphere.reference_height, # height at which the state is known + atmosphere.thermodynamics_parameters, + coupled_model.fluxes.ocean_reference_density, + coupled_model.fluxes.ocean_heat_capacity, + ice_thickness) + + # Note: I think this can be avoided if we modify the preceding kernel + # to compute from 0:Nx+1, ie in halo regions + fill_halo_regions!(centered_velocity_fluxes) + + launch!(arch, grid, :xy, accumulate_atmosphere_ocean_fluxes!, + grid, clock, + staggered_velocity_fluxes, + net_tracer_fluxes, + centered_velocity_fluxes, + prescribed_fluxes, + ocean_state, + atmosphere_state, + atmosphere_downwelling_radiation, + radiation_properties, + atmosphere_freshwater_flux, + coupled_model.fluxes.ocean_reference_density, + coupled_model.fluxes.ocean_heat_capacity, + ice_thickness) + + return nothing +end + +@kernel function compute_atmosphere_ocean_turbulent_fluxes!(grid, + clock, + centered_velocity_fluxes, + net_tracer_fluxes, + turbulent_fluxes, + prescribed_freshwater_flux, + downwelling_radiation, + radiation_properties, + ocean_state, + atmos_state, + atmosphere_reference_height, + atmosphere_thermodynamics_parameters, + ocean_reference_density, + ocean_heat_capacity, + ice_thickness) + + i, j = @index(Global, NTuple) + + time = Time(clock.time) + + # Extract state variables at cell centers + @inbounds begin + # Ocean state + uₒ = ℑxᶜᵃᵃ(i, j, 1, grid, ocean_state.u) + vₒ = ℑyᵃᶜᵃ(i, j, 1, grid, ocean_state.v) + Uₒ = SVector(uₒ, vₒ) + Tₒ = ocean_state.T[i, j, 1] + Sₒ = ocean_state.S[i, j, 1] + + # Atmos state + uₐ = atmos_state.u[i, j, 1, time] + vₐ = atmos_state.v[i, j, 1, time] + Uₐ = SVector(uₐ, vₐ) + + Tₐ = atmos_state.T[i, j, 1, time] + pₐ = atmos_state.p[i, j, 1, time] + qᵗₐ = atmos_state.q[i, j, 1] # total specific humidity + end + + # Build atmospheric state + ℂ = atmosphere_thermodynamics_parameters + ψₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₐ, qᵗₐ) + + # Build surface state with saturated specific humidity + surface_type = AtmosphericThermodynamics.Liquid() + q★ = surface_saturation_specific_humidity(ℂ, Tₒ, ψₐ, surface_type) + + # Thermodynamic and dynamic state at the surface + ψ₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₒ, q★) + Ψ₀ = dynamic_surface_state = SurfaceFluxes.StateValues(zero(grid), Uₒ, ψ₀) + + # Thermodynamic and dynamic state at reference level h above the surface + h = atmosphere_reference_height # elevation of atmos variables relative to surface + Ψₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(h, Uₐ, ψₐ) + + # Roughness lengths... + zᵐ = convert(eltype(grid), 1e-2) + zʰ = convert(eltype(grid), 1e-2) + + values = SurfaceFluxes.ValuesOnly(Ψₐ, Ψ₀, zᵐ, zʰ) + conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + + # Compute heat fluxes, bulk flux first + Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation_properties) + Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state) + Qs = conditions.shf + Qℓ = conditions.lhf + ΣQ = Qu + Qs + Qℓ + + E = conditions.evaporation + F = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) + + @show conditions + + Jᵘ = centered_velocity_fluxes.u + Jᵛ = centered_velocity_fluxes.v + Jᵀ = net_tracer_fluxes.T + Jˢ = net_tracer_fluxes.S + + ρₒ = ocean_reference_density + cₒ = ocean_heat_capacity + + atmos_ocean_Jᵘ = conditions.ρτxz / ρₒ + atmos_ocean_Jᵛ = conditions.ρτyz / ρₒ + atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) + atmos_ocean_Jˢ = Sₒ * (E + F) + + kᴺ = size(grid, 3) # index of the top ocean cell + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) + + @inbounds begin + Jᵘ[i, j, 1] = ifelse(inactive, zero(grid), atmos_ocean_Jᵘ) + Jᵛ[i, j, 1] = ifelse(inactive, zero(grid), atmos_ocean_Jᵛ) + Jᵀ[i, j, 1] = ifelse(inactive, zero(grid), atmos_ocean_Jᵀ) + Jˢ[i, j, 1] = ifelse(inactive, zero(grid), atmos_ocean_Jˢ) + end +end + +@kernel function accumulate_atmosphere_ocean_fluxes!(grid, + clock, + staggered_velocity_fluxes, + centered_velocity_fluxes) + + i, j = @index(Global, NTuple) + kᴺ = size(grid, 3) # index of the top ocean cell + + time = Time(clock.time) + + Jᵘ = staggered_velocity_fluxes.u + Jᵛ = staggered_velocity_fluxes.v + + @inbounds begin + Jᵘ[i, j, 1] = ℑxᶠᵃᵃ(i, j, k, grid, centered_velocity_fluxes.u) + Jᵛ[i, j, 1] = ℑyᵃᶠᵃ(i, j, k, grid, centered_velocity_fluxes.v) + end + + #= + # Note: there could one or more formula(e) + τˣ_formula = bulk_momentum_flux_formulae.u + τʸ_formula = bulk_momentum_flux_formulae.v + Q_formula = bulk_heat_flux_formulae + F_formula = bulk_tracer_flux_formulae.S + + atmos_state_names = keys(atmos_state) + ocean_state_names = keys(atmos_state) + + atmos_state_ij = stateindex(atmos_state, i, j, 1, time) + ocean_state_ij = stateindex(ocean_state, i, j, 1, time) + + # Compute transfer velocity scale + ΔUᶠᶜᶜ = bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) + ΔUᶜᶠᶜ = bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) + ΔUᶜᶜᶜ = bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) + + # Compute momentum fluxes + τˣ = cross_realm_flux(i, j, grid, time, τˣ_formula, ΔUᶠᶜᶜ, atmos_state, ocean_state) + τʸ = cross_realm_flux(i, j, grid, time, τʸ_formula, ΔUᶜᶠᶜ, atmos_state, ocean_state) + + # Compute heat fluxes, bulk flux first + Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation) + + Qu = net_upwelling_radiation(i, j, grid, time, radiation, ocean_state) + Q★ = cross_realm_flux(i, j, grid, time, Q_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) + Q = Q★ + Qd + Qu + + # Compute salinity fluxes, bulk flux first + Fp = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) + F★ = cross_realm_flux(i, j, grid, time, F_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) + F = F★ + Fp + + # Then the rest of the heat fluxes + ρₒ = ocean_reference_density + cₚ = ocean_heat_capacity + + atmos_ocean_Jᵘ = τˣ / ρₒ + atmos_ocean_Jᵛ = τʸ / ρₒ + atmos_ocean_Jᵀ = Q / (ρₒ * cₚ) + + S = ocean_state_ij.S + atmos_ocean_Jˢ = S * F + + @inbounds begin + # Set fluxes + # TODO: should this be peripheral_node? + Jᵘ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, f, c, c), zero(grid), atmos_ocean_Jᵘ) + Jᵛ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, f, c), zero(grid), atmos_ocean_Jᵛ) + Jᵀ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jᵀ) + Jˢ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jˢ) + end + =# +end + +@inline function net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation) + Qˢʷ = downwelling_radiation.shortwave + Qˡʷ = downwelling_radiation.longwave + α = stateindex(radiation.reflection.ocean, i, j, 1, time) + + return @inbounds - (1 - α) * Qˢʷ[i, j, 1, time] - Qˡʷ[i, j, 1, time] +end + +@inline function net_upwelling_radiation(i, j, grid, time, radiation, ocean_state) + σ = radiation.stefan_boltzmann_constant + Tᵣ = radiation.reference_temperature + ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) + + # Ocean surface temperature (departure from reference, typically in ᵒC) + Tₒ = @inbounds ocean_state.T[i, j, 1] + + # Note: positive implies _upward_ heat flux, and therefore cooling. + return σ * ϵ * (Tₒ + Tᵣ)^4 +end + +@inline cross_realm_flux(i, j, grid, time, ::Nothing, args...) = zero(grid) +@inline cross_realm_flux(i, j, grid, time, a::AbstractArray, args...) = stateindex(a, i, j, 1, time) +@inline cross_realm_flux(i, j, grid, time, nt::NamedTuple, args...) = cross_realm_flux(i, j, grid, time, values(nt), args...) + +@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any}, args...) = + cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) + +@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any, <:Any}, args...) = + cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[3], args...) + +@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = + cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[3], args...) + + cross_realm_flux(i, j, grid, time, flux_tuple[4], args...) + #= function default_atmosphere_ocean_fluxes(FT=Float64, tracers=tuple(:S)) # Note: we are constantly coping with the fact that the ocean is ᵒC. @@ -97,25 +462,6 @@ end return - ρₐ * C * Δc * ΔU end -@inline cross_realm_flux(i, j, grid, time, ::Nothing, args...) = zero(grid) -@inline cross_realm_flux(i, j, grid, time, a::AbstractArray, args...) = stateindex(a, i, j, 1, time) -@inline cross_realm_flux(i, j, grid, time, nt::NamedTuple, args...) = cross_realm_flux(i, j, grid, time, values(nt), args...) - -@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any}, args...) = - cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) - -@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any, <:Any}, args...) = - cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[3], args...) - -@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = - cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[3], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[4], args...) - ##### ##### Air-sea differences ##### @@ -251,8 +597,27 @@ end ##### Bulk velocity scales ##### -struct RelativeVelocityScale end +##### +##### Convenience containers for surface fluxes +##### +##### "Cross realm fluxes" can refer to the flux _data_ (ie, fields representing +##### the total flux for a given variable), or to the flux _components_ / formula. +##### + +struct CrossRealmFluxes{M, H, T} + momentum :: M + heat :: H + tracers :: T +end + +CrossRealmFluxes(; momentum=nothing, heat=nothing, tracers=nothing) = + CrossRealmFluxes(momentum, heat, tracers) + +Base.summary(osf::CrossRealmFluxes) = "CrossRealmFluxes" +Base.show(io::IO, osf::CrossRealmFluxes) = print(io, summary(osf)) + # struct AtmosphereOnlyVelocityScale end +struct RelativeVelocityScale end @inline function bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, atmos_state, ocean_state) uₐ = atmos_state.u @@ -284,24 +649,6 @@ end return sqrt(Δu² + Δv²) end -##### -##### Convenience containers for surface fluxes -##### -##### "Cross realm fluxes" can refer to the flux _data_ (ie, fields representing -##### the total flux for a given variable), or to the flux _components_ / formula. -##### - -struct CrossRealmFluxes{M, H, T} - momentum :: M - heat :: H - tracers :: T -end - -CrossRealmFluxes(; momentum=nothing, heat=nothing, tracers=nothing) = - CrossRealmFluxes(momentum, heat, tracers) - -Base.summary(osf::CrossRealmFluxes) = "CrossRealmFluxes" -Base.show(io::IO, osf::CrossRealmFluxes) = print(io, summary(osf)) =# diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl new file mode 100644 index 00000000..b7b54e0d --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -0,0 +1,37 @@ +struct Radiation{FT, E, R} + emission :: E + reflection :: R + stefan_boltzmann_constant :: FT + reference_temperature :: FT +end + +function Radiation(FT=Float64; + ocean_emissivity = 0.97, + sea_ice_emissivity = 1.0, + ocean_albedo = 0.3, + sea_ice_albedo = 0.7, + reference_temperature = 273.15, + stefan_boltzmann_constant = 5.67e-8) + + ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) + sea_ice_emissivity isa Number && (sea_ice_emissivity = convert(FT, sea_ice_emissivity)) + ocean_albedo isa Number && (ocean_albedo = convert(FT, ocean_albedo)) + sea_ice_albedo isa Number && (sea_ice_albedo = convert(FT, sea_ice_albedo)) + + emission = SurfaceProperties(ocean_emissivity, sea_ice_emissivity) + reflection = SurfaceProperties(ocean_albedo, sea_ice_albedo) + + return Radiation(emission, + reflection, + convert(FT, stefan_boltzmann_constant), + convert(FT, reference_temperature)) +end + +Base.summary(r::Radiation) = "Radiation" +Base.show(io::IO, r::Radiation) = print(io, summary(osf)) + +struct SurfaceProperties{O, I} + ocean :: O + sea_ice :: I +end + diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl index f105311b..5df717a2 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl @@ -1,32 +1,21 @@ using Oceananigans.Utils: prettysummary -using CLIMAParameters -using CLIMAParameters: AliasParamDict - using SurfaceFluxes.Parameters: SurfaceFluxesParameters, AbstractSurfaceFluxesParameters using SurfaceFluxes.UniversalFunctions: BusingerParams -using Thermodynamics.Parameters: AbstractThermodynamicsParameters +using ..PrescribedAtmospheres: PrescribedAtmosphereThermodynamicsParameters + +import Thermodynamics as AtmosphericThermodynamics -# TODO: write parameter meaning here -import Thermodynamics.Parameters: - gas_constant, - molmass_dryair, - molmass_water, - kappa_d, - LH_v0, - LH_s0, - cp_v, - cp_l, - cp_i, - T_freeze, - T_triple, - T_icenuc, - press_triple, - T_0 +import SurfaceFluxes.Parameters: + thermodynamics_params, + uf_params, + von_karman_const, + universal_func_type, + grav ##### -##### Similarity Theory bulk turbulent fluxes +##### Bulk turbulent fluxes based on similarity theory ##### struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP} <: AbstractSurfaceFluxesParameters @@ -37,23 +26,32 @@ struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP} <: AbstractSurfaceFluxes thermodynamics_parameters :: TP end +const STTF = SimilarityTheoryTurbulentFluxes +thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters +universal_func_type(fluxes::STTF) = universal_func_type(typeof(fluxes.universal_function)) +uf_params(fluxes::STTF) = fluxes.universal_function +von_karman_const(fluxes::STTF) = fluxes.von_karman_constant +grav(fluxes::STTF) = fluxes.gravitational_acceleration + Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) print(io, summary(fluxes), '\n', "├── gravitational_acceleration: ", prettysummary(fluxes.gravitational_acceleration), '\n', - "├── von_karman_constant: ", prettysummary(fluxes.von_karman_constant), '\n', - "├── bulk_velocity_scale: ", summary(fluxes.bulk_velocity_scale), '\n', - "├── universal_function: ", summary(fluxes.universal_function), '\n', - "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) + "├── von_karman_constant: ", prettysummary(fluxes.von_karman_constant), '\n', + "├── bulk_velocity_scale: ", summary(fluxes.bulk_velocity_scale), '\n', + "├── universal_function: ", summary(fluxes.universal_function), '\n', + "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) end +const PATP = PrescribedAtmosphereThermodynamicsParameters + function SimilarityTheoryTurbulentFluxes(FT = Float64; gravitational_acceleration = 9.80665, bulk_velocity_scale = nothing, von_karman_constant = 0.4, universal_function = default_universal_function_parameters(FT), - thermodynamics_parameters = HierarchicalThermodynamicsParameters(FT)) + thermodynamics_parameters = PATP(FT)) return SimilarityTheoryTurbulentFluxes(gravitational_acceleration, von_karman_constant, @@ -62,151 +60,19 @@ function SimilarityTheoryTurbulentFluxes(FT = Float64; thermodynamics_parameters) end -##### -##### Thermodynamics parameters -##### - -struct ConstitutiveParameters{FT} <: AbstractThermodynamicsParameters{FT} - gas_constant :: FT - dry_air_molar_mass :: FT - water_molar_mass :: FT -end - -""" - ConstitutiveParameters(FT; gas_constant = 8.3144598, - dry_air_molar_mass = 0.02897, - water_molar_mass = 0.018015) - -Construct a set of parameters that define the density of moist air, - -```math -ρ = p / Rᵐ(q) T, -``` - -where ``p`` is pressure, ``T`` is temperature, ``q`` defines the partition -of total mass into vapor, liqiud, and ice mass fractions, and -``Rᵐ`` is the effective specific gas constant for the mixture, - -```math -Rᵐ(q) = -``` - -where - -For more information see [reference docs]. -""" -function ConstitutiveParameters(FT = Float64; - gas_constant = 8.3144598, - dry_air_molar_mass = 0.02897, - water_molar_mass = 0.018015) - - return ConstitutiveParameters(convert(FT, gas_constant), - convert(FT, dry_air_molar_mass), - convert(FT, water_molar_mass)) -end - -const CP = ConstitutiveParameters - -gas_constant(p::CP) = p.gas_constant -molmass_dryair(p::CP) = p.dry_air_molar_mass -molmass_water(p::CP) = p.water_molar_mass - -struct HeatCapacityParameters{FT} <: AbstractThermodynamicsParameters{FT} - dry_air_adiabatic_exponent :: FT - water_vapor_heat_capacity :: FT - liquid_water_heat_capacity :: FT - ice_heat_capacity :: FT -end - -function HeatCapacityParameters(FT = Float64; - dry_air_adiabatic_exponent = 2/7, - water_vapor_heat_capacity = 1859, - liquid_water_heat_capacity = 4181, - ice_heat_capacity = 2100) - - return HeatCapacityParameters(convert(FT, dry_air_adiabatic_exponent), - convert(FT, water_vapor_heat_capacity), - convert(FT, liquid_water_heat_capacity), - convert(FT, ice_heat_capacity)) -end - -const HCP = HeatCapacityParameters -cp_v(p::HCP) = p.water_vapor_heat_capacity -cp_l(p::HCP) = p.liquid_water_heat_capacity -cp_i(p::HCP) = p.ice_heat_capacity -kappa_d(p::HCP) = p.dry_air_adiabatic_exponent - -struct PhaseTransitionParameters{FT} <: AbstractThermodynamicsParameters{FT} - reference_vaporization_enthalpy :: FT - reference_sublimation_enthalpy :: FT - reference_temperature :: FT - triple_point_temperature :: FT - triple_point_pressure :: FT - water_freezing_temperature :: FT - ice_nucleation_temperature :: FT -end - -function PhaseTransitionParameters(FT = Float64; - reference_vaporization_enthalpy = 2500800, - reference_sublimation_enthalpy = 2834400, - reference_temperature = 273.16, - triple_point_temperature = 273.16, - triple_point_pressure = 611.657, - water_freezing_temperature = 273.16, - ice_nucleation_temperature = 233) - - return PhaseTransitionParameters(convert(FT, reference_vaporization_enthalpy), - convert(FT, reference_sublimation_enthalpy), - convert(FT, reference_temperature), - convert(FT, triple_point_temperature), - convert(FT, triple_point_pressure), - convert(FT, water_freezing_temperature), - convert(FT, ice_nucleation_temperature)) -end - -const PTP = PhaseTransitionParameters -LH_v0(p::PTP) = p.reference_vaporization_enthalpy -LH_s0(p::PTP) = p.reference_sublimation_enthalpy -T_freeze(p::PTP) = p.water_freezing_temperature -T_triple(p::PTP) = p.triple_point_temperature -T_icenuc(p::PTP) = p.ice_nucleation_temperature -press_triple(p::PTP) = p.triple_point_pressure -T_0(p::PTP) = p.reference_temperature - -struct HierarchicalThermodynamicsParameters{FT} <: AbstractThermodynamicsParameters{FT} - constitutive :: ConstitutiveParameters{FT} - phase_transitions :: PhaseTransitionParameters{FT} - heat_capacity :: HeatCapacityParameters{FT} -end - -function HierarchicalThermodynamicsParameters(FT = Float64; - constitutive = ConstitutiveParameters(FT), - phase_transitions = PhaseTransitionParameters(FT), - heat_capacity = HeatCapacityParameters(FT)) - - return HierarchicalThermodynamicsParameters(constitutive, phase_transitions, heat_capacity) -end - -const HTP = HierarchicalThermodynamicsParameters - -gas_constant(p::HTP) = gas_constant(p.constitutive) -molmass_dryair(p::HTP) = molmass_dryair(p.constitutive) -molmass_water(p::HTP) = molmass_water(p.constitutive) -kappa_d(p::HTP) = kappa_d(p.heat_capacity) -LH_v0(p::HTP) = LH_v0(p.phase_transitions) -LH_s0(p::HTP) = LH_s0(p.phase_transitions) -cp_v(p::HTP) = cp_v(p.heat_capacity) -cp_l(p::HTP) = cp_l(p.heat_capacity) -cp_i(p::HTP) = cp_i(p.heat_capacity) -T_freeze(p::HTP) = T_freeze(p.phase_transitions) -T_triple(p::HTP) = T_triple(p.phase_transitions) -T_icenuc(p::HTP) = T_icenuc(p.phase_transitions) -press_triple(p::HTP) = press_triple(p.phase_transitions) -T_0(p::HTP) = T_0(p.phase_transitions) - +# See SurfaceFluxes.jl for other parameter set options. default_universal_function_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), a_m = convert(FT, 4.7), a_h = convert(FT, 4.7), ζ_a = convert(FT, 2.5), γ = convert(FT, 4.42)) +function surface_saturation_specific_humidity(params, surface_temperature, atmos_state, surface_type) + Tₛ = surface_temperature + ρₛ = atmos_state.ρ # should we extrapolate to obtain this? + p★ = AtmosphericThermodynamics.saturation_vapor_pressure(params, Tₛ, surface_type) + q★ = AtmosphericThermodynamics.q_vap_saturation_from_density(params, Tₛ, ρₛ, p★) + q★ *= 0.98 # TODO: understand this better... + return q★ +end + diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/surface_radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/surface_radiation.jl deleted file mode 100644 index e27d9dce..00000000 --- a/src/OceanSeaIceModels/CrossRealmFluxes/surface_radiation.jl +++ /dev/null @@ -1,37 +0,0 @@ -struct SurfaceRadiation{FT, E, R} - emission :: E - reflection :: R - stefan_boltzmann_constant :: FT - reference_temperature :: FT -end - -function SurfaceRadiation(FT=Float64; - ocean_emissivity = 0.97, - sea_ice_emissivity = 1.0, - ocean_albedo = 0.3, - sea_ice_albedo = 0.7, - reference_temperature = 273.15, - stefan_boltzmann_constant = 5.67e-8) - - ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) - sea_ice_emissivity isa Number && (sea_ice_emissivity = convert(FT, sea_ice_emissivity)) - ocean_albedo isa Number && (ocean_albedo = convert(FT, ocean_albedo)) - sea_ice_albedo isa Number && (sea_ice_albedo = convert(FT, sea_ice_albedo)) - - emission = SurfaceProperties(ocean_emissivity, sea_ice_emissivity) - reflection = SurfaceProperties(ocean_albedo, sea_ice_albedo) - - return SurfaceRadiation(emission, - reflection, - convert(FT, stefan_boltzmann_constant), - convert(FT, reference_temperature)) -end - -Base.summary(r::SurfaceRadiation) = "SurfaceRadiation" -Base.show(io::IO, r::SurfaceRadiation) = print(io, summary(osf)) - -struct SurfaceProperties{O, I} - ocean :: O - sea_ice :: I -end - diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 5e0e2b54..12f72314 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -16,15 +16,6 @@ using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll -# Simulations interface -import Oceananigans: fields, prognostic_fields -import Oceananigans.Fields: set! -import Oceananigans.Models: timestepper, NaNChecker, default_nan_checker -import Oceananigans.OutputWriters: default_included_properties -import Oceananigans.Simulations: reset!, initialize!, iteration -import Oceananigans.TimeSteppers: time_step!, update_state!, time -import Oceananigans.Utils: prettytime - const SomeKindOfFieldTimeSeries = Union{FieldTimeSeries, GPUAdaptedFieldTimeSeries} @@ -32,42 +23,36 @@ const SKOFTS = SomeKindOfFieldTimeSeries function surface_velocities end function surface_tracers end -function sea_ice_thickness end function downwelling_radiation end function freshwater_flux end +function reference_density end function heat_capacity end -function density end + +sea_ice_thickness(::Nothing) = nothing ##### ##### Some implementation ##### +include("PrescribedAtmospheres.jl") + +using .PrescribedAtmospheres: + PrescribedAtmosphere, + TwoStreamDownwellingRadiation + include("CrossRealmFluxes/CrossRealmFluxes.jl") using .CrossRealmFluxes -include("compute_atmosphere_ocean_fluxes.jl") include("ocean_sea_ice_model.jl") include("ocean_only_model.jl") +include("time_step_ocean_sea_ice_model.jl") + +import .CrossRealmFluxes: compute_atmosphere_ocean_fluxes! # "No atmosphere" implementation -const NoAtmosphereModel = OceanSeaIceModel{<:Any, <:Any, Nothing} +const NoAtmosphereModel = OceanSeaIceModel{<:Any, Nothing} compute_atmosphere_ocean_fluxes!(coupled_model::NoAtmosphereModel) = nothing -include("PrescribedAtmospheres.jl") - -using .PrescribedAtmospheres: PrescribedAtmosphere, TwoStreamDownwellingRadiation - -# Or "AtmosphereModels" -# include("Atmospheres.jl") -# using .Atmospheres - -# Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). -function default_nan_checker(model::OceanSeaIceModel) - u_ocean = model.ocean.model.velocities.u - nan_checker = NaNChecker((; u_ocean)) - return nan_checker -end - end # module diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 91447710..7d3ada77 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -1,21 +1,261 @@ module PrescribedAtmospheres -import ..OceanSeaIceModels: surface_velocities, surface_tracers, downwelling_radiation, freshwater_flux -import ..OceanSeaIceModels: density, specific_heat +using Oceananigans.Utils: prettysummary -struct PrescribedAtmosphere{U, F, R, C, ρ, CP, T} +using Thermodynamics.Parameters: AbstractThermodynamicsParameters + +# TODO: write parameter meaning here +import Thermodynamics.Parameters: + gas_constant, # + molmass_dryair, # Molar mass of dry air (without moisture) + molmass_water, # Molar mass of gaseous water vapor + kappa_d, # Ideal gas adiabatic exponent for dry air + T_0, # Enthalpy reference temperature + LH_v0, # Vaporization enthalpy at the reference temperature + LH_s0, # Sublimation enthalpy at the reference temperature + cp_d, # Isobaric specific heat capacity of dry air + cp_v, # Isobaric specific heat capacity of gaseous water vapor + cp_l, # Isobaric specific heat capacity of liquid water + cp_i, # Isobaric specific heat capacity of water ice + T_freeze, # Freezing temperature of _pure_ water + T_triple, # Triple point temperature of _pure_ water + press_triple, # Triple point pressure of pure water + T_icenuc # Temperature of ice nucleation of pure water + +import ..OceanSeaIceModels: + surface_velocities, + surface_tracers, + downwelling_radiation, + freshwater_flux + +##### +##### Atmospheric thermodynamics parameters +##### + +struct ConstitutiveParameters{FT} <: AbstractThermodynamicsParameters{FT} + gas_constant :: FT + dry_air_molar_mass :: FT + water_molar_mass :: FT +end + +function Base.summary(p::ConstitutiveParameters{FT}) where FT + return string("ConstitutiveParameters{$FT}(", + "R=", prettysummary(p.gas_constant), + ", Mᵈ=", prettysummary(p.dry_air_molar_mass), + ", Mᵛ=", prettysummary(p.water_molar_mass), ")") +end + +Base.show(io::IO, p::ConstitutiveParameters) = print(io, summary(p)) + +""" + ConstitutiveParameters(FT; gas_constant = 8.3144598, + dry_air_molar_mass = 0.02897, + water_molar_mass = 0.018015) + +Construct a set of parameters that define the density of moist air, + +```math +ρ = p / Rᵐ(q) T, +``` + +where ``p`` is pressure, ``T`` is temperature, ``q`` defines the partition +of total mass into vapor, liqiud, and ice mass fractions, and +``Rᵐ`` is the effective specific gas constant for the mixture, + +```math +Rᵐ(q) = +``` + +where + +For more information see [reference docs]. +""" +function ConstitutiveParameters(FT = Float64; + gas_constant = 8.3144598, + dry_air_molar_mass = 0.02897, + water_molar_mass = 0.018015) + + return ConstitutiveParameters(convert(FT, gas_constant), + convert(FT, dry_air_molar_mass), + convert(FT, water_molar_mass)) +end + +const CP = ConstitutiveParameters + +gas_constant(p::CP) = p.gas_constant +molmass_dryair(p::CP) = p.dry_air_molar_mass +molmass_water(p::CP) = p.water_molar_mass + +struct HeatCapacityParameters{FT} <: AbstractThermodynamicsParameters{FT} + dry_air_adiabatic_exponent :: FT + water_vapor_heat_capacity :: FT + liquid_water_heat_capacity :: FT + water_ice_heat_capacity :: FT +end + +function Base.summary(p::HeatCapacityParameters{FT}) where FT + return string("HeatCapacityParameters{$FT}(", + "κᵈ=", prettysummary(p.dry_air_adiabatic_exponent), + ", cᵖᵛ=", prettysummary(p.water_vapor_heat_capacity), + ", cᵖˡ=", prettysummary(p.liquid_water_heat_capacity), + ", cᵖⁱ=", prettysummary(p.water_ice_heat_capacity)) +end + +Base.show(io::IO, p::HeatCapacityParameters) = print(io, summary(p)) + +function HeatCapacityParameters(FT = Float64; + dry_air_adiabatic_exponent = 2/7, + water_vapor_heat_capacity = 1859, + liquid_water_heat_capacity = 4181, + water_ice_heat_capacity = 2100) + + return HeatCapacityParameters(convert(FT, dry_air_adiabatic_exponent), + convert(FT, water_vapor_heat_capacity), + convert(FT, liquid_water_heat_capacity), + convert(FT, water_ice_heat_capacity)) +end + +const HCP = HeatCapacityParameters +cp_v(p::HCP) = p.water_vapor_heat_capacity +cp_l(p::HCP) = p.liquid_water_heat_capacity +cp_i(p::HCP) = p.water_ice_heat_capacity +kappa_d(p::HCP) = p.dry_air_adiabatic_exponent + +struct PhaseTransitionParameters{FT} <: AbstractThermodynamicsParameters{FT} + reference_vaporization_enthalpy :: FT + reference_sublimation_enthalpy :: FT + reference_temperature :: FT + triple_point_temperature :: FT + triple_point_pressure :: FT + water_freezing_temperature :: FT + ice_nucleation_temperature :: FT +end + +function Base.summary(p::PhaseTransitionParameters{FT}) where FT + return string("PhaseTransitionParameters{$FT}(", + "ℒᵛ⁰=", prettysummary(p.reference_vaporization_enthalpy), + ", ℒˢ⁰=", prettysummary(p.reference_sublimation_enthalpy), + ", T⁰=", prettysummary(p.reference_temperature), + ", Tᵗʳ=", prettysummary(p.triple_point_temperature), + ", pᵗʳ=", prettysummary(p.triple_point_pressure), + ", Tᶠ=", prettysummary(p.water_freezing_temperature), + ", Tⁱⁿ=", prettysummary(p.ice_nucleation_temperature), ')') +end + +Base.show(io::IO, p::PhaseTransitionParameters) = print(io, summary(p)) + +function PhaseTransitionParameters(FT = Float64; + reference_vaporization_enthalpy = 2500800, + reference_sublimation_enthalpy = 2834400, + reference_temperature = 273.16, + triple_point_temperature = 273.16, + triple_point_pressure = 611.657, + water_freezing_temperature = 273.16, + ice_nucleation_temperature = 233) + + return PhaseTransitionParameters(convert(FT, reference_vaporization_enthalpy), + convert(FT, reference_sublimation_enthalpy), + convert(FT, reference_temperature), + convert(FT, triple_point_temperature), + convert(FT, triple_point_pressure), + convert(FT, water_freezing_temperature), + convert(FT, ice_nucleation_temperature)) +end + +const PTP = PhaseTransitionParameters +LH_v0(p::PTP) = p.reference_vaporization_enthalpy +LH_s0(p::PTP) = p.reference_sublimation_enthalpy +T_freeze(p::PTP) = p.water_freezing_temperature +T_triple(p::PTP) = p.triple_point_temperature +T_icenuc(p::PTP) = p.ice_nucleation_temperature +press_triple(p::PTP) = p.triple_point_pressure +T_0(p::PTP) = p.reference_temperature + +struct PrescribedAtmosphereThermodynamicsParameters{FT} <: AbstractThermodynamicsParameters{FT} + constitutive :: ConstitutiveParameters{FT} + heat_capacity :: HeatCapacityParameters{FT} + phase_transitions :: PhaseTransitionParameters{FT} +end + +const PATP{FT} = PrescribedAtmosphereThermodynamicsParameters{FT} where FT + +Base.summary(::PATP{FT}) where FT = "PrescribedAtmosphereThermodynamicsParameters{$FT}" + +function Base.show(io::IO, p::PrescribedAtmosphereThermodynamicsParameters) + FT = eltype(p) + + cp = p.constitutive + hc = p.heat_capacity + pt = p.phase_transitions + + return print(io, summary(p), ':', '\n', + "├── ConstitutiveParameters{$FT}:", '\n', + "│ ├── gas_constant (R): ", prettysummary(cp.gas_constant), '\n', + "│ ├── dry_air_molar_mass (Mᵈ): ", prettysummary(cp.dry_air_molar_mass), '\n', + "│ └── water_molar_mass (Mᵛ): ", prettysummary(cp.water_molar_mass), '\n', + "├── HeatCapacityParameters{$FT}:", '\n', + "│ ├── dry_air_adiabatic_exponent (κᵈ): ", prettysummary(hc.dry_air_adiabatic_exponent), '\n', + "│ ├── water_vapor_heat_capacity (cᵖᵛ): ", prettysummary(hc.water_vapor_heat_capacity), '\n', + "│ ├── liquid_water_heat_capacity (cᵖˡ): ", prettysummary(hc.liquid_water_heat_capacity), '\n', + "│ └── water_ice_heat_capacity (cᵖⁱ): ", prettysummary(hc.water_ice_heat_capacity), '\n', + "└── PhaseTransitionParameters{$FT}", '\n', + " ├── reference_vaporization_enthalpy (ℒᵛ⁰): ", prettysummary(pt.reference_vaporization_enthalpy), '\n', + " ├── reference_sublimation_enthalpy (ℒˢ⁰): ", prettysummary(pt.reference_sublimation_enthalpy), '\n', + " ├── reference_temperature (T⁰): ", prettysummary(pt.reference_temperature), '\n', + " ├── triple_point_temperature (Tᵗʳ): ", prettysummary(pt.triple_point_temperature), '\n', + " ├── triple_point_pressure (pᵗʳ): ", prettysummary(pt.triple_point_pressure), '\n', + " ├── water_freezing_temperature (Tᶠ): ", prettysummary(pt.water_freezing_temperature), '\n', + " └── ice_nucleation_temperature (Tⁱⁿ): ", prettysummary(pt.ice_nucleation_temperature)) +end + +function PrescribedAtmosphereThermodynamicsParameters(FT = Float64; + constitutive = ConstitutiveParameters(FT), + phase_transitions = PhaseTransitionParameters(FT), + heat_capacity = HeatCapacityParameters(FT)) + + return PrescribedAtmosphereThermodynamicsParameters(constitutive, heat_capacity, phase_transitions) +end + +const HTP = PrescribedAtmosphereThermodynamicsParameters + +gas_constant(p::HTP) = gas_constant(p.constitutive) +molmass_dryair(p::HTP) = molmass_dryair(p.constitutive) +molmass_water(p::HTP) = molmass_water(p.constitutive) +kappa_d(p::HTP) = kappa_d(p.heat_capacity) +LH_v0(p::HTP) = LH_v0(p.phase_transitions) +LH_s0(p::HTP) = LH_s0(p.phase_transitions) +cp_v(p::HTP) = cp_v(p.heat_capacity) +cp_l(p::HTP) = cp_l(p.heat_capacity) +cp_i(p::HTP) = cp_i(p.heat_capacity) +T_freeze(p::HTP) = T_freeze(p.phase_transitions) +T_triple(p::HTP) = T_triple(p.phase_transitions) +T_icenuc(p::HTP) = T_icenuc(p.phase_transitions) +press_triple(p::HTP) = press_triple(p.phase_transitions) +T_0(p::HTP) = T_0(p.phase_transitions) + +##### +##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic) +##### + +struct PrescribedAtmosphere{U, P, C, F, R, TP, TI, FT} velocities :: U + pressure :: P + tracers :: C freshwater_flux :: F downwelling_radiation :: R - tracers :: C - density :: ρ - specific_heat :: CP - times :: T + thermodynamics_parameters :: TP + times :: TI + reference_height :: FT end +Base.summary(::PrescribedAtmosphere) = "PrescribedAtmosphere" +Base.show(io::IO, pa::PrescribedAtmosphere) = print(io, summary(pa)) + """ PrescribedAtmosphere(times; + reference_height, velocities = nothing, + pressure = nothing, freshwater_flux = nothing, downwelling_radiation = nothing, tracers = nothing) @@ -23,30 +263,25 @@ end Return a representation of a prescribed time-evolving atmospheric state with data given at `times`. """ -function PrescribedAtmosphere(times; +function PrescribedAtmosphere(times, FT=Float64; + reference_height, velocities = nothing, + pressure = nothing, freshwater_flux = nothing, downwelling_radiation = nothing, - density = 1.2, - specific_heat = 1.0005, + thermodynamics_parameters = PrescribedAtmosphereThermodynamicsParameters(FT), tracers = nothing) return PrescribedAtmosphere(velocities, + pressure, + tracers, freshwater_flux, downwelling_radiation, - tracers, - density, - specific_heat, - times) + thermodynamics_parameters, + times, + convert(FT, reference_height)) end -surface_velocities(pa::PrescribedAtmosphere) = pa.velocities -surface_tracers(pa::PrescribedAtmosphere) = pa.tracers -freshwater_flux(pa::PrescribedAtmosphere) = pa.freshwater_flux -downwelling_radiation(pa::PrescribedAtmosphere) = pa.downwelling_radiation -density(pa::PrescribedAtmosphere) = pa.density -specific_heat(pa::PrescribedAtmosphere) = pa.specific_heat - struct TwoStreamDownwellingRadiation{SW, LW} shortwave :: SW longwave :: LW diff --git a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl deleted file mode 100644 index cf77dd30..00000000 --- a/src/OceanSeaIceModels/compute_atmosphere_ocean_fluxes.jl +++ /dev/null @@ -1,192 +0,0 @@ -using Oceananigans.Grids: inactive_node -using Oceananigans.Fields: ConstantField - -##### -##### Utilities -##### - -function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) - grid = ocean.model.grid - Nz = size(grid, 3) - u = view(ocean.model.velocities.u.data, :, :, Nz) - v = view(ocean.model.velocities.v.data, :, :, Nz) - w = view(ocean.model.velocities.w.data, :, :, Nz+1) - return (; u, v, w) -end - -function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) - grid = ocean.model.grid - Nz = size(grid, 3) - tracers = ocean.model.tracers - names = keys(tracers) - sfc_tracers = NamedTuple(name => view(tracers[name].data, :, :, Nz) for name in names) - return sfc_tracers -end - -##### -##### Computation -##### - -const c = Center() -const f = Face() - -function compute_atmosphere_ocean_fluxes!(coupled_model) - ocean = coupled_model.ocean - sea_ice = coupled_model.sea_ice - atmosphere = coupled_model.atmosphere - - # Basic model properties - grid = ocean.model.grid - arch = architecture(grid) - clock = ocean.model.clock - - # Ocean, atmosphere, and sea ice state - ocean_velocities = surface_velocities(ocean) - ocean_tracers = surface_tracers(ocean) - - atmosphere_velocities = surface_velocities(atmosphere) - atmosphere_tracers = surface_tracers(atmosphere) - atmosphere_downwelling_radiation = downwelling_radiation(atmosphere) - atmosphere_freshwater_flux = freshwater_flux(atmosphere) - - ice_thickness = sea_ice_thickness(sea_ice) - - # Fluxes, and flux contributors - net_momentum_fluxes = coupled_model.surfaces.ocean.momentum - net_tracer_fluxes = coupled_model.surfaces.ocean.tracers - bulk_momentum_flux_formulae = coupled_model.fluxes.atmosphere_ocean.momentum - bulk_heat_flux_formulae = coupled_model.fluxes.atmosphere_ocean.heat - bulk_tracer_flux_formulae = coupled_model.fluxes.atmosphere_ocean.tracers - bulk_velocity_scale = coupled_model.fluxes.bulk_velocity_scale - surface_radiation = coupled_model.fluxes.surface_radiation - - ocean_state = merge(ocean_velocities, ocean_tracers) - - atmosphere_state = (ρ = density(atmosphere), - cₚ = specific_heat(atmosphere)) - - atmosphere_state = merge(atmosphere_velocities, - atmosphere_tracers, - atmosphere_state) - - launch!(arch, grid, :xy, _compute_atmosphere_ocean_fluxes!, - grid, clock, - net_momentum_fluxes, - net_tracer_fluxes, - bulk_velocity_scale, - bulk_momentum_flux_formulae, - bulk_heat_flux_formulae, - bulk_tracer_flux_formulae, - ocean_state, - atmosphere_state, - atmosphere_downwelling_radiation, - surface_radiation, - atmosphere_freshwater_flux, - coupled_model.ocean_reference_density, - coupled_model.ocean_heat_capacity, - ice_thickness) - - return nothing -end - -@kernel function _compute_atmosphere_ocean_fluxes!(grid, - clock, - net_momentum_fluxes, - net_tracer_fluxes, - bulk_velocity, - bulk_momentum_flux_formulae, - bulk_heat_flux_formulae, - bulk_tracer_flux_formulae, - ocean_state, - atmos_state, - downwelling_radiation, - surface_radiation, - prescribed_freshwater_flux, - ocean_reference_density, - ocean_heat_capacity, - ice_thickness) - - i, j = @index(Global, NTuple) - kᴺ = size(grid, 3) # index of the top ocean cell - - time = Time(clock.time) - - Jᵘ = net_momentum_fluxes.u - Jᵛ = net_momentum_fluxes.v - Jᵀ = net_tracer_fluxes.T - Jˢ = net_tracer_fluxes.S - - # Note: there could one or more formula(e) - τˣ_formula = bulk_momentum_flux_formulae.u - τʸ_formula = bulk_momentum_flux_formulae.v - Q_formula = bulk_heat_flux_formulae - F_formula = bulk_tracer_flux_formulae.S - - atmos_state_names = keys(atmos_state) - ocean_state_names = keys(atmos_state) - - atmos_state_ij = stateindex(atmos_state, i, j, 1, time) - ocean_state_ij = stateindex(ocean_state, i, j, 1, time) - - # Compute transfer velocity scale - ΔUᶠᶜᶜ = bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) - ΔUᶜᶠᶜ = bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) - ΔUᶜᶜᶜ = bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) - - # Compute momentum fluxes - τˣ = cross_realm_flux(i, j, grid, time, τˣ_formula, ΔUᶠᶜᶜ, atmos_state, ocean_state) - τʸ = cross_realm_flux(i, j, grid, time, τʸ_formula, ΔUᶜᶠᶜ, atmos_state, ocean_state) - - # Compute heat fluxes, bulk flux first - Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, surface_radiation) - - Qu = net_upwelling_radiation(i, j, grid, time, surface_radiation, ocean_state) - Q★ = cross_realm_flux(i, j, grid, time, Q_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) - Q = Q★ + Qd + Qu - - # Compute salinity fluxes, bulk flux first - Fp = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) - F★ = cross_realm_flux(i, j, grid, time, F_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) - F = F★ + Fp - - # Then the rest of the heat fluxes - ρₒ = ocean_reference_density - cₚ = ocean_heat_capacity - - atmos_ocean_Jᵘ = τˣ / ρₒ - atmos_ocean_Jᵛ = τʸ / ρₒ - atmos_ocean_Jᵀ = Q / (ρₒ * cₚ) - - S = ocean_state_ij.S - atmos_ocean_Jˢ = S * F - - @inbounds begin - # Set fluxes - # TODO: should this be peripheral_node? - Jᵘ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, f, c, c), zero(grid), atmos_ocean_Jᵘ) - Jᵛ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, f, c), zero(grid), atmos_ocean_Jᵛ) - Jᵀ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jᵀ) - Jˢ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jˢ) - end -end - -@inline function net_downwelling_radiation(i, j, grid, time, downwelling_radiation, surface_radiation) - Qˢʷ = downwelling_radiation.shortwave - Qˡʷ = downwelling_radiation.longwave - α = stateindex(surface_radiation.reflection.ocean, i, j, 1, time) - - return @inbounds - (1 - α) * Qˢʷ[i, j, 1, time] - Qˡʷ[i, j, 1, time] -end - -@inline function net_upwelling_radiation(i, j, grid, time, surface_radiation, ocean_state) - σ = surface_radiation.stefan_boltzmann_constant - Tᵣ = surface_radiation.reference_temperature - ϵ = stateindex(surface_radiation.emission.ocean, i, j, 1, time) - - # Ocean surface temperature (departure from reference, typically in ᵒC) - Tₒ = @inbounds ocean_state.T[i, j, 1] - - # Note: positive implies _upward_ heat flux, and therefore cooling. - return σ * ϵ * (Tₒ + Tᵣ)^4 -end - diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 1ef186a3..2d7b1bdc 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -1,4 +1,4 @@ -const OceanOnlyModel = OceanSeaIceModel{<:Any, Nothing} +const OceanOnlyModel = OceanSeaIceModel{Nothing} OceanOnlyModel(ocean; kw...) = OceanSeaIceModel(nothing, ocean; kw...) diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index d8b3851f..e8cfc26d 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -5,23 +5,29 @@ using Oceananigans.BuoyancyModels: SeawaterBuoyancy using SeawaterPolynomials: TEOS10EquationOfState -struct OceanSeaIceModel{FT, I, A, O, F, PI, PC, C, G} <: AbstractModel{Nothing} +# Simulations interface +import Oceananigans: fields, prognostic_fields +import Oceananigans.Fields: set! +import Oceananigans.Models: timestepper, NaNChecker, default_nan_checker +import Oceananigans.OutputWriters: default_included_properties +import Oceananigans.Simulations: reset!, initialize!, iteration +import Oceananigans.TimeSteppers: time_step!, update_state!, time +import Oceananigans.Utils: prettytime +import Oceananigans.Models: timestepper, NaNChecker, default_nan_checker + +struct OceanSeaIceModel{I, A, O, F, C, G} <: AbstractModel{Nothing} clock :: C grid :: G # TODO: make it so Oceananigans.Simulation does not require this atmosphere :: A sea_ice :: I ocean :: O fluxes :: F - previous_ice_thickness :: PI - previous_ice_concentration :: PC - # The ocean is Boussinesq, so these are _only_ coupled properties: - ocean_reference_density :: FT - ocean_heat_capacity :: FT end const OSIM = OceanSeaIceModel Base.summary(::OSIM) = "OceanSeaIceModel" +Base.show(io::IO, cm::OSIM) = print(io, summary(cm)) prettytime(model::OSIM) = prettytime(model.clock.time) iteration(model::OSIM) = model.clock.iteration timestepper(::OSIM) = nothing @@ -32,8 +38,11 @@ prognostic_fields(cm::OSIM) = nothing fields(::OSIM) = NamedTuple() default_clock(TT) = Oceananigans.TimeSteppers.Clock{TT}(0, 0, 1) -reference_density(unsupported) = throw(ArgumentError("Cannot extract reference density from $(typeof(unsupported))")) -heat_capacity(unsupported) = throw(ArgumentError("Cannot deduce the heat capacity from $(typeof(unsupported))")) +reference_density(unsupported) = + throw(ArgumentError("Cannot extract reference density from $(typeof(unsupported))")) + +heat_capacity(unsupported) = + throw(ArgumentError("Cannot deduce the heat capacity from $(typeof(unsupported))")) reference_density(ocean::Simulation) = reference_density(ocean.model.buoyancy.model) reference_density(buoyancy_model::SeawaterBuoyancy) = reference_density(buoyancy_model.equation_of_state) @@ -49,86 +58,33 @@ end function OceanSeaIceModel(ocean, sea_ice=nothing; atmosphere = nothing, - surface_radiation = nothing, + radiation = nothing, ocean_reference_density = reference_density(ocean), ocean_heat_capacity = heat_capacity(ocean), clock = deepcopy(ocean.model.clock)) - if isnothing(sea_ice) - previous_ice_thickness = nothing - previous_ice_concentration = nothing - else - previous_ice_thickness = deepcopy(sea_ice.model.ice_thickness) - previous_ice_concentration = deepcopy(sea_ice.model.ice_concentration) - end - - # Contains information about flux contributions: bulk formula, prescribed - # fluxes, etc. - fluxes = OceanSeaIceSurfaceFluxes(ocean, sea_ice; - atmosphere, - surface_radiation) - - FT = eltype(ocean.model.grid) - - return OceanSeaIceModel(clock, - ocean.model.grid, - atmosphere, - sea_ice, - ocean, - fluxes, - previous_ice_thickness, - previous_ice_concentration, - convert(FT, ocean_reference_density), - convert(FT, ocean_heat_capacity)) -end - -time(coupled_model::OceanSeaIceModel) = coupled_model.clock.time - -function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_tendencies=true) - ocean = coupled_model.ocean - sea_ice = coupled_model.sea_ice - - # Be paranoid and update state at iteration 0 - coupled_model.clock.iteration == 0 && update_state!(coupled_model, callbacks) + # Contains information about flux contributions: bulk formula, prescribed fluxes, etc. + fluxes = OceanSeaIceSurfaceFluxes(ocean, sea_ice; atmosphere, radiation) - # Eventually, split out into OceanOnlyModel - if !isnothing(sea_ice) - h = sea_ice.model.ice_thickness - fill_halo_regions!(h) + ocean_sea_ice_model = OceanSeaIceModel(clock, + ocean.model.grid, + atmosphere, + sea_ice, + ocean, + fluxes) - # Initialization - if coupled_model.clock.iteration == 0 - @info "Initializing coupled model ice thickness..." - h⁻ = coupled_model.previous_ice_thickness - hⁿ = coupled_model.sea_ice.model.ice_thickness - parent(h⁻) .= parent(hⁿ) - end + update_state!(ocean_sea_ice_model) - sea_ice.Δt = Δt - time_step!(sea_ice) - end - - ocean.Δt = Δt - - # TODO after ice time-step: - # - Adjust ocean heat flux if the ice completely melts? + return ocean_sea_ice_model +end - time_step!(ocean) +time(coupled_model::OceanSeaIceModel) = coupled_model.clock.time - # TODO: - # - Store fractional ice-free / ice-covered _time_ for more - # accurate flux computation? - tick!(coupled_model.clock, Δt) - update_state!(coupled_model, callbacks; compute_tendencies) - - return nothing +# Check for NaNs in the first prognostic field (generalizes to prescribed velocitries). +function default_nan_checker(model::OceanSeaIceModel) + u_ocean = model.ocean.model.velocities.u + nan_checker = NaNChecker((; u_ocean)) + return nan_checker end -function update_state!(coupled_model::OceanSeaIceModel, callbacks=[]; compute_tendencies=false) - # update_model_field_time_series!(coupled_model.atmosphere) - compute_atmosphere_ocean_fluxes!(coupled_model) - # compute_atmosphere_sea_ice_fluxes!(coupled_model) - # compute_sea_ice_ocean_fluxes!(coupled_model) - return nothing -end diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl new file mode 100644 index 00000000..643400c5 --- /dev/null +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -0,0 +1,50 @@ +using .CrossRealmFluxes: compute_atmosphere_ocean_fluxes! + +function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_tendencies=true) + ocean = coupled_model.ocean + sea_ice = coupled_model.sea_ice + + # Be paranoid and update state at iteration 0 + coupled_model.clock.iteration == 0 && update_state!(coupled_model, callbacks) + + # Eventually, split out into OceanOnlyModel + if !isnothing(sea_ice) + h = sea_ice.model.ice_thickness + fill_halo_regions!(h) + + # Initialization + if coupled_model.clock.iteration == 0 + @info "Initializing coupled model ice thickness..." + h⁻ = coupled_model.previous_ice_thickness + hⁿ = coupled_model.sea_ice.model.ice_thickness + parent(h⁻) .= parent(hⁿ) + end + + sea_ice.Δt = Δt + time_step!(sea_ice) + end + + ocean.Δt = Δt + + # TODO after ice time-step: + # - Adjust ocean heat flux if the ice completely melts? + + time_step!(ocean) + + # TODO: + # - Store fractional ice-free / ice-covered _time_ for more + # accurate flux computation? + tick!(coupled_model.clock, Δt) + update_state!(coupled_model, callbacks; compute_tendencies) + + return nothing +end + +function update_state!(coupled_model::OceanSeaIceModel, callbacks=[]; compute_tendencies=false) + # update_model_field_time_series!(coupled_model.atmosphere) + compute_atmosphere_ocean_fluxes!(coupled_model) + # compute_atmosphere_sea_ice_fluxes!(coupled_model) + # compute_sea_ice_ocean_fluxes!(coupled_model) + return nothing +end + From daa0085bf7dc415061fcb6bf319ebdfc9cba5109 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 19 Jan 2024 06:43:31 -0700 Subject: [PATCH 054/182] Much progress --- Manifest.toml | 6 +- .../omip_ocean_component.jl | 85 ++- .../single_column_omip_ocean_component.jl | 50 -- .../single_column_omip_simulation.jl | 655 ++++++++++-------- src/DataWrangling/JRA55.jl | 29 +- .../CrossRealmFluxes/CrossRealmFluxes.jl | 3 +- .../compute_atmosphere_ocean_fluxes.jl | 0 .../ocean_sea_ice_surface_fluxes.jl | 406 ++--------- .../similarity_theory_surface_fluxes.jl | 78 --- .../similarity_theory_turbulent_fluxes.jl | 190 +++++ .../PrescribedAtmospheres.jl | 104 +-- 11 files changed, 744 insertions(+), 862 deletions(-) delete mode 100644 experiments/prototype_omip_simulation/single_column_omip_ocean_component.jl delete mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/compute_atmosphere_ocean_fluxes.jl delete mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl diff --git a/Manifest.toml b/Manifest.toml index bac266fb..69c4ab57 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1084,9 +1084,11 @@ version = "7.2.0+1" [[deps.SurfaceFluxes]] deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] -path = "/Users/gregorywagner/Projects/SurfaceFluxes.jl" +git-tree-sha1 = "dac64dc26093ed511d9f11d82fde437acdc540a4" +repo-rev = "glw/generalize-parameters" +repo-url = "https://github.com/glwagner/SurfaceFluxes.jl.git" uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.8.0" +version = "0.8.1" [[deps.TOML]] deps = ["Dates"] diff --git a/experiments/prototype_omip_simulation/omip_ocean_component.jl b/experiments/prototype_omip_simulation/omip_ocean_component.jl index d911bf75..ebd6b56c 100644 --- a/experiments/prototype_omip_simulation/omip_ocean_component.jl +++ b/experiments/prototype_omip_simulation/omip_ocean_component.jl @@ -1,35 +1,50 @@ -top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) -top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) -top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) -top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(grid) - -ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), - v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), - T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), - S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) - -# Model construction -teos10 = TEOS10EquationOfState() -buoyancy = SeawaterBuoyancy(equation_of_state=teos10) - -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: MixingLength -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: TurbulentKineticEnergyEquation - -mixing_length = MixingLength(Cᵇ=0.01) -turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) -closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) - -tracer_advection = WENO() -momentum_advection = VectorInvariant(vorticity_scheme = WENO(), - divergence_scheme = WENO(), - vertical_scheme = WENO()) - -ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, - tracer_advection, momentum_advection, - tracers = (:T, :S, :e), - free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), - boundary_conditions = ocean_boundary_conditions, - coriolis = HydrostaticSphericalCoriolis()) - -ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) - +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: + CATKEVerticalDiffusivity, + MixingLength, + TurbulentKineticEnergyEquation + +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + +function omip_ocean_component(grid) + + top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) + top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) + top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) + top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(grid) + + ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), + T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) + + # Model construction + teos10 = TEOS10EquationOfState() + buoyancy = SeawaterBuoyancy(equation_of_state=teos10) + + Nx, Ny, Nz = size(grid) + + if Nx == Ny == 1 + tracer_advection = nothing + momentum_advection = nothing + else + tracer_advection = WENO() + momentum_advection = VectorInvariant(vorticity_scheme = WENO(), + divergence_scheme = WENO(), + vertical_scheme = WENO()) + end + + mixing_length = MixingLength(Cᵇ=0.01) + turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) + + ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, + tracer_advection, momentum_advection, + tracers = (:T, :S, :e), + free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), + boundary_conditions = ocean_boundary_conditions, + coriolis = HydrostaticSphericalCoriolis()) + + ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) + + return ocean +end diff --git a/experiments/prototype_omip_simulation/single_column_omip_ocean_component.jl b/experiments/prototype_omip_simulation/single_column_omip_ocean_component.jl deleted file mode 100644 index ebd6b56c..00000000 --- a/experiments/prototype_omip_simulation/single_column_omip_ocean_component.jl +++ /dev/null @@ -1,50 +0,0 @@ -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: - CATKEVerticalDiffusivity, - MixingLength, - TurbulentKineticEnergyEquation - -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState - -function omip_ocean_component(grid) - - top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) - top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) - top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) - top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(grid) - - ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), - v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), - T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), - S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) - - # Model construction - teos10 = TEOS10EquationOfState() - buoyancy = SeawaterBuoyancy(equation_of_state=teos10) - - Nx, Ny, Nz = size(grid) - - if Nx == Ny == 1 - tracer_advection = nothing - momentum_advection = nothing - else - tracer_advection = WENO() - momentum_advection = VectorInvariant(vorticity_scheme = WENO(), - divergence_scheme = WENO(), - vertical_scheme = WENO()) - end - - mixing_length = MixingLength(Cᵇ=0.01) - turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) - closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) - - ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, - tracer_advection, momentum_advection, - tracers = (:T, :S, :e), - free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), - boundary_conditions = ocean_boundary_conditions, - coriolis = HydrostaticSphericalCoriolis()) - - ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) - - return ocean -end diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 8a862b1c..1dba6ed3 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -1,6 +1,7 @@ using Oceananigans using Oceananigans.Units using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time using ClimaOcean using ClimaOcean.OceanSeaIceModels: Radiation @@ -11,284 +12,378 @@ using GLMakie using Printf using Dates -start_time = time_ns() - -include("single_column_omip_ocean_component.jl") - -epoch = Date(1992, 1, 1) -date = Date(1992, 10, 01) -start_seconds = Second(date - epoch).value -uᵢ = ecco2_field(:u_velocity, date) -vᵢ = ecco2_field(:v_velocity, date) -Tᵢ = ecco2_field(:temperature, date) -Sᵢ = ecco2_field(:salinity, date) - -land = interior(Tᵢ) .< -10 -interior(Tᵢ)[land] .= NaN -interior(Sᵢ)[land] .= NaN - -teos10 = TEOS10EquationOfState() -buoyancy = SeawaterBuoyancy(equation_of_state=teos10) -tracers = (T=Tᵢ, S=Sᵢ) -N²_op = buoyancy_frequency(buoyancy, Tᵢ.grid, tracers) -N² = Field(N²_op) -compute!(N²) - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### - -zc = znodes(Tᵢ) -zf = znodes(N²) - -arch = CPU() - -Δ = 1/4 # resolution in degrees -φ₁ = -90 + Δ/2 -φ₂ = +90 - Δ/2 -λ₁ = 0 + Δ/2 -λ₂ = 360 - Δ/2 -φe = φ₁:Δ:φ₂ -λe = λ₁:Δ:λ₂ - -φ★ = 50 # degrees latitude -λ★ = 180 + 35 # degrees longitude (?) - -i★ = searchsortedfirst(λe, λ★) -j★ = searchsortedfirst(φe, φ★) - -longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) -latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) - -# Column -uc = interior(uᵢ, i★:i★, j★:j★, :) -vc = interior(vᵢ, i★:i★, j★:j★, :) -Tc = interior(Tᵢ, i★:i★, j★:j★, :) -Sc = interior(Sᵢ, i★:i★, j★:j★, :) - -# Find bottom -zm = -400 -zf = znodes(Tᵢ.grid, Face()) -kb = findlast(T -> T < -20, Tc[1, 1, :]) -km = findlast(z -> z < zm, zf) -k★ = isnothing(kb) ? km : max(kb, km) - -Nz = size(Tc, 3) -kf = k★:Nz+1 -kc = k★:Nz -zf = zf[kf] -uc = uc[:, :, kc] -vc = vc[:, :, kc] -Tc = Tc[:, :, kc] -Sc = Sc[:, :, kc] -Nz′ = length(kc) - -grid = LatitudeLongitudeGrid(arch; longitude, latitude, - size = (1, 1, Nz′), - z = zf, - topology = (Periodic, Periodic, Bounded)) - -elapsed = time_ns() - start_time -@info "Grid constructed. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -ocean = omip_ocean_component(grid) -elapsed = time_ns() - start_time -@info "Ocean component built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -Ndays = 365 -Nt = 8 * Ndays -atmosphere = jra55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) -elapsed = time_ns() - start_time -@info "Atmosphere built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -ocean.model.clock.time = start_seconds -ocean.model.clock.iteration = 0 -set!(ocean.model, T=Tc, S=Sc, e=1e-6) - -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -times = ua.times - -#= -fig = Figure(resolution=(1200, 1800)) -axu = Axis(fig[1, 1]) -axT = Axis(fig[2, 1]) -axq = Axis(fig[3, 1]) - -lines!(axu, times ./ days, interior(ua, 1, 1, 1, :)) -lines!(axu, times ./ days, interior(va, 1, 1, 1, :)) -lines!(axT, times ./ days, interior(Ta, 1, 1, 1, :)) -lines!(axq, times ./ days, interior(qa, 1, 1, 1, :)) - -display(fig) -=# - -sea_ice = nothing -radiation = Radiation() -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) - -#= -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 90days) - -elapsed = time_ns() - start_time -@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -wall_clock = Ref(time_ns()) - -function progress(sim) - msg1 = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg2 = string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg3 = @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - e = sim.model.ocean.model.tracers.e - Nz = size(T, 3) - msg4 = @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) - msg5 = @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) - msg6 = @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) - - @info msg1 * msg2 * msg3 * msg4 * msg5 * msg6 -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) - -# Build flux outputs -Jᵘ = coupled_model.surfaces.ocean.momentum.u -Jᵛ = coupled_model.surfaces.ocean.momentum.v -Jᵀ = coupled_model.surfaces.ocean.tracers.T -F = coupled_model.surfaces.ocean.tracers.S -ρₒ = coupled_model.ocean_reference_density -cₚ = coupled_model.ocean_heat_capacity - -Q = ρₒ * cₚ * Jᵀ -τˣ = ρₒ * Jᵘ -τʸ = ρₒ * Jᵛ - -fluxes = (; τˣ, τʸ, Q, F) -fields = merge(ocean.model.velocities, ocean.model.tracers) - -# Slice fields at the surface -outputs = merge(fields, fluxes) - -filename = "single_column_omip_surface_fields.jld2" - -coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean.model, outputs; filename, - schedule = TimeInterval(1hours), - overwrite_existing = true) - -run!(coupled_simulation) - -ut = FieldTimeSeries(filename, "u") -vt = FieldTimeSeries(filename, "v") -Tt = FieldTimeSeries(filename, "T") -St = FieldTimeSeries(filename, "S") -et = FieldTimeSeries(filename, "e") -Qt = FieldTimeSeries(filename, "Q") -Ft = FieldTimeSeries(filename, "F") -τˣt = FieldTimeSeries(filename, "τˣ") -τʸt = FieldTimeSeries(filename, "τʸ") - -Nz = size(Tt, 3) -times = Qt.times - -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -Qlw = atmosphere.downwelling_radiation.longwave -Qsw = atmosphere.downwelling_radiation.shortwave - -using Oceananigans.Units: Time - -Nt = length(times) -uat = zeros(Nt) -vat = zeros(Nt) -Tat = zeros(Nt) -qat = zeros(Nt) -Qswt = zeros(Nt) -Qlwt = zeros(Nt) - -for n = 1:Nt - t = times[n] - uat[n] = ua[1, 1, 1, Time(t)] - vat[n] = va[1, 1, 1, Time(t)] - Tat[n] = Ta[1, 1, 1, Time(t)] - qat[n] = qa[1, 1, 1, Time(t)] - Qswt[n] = Qsw[1, 1, 1, Time(t)] - Qlwt[n] = Qlw[1, 1, 1, Time(t)] +locations = ( + #eastern_mediterranean = (λ = 30, φ = 32), + ocean_station_papa = (λ = 215, φ = 50), + north_atlantic = (λ = 325, φ = 50), + drake_passage = (λ = 300, φ = -60), + weddell_sea = (λ = 325, φ = -70), + tasman_southern_ocean = (λ = 145, φ = -55), +) + +for location in keys(locations) + +#location = :ocean_station_papa + start_time = time_ns() + + include("omip_ocean_component.jl") + + epoch = Date(1992, 1, 1) + date = Date(1992, 10, 1) + start_seconds = Second(date - epoch).value + uᵢ = ecco2_field(:u_velocity, date) + vᵢ = ecco2_field(:v_velocity, date) + Tᵢ = ecco2_field(:temperature, date) + Sᵢ = ecco2_field(:salinity, date) + + land = interior(Tᵢ) .< -10 + interior(Tᵢ)[land] .= NaN + interior(Sᵢ)[land] .= NaN + + teos10 = TEOS10EquationOfState() + buoyancy = SeawaterBuoyancy(equation_of_state=teos10) + tracers = (T=Tᵢ, S=Sᵢ) + N²_op = buoyancy_frequency(buoyancy, Tᵢ.grid, tracers) + N² = Field(N²_op) + compute!(N²) + + elapsed = time_ns() - start_time + @info "Initial condition built. " * prettytime(elapsed * 1e-9) + start_time = time_ns() + + ##### + ##### Construct the grid + ##### + + zc = znodes(Tᵢ) + zf = znodes(N²) + + arch = CPU() + + Δ = 1/4 # resolution in degrees + φ₁ = -90 + Δ/2 + φ₂ = +90 - Δ/2 + λ₁ = 0 + Δ/2 + λ₂ = 360 - Δ/2 + φe = φ₁:Δ:φ₂ + λe = λ₁:Δ:λ₂ + + λ★, φ★ = locations[location] + + i★ = searchsortedfirst(λe, λ★) + j★ = searchsortedfirst(φe, φ★) + + longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) + latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) + + # Column + uc = interior(uᵢ, i★:i★, j★:j★, :) + vc = interior(vᵢ, i★:i★, j★:j★, :) + Tc = interior(Tᵢ, i★:i★, j★:j★, :) + Sc = interior(Sᵢ, i★:i★, j★:j★, :) + + # Find bottom + zm = -400 + zf = znodes(Tᵢ.grid, Face()) + kb = findlast(T -> T < -20, Tc[1, 1, :]) + km = findlast(z -> z < zm, zf) + k★ = isnothing(kb) ? km : max(kb + 1, km) + + Nz = size(Tc, 3) + kf = k★:Nz+1 + kc = k★:Nz + zf = zf[kf] + uc = uc[:, :, kc] + vc = vc[:, :, kc] + Tc = Tc[:, :, kc] + Sc = Sc[:, :, kc] + Nz′ = length(kc) + + grid = LatitudeLongitudeGrid(arch; longitude, latitude, + size = (1, 1, Nz′), + z = zf, + topology = (Periodic, Periodic, Bounded)) + + elapsed = time_ns() - start_time + @info "Grid constructed. " * prettytime(elapsed * 1e-9) + start_time = time_ns() + + ocean = omip_ocean_component(grid) + elapsed = time_ns() - start_time + @info "Ocean component built. " * prettytime(elapsed * 1e-9) + start_time = time_ns() + + Ndays = 365 + Nt = 8 * Ndays + atmosphere = jra55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) + elapsed = time_ns() - start_time + @info "Atmosphere built. " * prettytime(elapsed * 1e-9) + start_time = time_ns() + + ocean.model.clock.time = start_seconds + ocean.model.clock.iteration = 0 + set!(ocean.model, T=Tc, S=Sc, e=1e-6) + + ua = atmosphere.velocities.u + va = atmosphere.velocities.v + Ta = atmosphere.tracers.T + qa = atmosphere.tracers.q + times = ua.times + + #= + fig = Figure(resolution=(1200, 1800)) + axu = Axis(fig[1, 1]) + axT = Axis(fig[2, 1]) + axq = Axis(fig[3, 1]) + + lines!(axu, times ./ days, interior(ua, 1, 1, 1, :)) + lines!(axu, times ./ days, interior(va, 1, 1, 1, :)) + lines!(axT, times ./ days, interior(Ta, 1, 1, 1, :)) + lines!(axq, times ./ days, interior(qa, 1, 1, 1, :)) + + display(fig) + =# + + sea_ice = nothing + radiation = Radiation() + coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + + coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 60days) + + elapsed = time_ns() - start_time + @info "Coupled simulation built. " * prettytime(elapsed * 1e-9) + start_time = time_ns() + + wall_clock = Ref(time_ns()) + + function progress(sim) + msg = string("(", location, ")") + msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + e = sim.model.ocean.model.tracers.e + + τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) + τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) + u★ = (τˣ^2 + τʸ^2)^(1/4) + Q = first(sim.model.fluxes.total.ocean.heat) + + Nz = size(T, 3) + msg *= @sprintf(", u★: %.2f m s⁻¹", u★) + msg *= @sprintf(", Q: %.2f W m⁻²", Q) + msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) + msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) + msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) + + @info msg + end + + coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) + + # Build flux outputs + Jᵘ = coupled_model.fluxes.total.ocean.momentum.u + Jᵛ = coupled_model.fluxes.total.ocean.momentum.v + Jᵀ = coupled_model.fluxes.total.ocean.tracers.T + F = coupled_model.fluxes.total.ocean.tracers.S + E = coupled_model.fluxes.turbulent.fields.evaporation + Qse = coupled_model.fluxes.turbulent.fields.sensible_heat_flux + Qla = coupled_model.fluxes.turbulent.fields.latent_heat_flux + ρₒ = coupled_model.fluxes.ocean_reference_density + cₚ = coupled_model.fluxes.ocean_heat_capacity + + Q = ρₒ * cₚ * Jᵀ + τˣ = ρₒ * Jᵘ + τʸ = ρₒ * Jᵛ + N² = buoyancy_frequency(ocean.model) + κᶜ = ocean.model.diffusivity_fields.κᶜ + + fluxes = (; τˣ, τʸ, E, F, Q, Qse, Qla) + + auxiliary_fields = (; N², κᶜ) + fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + + # Slice fields at the surface + outputs = merge(fields, fluxes) + + filename = "single_column_omip_$location" + + coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, + schedule = TimeInterval(3hours), + overwrite_existing = true) + + coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, + schedule = AveragedTimeInterval(1day), + overwrite_existing = true) + + run!(coupled_simulation) + + ut = FieldTimeSeries(filename, "u") + vt = FieldTimeSeries(filename, "v") + Tt = FieldTimeSeries(filename, "T") + St = FieldTimeSeries(filename, "S") + et = FieldTimeSeries(filename, "e") + N²t = FieldTimeSeries(filename, "N²") + κt = FieldTimeSeries(filename, "κᶜ") + + Qt = FieldTimeSeries(filename, "Q") + Qset = FieldTimeSeries(filename, "Qse") + Qlat = FieldTimeSeries(filename, "Qla") + Ft = FieldTimeSeries(filename, "F") + Et = FieldTimeSeries(filename, "E") + τˣt = FieldTimeSeries(filename, "τˣ") + τʸt = FieldTimeSeries(filename, "τʸ") + + Nz = size(Tt, 3) + times = Qt.times + + ua = atmosphere.velocities.u + va = atmosphere.velocities.v + Ta = atmosphere.tracers.T + qa = atmosphere.tracers.q + Qlw = atmosphere.downwelling_radiation.longwave + Qsw = atmosphere.downwelling_radiation.shortwave + Pr = atmosphere.freshwater_flux.rain + Ps = atmosphere.freshwater_flux.snow + + Nt = length(times) + uat = zeros(Nt) + vat = zeros(Nt) + Tat = zeros(Nt) + qat = zeros(Nt) + Qswt = zeros(Nt) + Qlwt = zeros(Nt) + Pt = zeros(Nt) + + for n = 1:Nt + t = times[n] + uat[n] = ua[1, 1, 1, Time(t)] + vat[n] = va[1, 1, 1, Time(t)] + Tat[n] = Ta[1, 1, 1, Time(t)] + qat[n] = qa[1, 1, 1, Time(t)] + Qswt[n] = Qsw[1, 1, 1, Time(t)] + Qlwt[n] = Qlw[1, 1, 1, Time(t)] + Pt[n] = Pr[1, 1, 1, Time(t)] + Ps[1, 1, 1, Time(t)] + end + + set_theme!(Theme(linewidth=3)) + + fig = Figure(resolution=(2400, 1800)) + + axτ = Axis(fig[1, 1:2], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") + axu = Axis(fig[2, 1:2], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") + axQ = Axis(fig[1, 3:4], xlabel="Days since Oct 1 1992", ylabel="Heat flux (W m⁻²)") + axT = Axis(fig[2, 3:4], xlabel="Days since Oct 1 1992", ylabel="Surface temperature (ᵒC)") + axF = Axis(fig[1, 5:6], xlabel="Days since Oct 1 1992", ylabel="Freshwater volume flux (m s⁻¹)") + axS = Axis(fig[2, 5:6], xlabel="Days since Oct 1 1992", ylabel="Surface salinity (g kg⁻¹)") + + axuz = Axis(fig[3, 1], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") + axTz = Axis(fig[3, 2], xlabel="Temperature (ᵒC)", ylabel="z (m)") + axSz = Axis(fig[3, 3], xlabel="Salinity (g kg⁻¹)", ylabel="z (m)") + axNz = Axis(fig[3, 4], xlabel="Buoyancy frequency (s⁻²)", ylabel="z (m)") + axκz = Axis(fig[3, 5], xlabel="Eddy diffusivity (m² s⁻¹)", ylabel="z (m)", xscale=log10) + axez = Axis(fig[3, 6], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)", xscale=log10) + + title = @sprintf("Single column simulation at %.2f, %.2f", φ★, λ★) + Label(fig[0, 1:6], title) + + slider = Slider(fig[4, 1:6], range=1:Nt, startvalue=1) + n = slider.value + + times = (times .- times[1]) ./days + tn = @lift times[$n] + + colors = Makie.wong_colors() + + #lines!(axu, times, uat, color=colors[1]) + #lines!(axu, times, vat, color=colors[2]) + + ρₒ = coupled_model.fluxes.ocean_reference_density + Jᵘt = interior(τˣt, 1, 1, 1, :) ./ ρₒ + Jᵛt = interior(τʸt, 1, 1, 1, :) ./ ρₒ + u★ = @. (Jᵘt^2 + Jᵛt^2)^(1/4) + + lines!(axu, times, interior(ut, 1, 1, Nz, :), color=colors[1], label="Zonal") + lines!(axu, times, interior(vt, 1, 1, Nz, :), color=colors[2], label="Meridional") + lines!(axu, times, u★, color=colors[3], label="Ocean-side u★") + vlines!(axu, tn, linewidth=4, color=(:black, 0.5)) + axislegend(axu) + + lines!(axτ, times, interior(τˣt, 1, 1, 1, :), label="Zonal") + lines!(axτ, times, interior(τʸt, 1, 1, 1, :), label="Meridional") + vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) + axislegend(axτ) + + lines!(axT, times, Tat .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") + lines!(axT, times, interior(Tt, 1, 1, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") + vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) + axislegend(axT) + + lines!(axQ, times, interior(Qt, 1, 1, 1, :), color=colors[1], label="Total", linewidth=6) + lines!(axQ, times, interior(Qset, 1, 1, 1, :), color=colors[2], label="Sensible", linewidth=2) + lines!(axQ, times, interior(Qlat, 1, 1, 1, :), color=colors[3], label="Latent", linewidth=2) + lines!(axQ, times, - Qswt, color=colors[4], label="Shortwave", linewidth=2) + lines!(axQ, times, - Qlwt, color=colors[5], label="Longwave", linewidth=2) + vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) + axislegend(axQ) + + #lines!(axF, times, interior(Ft, 1, 1, 1, :), label="Net freshwater flux") + lines!(axF, times, Pt, label="Prescribed freshwater flux") + lines!(axF, times, - interior(Et, 1, 1, 1, :), label="Evaporation") + vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) + axislegend(axF) + + lines!(axS, times, interior(St, 1, 1, Nz, :)) + vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) + + zc = znodes(Tt) + zf = znodes(κt) + un = @lift interior(ut[$n], 1, 1, :) + vn = @lift interior(vt[$n], 1, 1, :) + Tn = @lift interior(Tt[$n], 1, 1, :) + Sn = @lift interior(St[$n], 1, 1, :) + κn = @lift interior(κt[$n], 1, 1, :) + en = @lift max.(1e-6, interior(et[$n], 1, 1, :)) + N²n = @lift interior(N²t[$n], 1, 1, :) + + scatterlines!(axuz, un, zc, label="u") + scatterlines!(axuz, vn, zc, label="v") + scatterlines!(axTz, Tn, zc) + scatterlines!(axSz, Sn, zc) + scatterlines!(axez, en, zc) + scatterlines!(axNz, N²n, zf) + scatterlines!(axκz, κn, zf) + + axislegend(axuz) + + Tmax = maximum(interior(Tt)) + Tmin = minimum(interior(Tt)) + xlims!(axTz, Tmin - 0.1, Tmax + 0.1) + + Nmax = maximum(interior(N²t)) + Nmin = minimum(interior(N²t)) + xlims!(axNz, Nmin / 2, Nmin * 1.1) + + emax = maximum(interior(et)) + xlims!(axez, 8e-7, emax * 1.1) + xlims!(axκz, 1e-7, 10) + + Smax = maximum(interior(St)) + Smin = minimum(interior(St)) + xlims!(axSz, Smin - 0.2, Smax + 0.2) + + display(fig) + + record(fig, "$(location)_single_column_simulation.mp4", 1:Nt, framerate=24) do nn + @info "Drawing frame $nn of $Nt..." + n[] = nn + end end - -fig = Figure(resolution=(2400, 1800)) - -axu = Axis(fig[1, 1:4], xlabel="Time (days)", ylabel="Velocities (m s⁻¹)") -axτ = Axis(fig[2, 1:4], xlabel="Time (days)", ylabel="Wind stress (N m⁻²)") -axT = Axis(fig[3, 1:4], xlabel="Time (days)", ylabel="Temperature (K)") -axQ = Axis(fig[4, 1:4], xlabel="Time (days)", ylabel="Heat flux (W m⁻²)") -axF = Axis(fig[5, 1:4], xlabel="Time (days)", ylabel="Salt flux (...)") - -axuz = Axis(fig[6, 1], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") -axTz = Axis(fig[6, 2], xlabel="Temperature (K)", ylabel="z (m)") -axSz = Axis(fig[6, 3], xlabel="Salinity (g/kg)", ylabel="z (m)") -axez = Axis(fig[6, 4], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)") - -slider = Slider(fig[7, 1:4], range=1:Nt, startvalue=1) -n = slider.value - -times ./= days -tn = @lift times[$n] - -colors = Makie.wong_colors() - -lines!(axu, times, uat, color=colors[1]) -lines!(axu, times, interior(ut, 1, 1, Nz, :), color=colors[1], linestyle=:dash) -vlines!(axu, tn) - -lines!(axu, times, vat, color=colors[2]) -lines!(axu, times, interior(vt, 1, 1, Nz, :), color=colors[2], linestyle=:dash) - -lines!(axτ, times, interior(τˣt, 1, 1, 1, :)) -lines!(axτ, times, interior(τʸt, 1, 1, 1, :)) -vlines!(axτ, tn) - -lines!(axT, times, Tat, color=colors[1]) -lines!(axT, times, interior(Tt, 1, 1, Nz, :) .+ 273.15, color=colors[1], linestyle=:dash) -vlines!(axT, tn) - -lines!(axQ, times, interior(Qt, 1, 1, 1, :), color=colors[1], linestyle=:dash) -lines!(axQ, times, - Qswt, color=colors[2], linewidth=3) -lines!(axQ, times, - Qlwt, color=colors[3], linewidth=3) -vlines!(axQ, tn) - -lines!(axF, times, interior(Ft, 1, 1, 1, :)) -vlines!(axF, tn) - -z = znodes(Tt) -un = @lift interior(ut[$n], 1, 1, :) -vn = @lift interior(vt[$n], 1, 1, :) -Tn = @lift interior(Tt[$n], 1, 1, :) -Sn = @lift interior(St[$n], 1, 1, :) -en = @lift interior(et[$n], 1, 1, :) -lines!(axuz, un, z) -lines!(axuz, vn, z) -lines!(axTz, Tn, z) -lines!(axSz, Sn, z) -lines!(axez, en, z) - -display(fig) -=# diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index fe234d99..1fb454d7 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -15,8 +15,8 @@ using NCDatasets # A list of all variables provided in the JRA55 dataset: jra55_variable_names = (:freshwater_river_flux, - :freshwater_rain_flux, - :freshwater_snow_flux, + :rain_freshwater_flux, + :snow_freshwater_flux, :freshwater_iceberg_flux, :specific_humidity, :sea_level_pressure, @@ -29,8 +29,8 @@ jra55_variable_names = (:freshwater_river_flux, filenames = Dict( :freshwater_river_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers - :freshwater_rain_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall - :freshwater_snow_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall + :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall + :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall :freshwater_iceberg_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure @@ -44,8 +44,8 @@ filenames = Dict( shortnames = Dict( :freshwater_river_flux => "friver", # Freshwater fluxes from rivers - :freshwater_rain_flux => "prra", # Freshwater flux from rainfall - :freshwater_snow_flux => "prsn", # Freshwater flux from snowfall + :rain_freshwater_flux => "prra", # Freshwater flux from rainfall + :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall :freshwater_iceberg_flux => "licalvf", # Freshwater flux from calving icebergs :specific_humidity => "huss", # Surface specific humidity :sea_level_pressure => "psl", # Sea level pressure @@ -64,10 +64,10 @@ urls = Dict( :freshwater_river_flux => "https://www.dropbox.com/scl/fi/21ggl4p74k4zvbf04nb67/" * "RYF.friver.1990_1991.nc?rlkey=ny2qcjkk1cfijmwyqxsfm68fz&dl=0", - :freshwater_rain_flux => "https://www.dropbox.com/scl/fi/5icl1gbd7f5hvyn656kjq/" * + :rain_freshwater_flux => "https://www.dropbox.com/scl/fi/5icl1gbd7f5hvyn656kjq/" * "RYF.prra.1990_1991.nc?rlkey=iifyjm4ppwyd8ztcek4dtx0k8&dl=0", - :freshwater_snow_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * + :snow_freshwater_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * "RYF.prsn.1990_1991.nc?rlkey=auyqpwn060cvy4w01a2yskfah&dl=0", :freshwater_iceberg_flux => "https://www.dropbox.com/scl/fi/44nc5y27ohvif7lkvpyv0/" * @@ -118,8 +118,8 @@ The `variable_name`s (and their `shortname`s used in NetCDF files) available from the JRA55-do are: - `:freshwater_river_flux` ("friver") - - `:freshwater_rain_flux` ("prra") - - `:freshwater_snow_flux` ("prsn") + - `:rain_freshwater_flux` ("prra") + - `:snow_freshwater_flux` ("prsn") - `:freshwater_iceberg_flux` ("licalvf") - `:specific_humidity` ("huss") - `:sea_level_pressure` ("psl") @@ -192,6 +192,10 @@ function jra55_field_time_series(variable_name, grid=nothing; # ds["lat_bnds"]: bounding latitudes between which variables are averaged # ds[shortname]: the variable data + if variable_name == :rain_freshwater_flux + @show ds + end + # Nodes at the variable location λc = ds["lon"][:] φc = ds["lat"][:] @@ -288,7 +292,6 @@ function jra55_field_time_series(variable_name, grid=nothing; if isnothing(grid) return native_fts else # make a new FieldTimeSeries and interpolate native data onto it. - boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; boundary_conditions) @@ -307,8 +310,8 @@ function jra55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # T_jra55 = jra55_field_time_series(:temperature, grid; time_indices, architecture) q_jra55 = jra55_field_time_series(:specific_humidity, grid; time_indices, architecture) p_jra55 = jra55_field_time_series(:sea_level_pressure, grid; time_indices, architecture) - Fr_jra55 = jra55_field_time_series(:freshwater_rain_flux, grid; time_indices, architecture) - Fs_jra55 = jra55_field_time_series(:freshwater_snow_flux, grid; time_indices, architecture) + Fr_jra55 = jra55_field_time_series(:rain_freshwater_flux, grid; time_indices, architecture) + Fs_jra55 = jra55_field_time_series(:snow_freshwater_flux, grid; time_indices, architecture) Qlw_jra55 = jra55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) Qsw_jra55 = jra55_field_time_series(:downwelling_shortwave_radiation, grid; time_indices, architecture) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 4a6cd6de..c41aec12 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -60,9 +60,8 @@ function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) end include("radiation.jl") -include("similarity_theory_surface_fluxes.jl") +include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") -include("compute_atmosphere_ocean_fluxes.jl") # include("ocean_sea_ice_model_fluxes.jl") # include("ocean_sea_ice_surfaces.jl") diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/compute_atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/compute_atmosphere_ocean_fluxes.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index ea318039..7b831e3b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -16,7 +16,7 @@ using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Fields: ConstantField using Oceananigans.Utils: launch!, Time -using Oceananigans.Operators: ℑxᶜᵃᵃ, ℑyᵃᶜᵃ +using Oceananigans.Operators: ℑxᶜᵃᵃ, ℑyᵃᶜᵃ, ℑxᶠᵃᵃ, ℑyᵃᶠᵃ using KernelAbstractions: @kernel, @index @@ -34,8 +34,18 @@ struct OceanSeaIceSurfaceFluxes{T, P, C, R, PI, PC, FT} # The ocean is Boussinesq, so these are _only_ coupled properties: ocean_reference_density :: FT ocean_heat_capacity :: FT + # ocean_temperature_units + # freshwater_density ? end +# Possible units for temperature and salinity +struct DegreesCelsius end +struct DegreesKelvin end + +const celsius_to_kelvin = 273.15 +@inline convert_to_kelvin(::DegreesCelsius, T::FT) where FT = T + convert(FT, celsius_to_kelvin) +@inline convert_to_kelvin(::DegreesKelvin, T) = T + Base.summary(crf::OceanSeaIceSurfaceFluxes) = "OceanSeaIceSurfaceFluxes" Base.show(io::IO, crf::OceanSeaIceSurfaceFluxes) = print(io, summary(crf)) @@ -45,15 +55,16 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; ocean_reference_density = reference_density(ocean), ocean_heat_capacity = heat_capacity(ocean)) - FT = eltype(ocean.model.grid) + grid = ocean.model.grid + FT = eltype(grid) ocean_reference_density = convert(FT, ocean_reference_density) ocean_heat_capacity = convert(FT, ocean_heat_capacity) # It's the "thermodynamics gravitational acceleration" # (as opposed to the one used for the free surface) - g = ocean.model.buoyancy.model.gravitational_acceleration - turbulent_fluxes = SimilarityTheoryTurbulentFluxes(FT, gravitational_acceleration=g) + gravitational_acceleration = ocean.model.buoyancy.model.gravitational_acceleration + turbulent_fluxes = SimilarityTheoryTurbulentFluxes(grid; gravitational_acceleration) prescribed_fluxes = nothing @@ -165,20 +176,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) # to compute from 0:Nx+1, ie in halo regions fill_halo_regions!(centered_velocity_fluxes) - launch!(arch, grid, :xy, accumulate_atmosphere_ocean_fluxes!, - grid, clock, - staggered_velocity_fluxes, - net_tracer_fluxes, - centered_velocity_fluxes, - prescribed_fluxes, - ocean_state, - atmosphere_state, - atmosphere_downwelling_radiation, - radiation_properties, - atmosphere_freshwater_flux, - coupled_model.fluxes.ocean_reference_density, - coupled_model.fluxes.ocean_heat_capacity, - ice_thickness) + launch!(arch, grid, :xy, reconstruct_momentum_fluxes!, + grid, staggered_velocity_fluxes, centered_velocity_fluxes) return nothing end @@ -209,7 +208,7 @@ end uₒ = ℑxᶜᵃᵃ(i, j, 1, grid, ocean_state.u) vₒ = ℑyᵃᶜᵃ(i, j, 1, grid, ocean_state.v) Uₒ = SVector(uₒ, vₒ) - Tₒ = ocean_state.T[i, j, 1] + Tₒ = ocean_state.T[i, j, 1] + 273.15 # K Sₒ = ocean_state.S[i, j, 1] # Atmos state @@ -228,7 +227,12 @@ end # Build surface state with saturated specific humidity surface_type = AtmosphericThermodynamics.Liquid() - q★ = surface_saturation_specific_humidity(ℂ, Tₒ, ψₐ, surface_type) + water_mole_fraction = turbulent_fluxes.water_mole_fraction + water_vapor_saturation = turbulent_fluxes.water_vapor_saturation + q★ = seawater_saturation_specific_humidity(ℂ, Tₒ, Sₒ, ψₐ, + water_mole_fraction, + water_vapor_saturation, + surface_type) # Thermodynamic and dynamic state at the surface ψ₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₒ, q★) @@ -242,21 +246,33 @@ end zᵐ = convert(eltype(grid), 1e-2) zʰ = convert(eltype(grid), 1e-2) - values = SurfaceFluxes.ValuesOnly(Ψₐ, Ψ₀, zᵐ, zʰ) + Uᵍ = zero(grid) # gustiness + β = one(grid) # surface "resistance" + values = SurfaceFluxes.ValuesOnly(Ψₐ, Ψ₀, zᵐ, zʰ, Uᵍ, β) conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + update_turbulent_flux_fields!(turbulent_fluxes.fields, i, j, grid, conditions) # Compute heat fluxes, bulk flux first Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation_properties) Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state) - Qs = conditions.shf - Qℓ = conditions.lhf - ΣQ = Qu + Qs + Qℓ + Qs = conditions.shf # sensible heat flux + Qℓ = conditions.lhf # latent heat flux + ΣQ = Qd + Qu + Qs + Qℓ + + # Accumulate freshwater fluxes. Rain, snow, runoff -- all freshwater. + M = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) # mass fluxes apparently? + ρᶠ = 1000 # density of freshwater? + ΣF = M / ρᶠ # convert from a mass flux to a volume flux / velocity - E = conditions.evaporation - F = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) + # Apparently, conditions.evaporation is a mass flux of water. + # So, we divide by the density of freshwater. + E = - conditions.evaporation / ρᶠ # ? - @show conditions + # Clip evaporation. TODO: figure out why this is needed. + E = min(zero(E), E) # why does this happen? + ΣF += E + # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes Jᵘ = centered_velocity_fluxes.u Jᵛ = centered_velocity_fluxes.v Jᵀ = net_tracer_fluxes.T @@ -268,8 +284,9 @@ end atmos_ocean_Jᵘ = conditions.ρτxz / ρₒ atmos_ocean_Jᵛ = conditions.ρτyz / ρₒ atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) - atmos_ocean_Jˢ = Sₒ * (E + F) + atmos_ocean_Jˢ = Sₒ * ΣF + # Mask fluxes over land for convenience kᴺ = size(grid, 3) # index of the top ocean cell inactive = inactive_node(i, j, kᴺ, grid, c, c, c) @@ -281,78 +298,13 @@ end end end -@kernel function accumulate_atmosphere_ocean_fluxes!(grid, - clock, - staggered_velocity_fluxes, - centered_velocity_fluxes) - +@kernel function reconstruct_momentum_fluxes!(grid, J, Jᶜᶜᶜ) i, j = @index(Global, NTuple) - kᴺ = size(grid, 3) # index of the top ocean cell - - time = Time(clock.time) - - Jᵘ = staggered_velocity_fluxes.u - Jᵛ = staggered_velocity_fluxes.v @inbounds begin - Jᵘ[i, j, 1] = ℑxᶠᵃᵃ(i, j, k, grid, centered_velocity_fluxes.u) - Jᵛ[i, j, 1] = ℑyᵃᶠᵃ(i, j, k, grid, centered_velocity_fluxes.v) + J.u[i, j, 1] = ℑxᶠᵃᵃ(i, j, 1, grid, Jᶜᶜᶜ.u) + J.v[i, j, 1] = ℑyᵃᶠᵃ(i, j, 1, grid, Jᶜᶜᶜ.v) end - - #= - # Note: there could one or more formula(e) - τˣ_formula = bulk_momentum_flux_formulae.u - τʸ_formula = bulk_momentum_flux_formulae.v - Q_formula = bulk_heat_flux_formulae - F_formula = bulk_tracer_flux_formulae.S - - atmos_state_names = keys(atmos_state) - ocean_state_names = keys(atmos_state) - - atmos_state_ij = stateindex(atmos_state, i, j, 1, time) - ocean_state_ij = stateindex(ocean_state, i, j, 1, time) - - # Compute transfer velocity scale - ΔUᶠᶜᶜ = bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) - ΔUᶜᶠᶜ = bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) - ΔUᶜᶜᶜ = bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, bulk_velocity, atmos_state, ocean_state) - - # Compute momentum fluxes - τˣ = cross_realm_flux(i, j, grid, time, τˣ_formula, ΔUᶠᶜᶜ, atmos_state, ocean_state) - τʸ = cross_realm_flux(i, j, grid, time, τʸ_formula, ΔUᶜᶠᶜ, atmos_state, ocean_state) - - # Compute heat fluxes, bulk flux first - Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation) - - Qu = net_upwelling_radiation(i, j, grid, time, radiation, ocean_state) - Q★ = cross_realm_flux(i, j, grid, time, Q_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) - Q = Q★ + Qd + Qu - - # Compute salinity fluxes, bulk flux first - Fp = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) - F★ = cross_realm_flux(i, j, grid, time, F_formula, ΔUᶜᶜᶜ, atmos_state_ij, ocean_state_ij) - F = F★ + Fp - - # Then the rest of the heat fluxes - ρₒ = ocean_reference_density - cₚ = ocean_heat_capacity - - atmos_ocean_Jᵘ = τˣ / ρₒ - atmos_ocean_Jᵛ = τʸ / ρₒ - atmos_ocean_Jᵀ = Q / (ρₒ * cₚ) - - S = ocean_state_ij.S - atmos_ocean_Jˢ = S * F - - @inbounds begin - # Set fluxes - # TODO: should this be peripheral_node? - Jᵘ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, f, c, c), zero(grid), atmos_ocean_Jᵘ) - Jᵛ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, f, c), zero(grid), atmos_ocean_Jᵛ) - Jᵀ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jᵀ) - Jˢ[i, j, 1] = ifelse(inactive_node(i, j, kᴺ, grid, c, c, c), zero(grid), atmos_ocean_Jˢ) - end - =# end @inline function net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation) @@ -369,10 +321,10 @@ end ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) # Ocean surface temperature (departure from reference, typically in ᵒC) - Tₒ = @inbounds ocean_state.T[i, j, 1] + Tₒ = @inbounds ocean_state.T[i, j, 1] + 273.15 # K # Note: positive implies _upward_ heat flux, and therefore cooling. - return σ * ϵ * (Tₒ + Tᵣ)^4 + return σ * ϵ * Tₒ^4 end @inline cross_realm_flux(i, j, grid, time, ::Nothing, args...) = zero(grid) @@ -394,261 +346,3 @@ end cross_realm_flux(i, j, grid, time, flux_tuple[3], args...) + cross_realm_flux(i, j, grid, time, flux_tuple[4], args...) -#= -function default_atmosphere_ocean_fluxes(FT=Float64, tracers=tuple(:S)) - # Note: we are constantly coping with the fact that the ocean is ᵒC. - ocean_reference_temperature = 273.15 - momentum_transfer_coefficient = 5e-3 - evaporation_transfer_coefficient = 1e-3 - sensible_heat_transfer_coefficient = 2e-3 - vaporization_enthalpy = 2.5e-3 - - momentum_transfer_coefficient = convert(FT, momentum_transfer_coefficient) - evaporation_transfer_coefficient = convert(FT, evaporation_transfer_coefficient) - sensible_heat_transfer_coefficient = convert(FT, sensible_heat_transfer_coefficient) - vaporization_enthalpy = convert(FT, vaporization_enthalpy) - - τˣ = BulkFormula(RelativeUVelocity(), momentum_transfer_coefficient) - τʸ = BulkFormula(RelativeVVelocity(), momentum_transfer_coefficient) - momentum_flux_formulae = (u=τˣ, v=τʸ) - - # Note: reference temperature comes in here - water_specific_humidity_difference = SpecificHumidity(FT) - evaporation = nothing #BulkFormula(SpecificHumidity(FT), evaporation_transfer_coefficient) - tracer_flux_formulae = (; S = evaporation) - - latent_heat_difference = LatentHeat(specific_humidity_difference = water_specific_humidity_difference; vaporization_enthalpy) - latent_heat_formula = nothing #BulkFormula(latent_heat_difference, evaporation_transfer_coefficient) - - sensible_heat_difference = SensibleHeat(FT; ocean_reference_temperature) - sensible_heat_formula = BulkFormula(sensible_heat_difference, sensible_heat_transfer_coefficient) - - heat_flux_formulae = (sensible_heat_formula, latent_heat_formula) - - return CrossRealmFluxes(momentum = momentum_flux_formulae, - heat = heat_flux_formulae, - tracers = tracer_flux_formulae) -end -=# - -#= -##### -##### Bulk formula -##### - -""" - BulkFormula(air_sea_difference, transfer_coefficient) - -The basic structure of a flux `J` computed by a bulk formula is: - -```math -J = - ρₐ * C * Δc * ΔU -``` - -where `ρₐ` is the density of air, `C` is the `transfer_coefficient`, -`Δc` is the air_sea_difference, and `ΔU` is the bulk velocity scale. -""" -struct BulkFormula{F, CD} - air_sea_difference :: F - transfer_coefficient :: CD -end - -@inline function cross_realm_flux(i, j, grid, time, formula::BulkFormula, ΔU, atmos_state, ocean_state) - ρₐ = stateindex(atmos_state.ρ, i, j, 1, time) - C = formula.transfer_coefficient - Δc = air_sea_difference(i, j, grid, time, formula.air_sea_difference, atmos_state, ocean_state) - - # Note the sign convention, which corresponds to positive upward fluxes: - return - ρₐ * C * Δc * ΔU -end - -##### -##### Air-sea differences -##### - -@inline air_sea_difference(i, j, grid, time, air, sea) = stateindex(air, i, j, 1, time) - - stateindex(sea, i, j, 1, time) - -struct RelativeUVelocity end -struct RelativeVVelocity end - -@inline function air_sea_difference(i, j, grid, time, ::RelativeUVelocity, atmos_state, ocean_state) - uₐ = atmos_state.u - uₒ = ocean_state.u - return air_sea_difference(i, j, grid, time, uₐ, uₒ) -end - -@inline function air_sea_difference(i, j, grid, time, ::RelativeVVelocity, atmos_state, ocean_state) - vₐ = atmos_state.v - vₒ = ocean_state.v - return air_sea_difference(i, j, grid, time, vₐ, vₒ) -end - -struct SensibleHeat{FT} - ocean_reference_temperature :: FT -end - -SensibleHeat(FT::DataType=Float64; ocean_reference_temperature=273.15) = - SensibleHeat(convert(FT, ocean_reference_temperature)) - -@inline function air_sea_difference(i, j, grid, time, Qs::SensibleHeat, atmos_state, ocean_state) - cₚ = stateindex(atmos_state.cₚ, i, j, 1, time) - Tₐ = atmos_state.T - - # Compute ocean temperature in degrees K - Tᵣ = Qs.ocean_reference_temperature - Tₒᵢ = stateindex(ocean_state.T, i, j, 1, time) - Tₒ = Tₒᵢ + Tᵣ - - ΔT = air_sea_difference(i, j, grid, time, Tₐ, Tₒ) - - return @inbounds cₚ[i, j, 1] * ΔT -end - -struct SpecificHumidity{S} - saturation_specific_humidity :: S - - @doc """ - SpecificHumidity(FT = Float64; - saturation_specific_humidity = LargeYeagerSaturationVaporFraction(FT)) - - """ - function SpecificHumidity(FT = Float64; - saturation_specific_humidity = LargeYeagerSaturationVaporFraction(FT)) - S = typeof(saturation_specific_humidity) - return new{S}(saturation_specific_humidity) - end -end - -struct LargeYeagerSaturationVaporFraction{FT} - q₀ :: FT - c₁ :: FT - c₂ :: FT - reference_temperature :: FT -end - -""" - LargeYeagerSaturationVaporFraction(FT = Float64; - q₀ = 0.98, - c₁ = 640380, - c₂ = -5107.4, - reference_temperature = 273.15) - -""" -function LargeYeagerSaturationVaporFraction(FT = Float64; - q₀ = 0.98, - c₁ = 640380, - c₂ = -5107.4, - reference_temperature = 273.15) - - return LargeYeagerSaturationVaporFraction(convert(FT, q₀), - convert(FT, c₁), - convert(FT, c₂), - convert(FT, reference_temperature)) -end - -@inline function saturation_specific_humidity(i, j, grid, time, - ratio::LargeYeagerSaturationVaporFraction, - atmos_state, ocean_state) - - Tₒ = stateindex(ocean_state.T, i, j, 1, time) - ρₐ = stateindex(atmos_state.ρ, i, j, 1, time) - Tᵣ = ratio.reference_temperature - q₀ = ratio.q₀ - c₁ = ratio.c₁ - c₂ = ratio.c₂ - - return q₀ * c₁ * exp(-c₂ / (Tₒ + Tᵣ)) -end - -@inline function air_sea_difference(i, j, grid, time, diff::SpecificHumidity, atmos_state, ocean_state) - vapor_fraction = diff.saturation_specific_humidity - qₐ = stateindex(atmos_state.q, i, j, 1, time) - qₛ = saturation_specific_humidity(i, j, grid, time, vapor_fraction, atmos_state, ocean_state) - return qₐ - qₛ -end - -struct LatentHeat{Q, FT} - specific_humidity_difference :: Q - vaporization_enthalpy :: FT -end - -""" - LatentHeat(FT = Float64; - vaporization_enthalpy = 2.5e3 # J / g - specific_humidity_difference = SpecificHumidity(FT)) - -""" -function LatentHeat(FT = Float64; - vaporization_enthalpy = 2.5e3, # J / g - specific_humidity_difference = SpecificHumidity(FT)) - - vaporization_enthalpy = convert(FT, vaporization_enthalpy) - return LatentHeat(specific_humidity_difference, vaporization_enthalpy) -end - -@inline function air_sea_difference(i, j, grid, time, diff::LatentHeat, atmos, ocean) - Δq = air_sea_difference(i, j, grid, time, diff.specific_humidity_difference, atmos, ocean) - Λᵥ = diff.vaporization_enthalpy - return Λᵥ * Δq -end - -##### -##### Bulk velocity scales -##### - -##### -##### Convenience containers for surface fluxes -##### -##### "Cross realm fluxes" can refer to the flux _data_ (ie, fields representing -##### the total flux for a given variable), or to the flux _components_ / formula. -##### - -struct CrossRealmFluxes{M, H, T} - momentum :: M - heat :: H - tracers :: T -end - -CrossRealmFluxes(; momentum=nothing, heat=nothing, tracers=nothing) = - CrossRealmFluxes(momentum, heat, tracers) - -Base.summary(osf::CrossRealmFluxes) = "CrossRealmFluxes" -Base.show(io::IO, osf::CrossRealmFluxes) = print(io, summary(osf)) - -# struct AtmosphereOnlyVelocityScale end -struct RelativeVelocityScale end - -@inline function bulk_velocity_scaleᶠᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, atmos_state, ocean_state) - uₐ = atmos_state.u - vₐ = atmos_state.v - uₒ = ocean_state.u - vₒ = ocean_state.v - Δu = stateindex(uₐ, i, j, 1, time) - stateindex(uₒ, i, j, 1, time) - Δv² = ℑxyᶠᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) - return sqrt(Δu^2 + Δv²) -end - -@inline function bulk_velocity_scaleᶜᶠᶜ(i, j, grid, time, ::RelativeVelocityScale, atmos_state, ocean_state) - uₐ = atmos_state.u - vₐ = atmos_state.v - uₒ = ocean_state.u - vₒ = ocean_state.v - Δu² = ℑxyᶜᶠᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) - Δv = stateindex(vₐ, i, j, 1, time) - stateindex(vₒ, i, j, 1, time) - return sqrt(Δu² + Δv^2) -end - -@inline function bulk_velocity_scaleᶜᶜᶜ(i, j, grid, time, ::RelativeVelocityScale, atmos_state, ocean_state) - uₐ = atmos_state.u - vₐ = atmos_state.v - uₒ = ocean_state.u - vₒ = ocean_state.v - Δu² = ℑxᶜᵃᵃ(i, j, 1, grid, Δϕt², uₐ, uₒ, time) - Δv² = ℑyᵃᶜᵃ(i, j, 1, grid, Δϕt², vₐ, vₒ, time) - return sqrt(Δu² + Δv²) -end - - -=# - diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl deleted file mode 100644 index 5df717a2..00000000 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_surface_fluxes.jl +++ /dev/null @@ -1,78 +0,0 @@ -using Oceananigans.Utils: prettysummary - -using SurfaceFluxes.Parameters: SurfaceFluxesParameters, AbstractSurfaceFluxesParameters -using SurfaceFluxes.UniversalFunctions: BusingerParams - -using ..PrescribedAtmospheres: PrescribedAtmosphereThermodynamicsParameters - -import Thermodynamics as AtmosphericThermodynamics - -import SurfaceFluxes.Parameters: - thermodynamics_params, - uf_params, - von_karman_const, - universal_func_type, - grav - -##### -##### Bulk turbulent fluxes based on similarity theory -##### - -struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP} <: AbstractSurfaceFluxesParameters - gravitational_acceleration :: FT - von_karman_constant :: FT - bulk_velocity_scale :: ΔU - universal_function :: UF - thermodynamics_parameters :: TP -end - -const STTF = SimilarityTheoryTurbulentFluxes -thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters -universal_func_type(fluxes::STTF) = universal_func_type(typeof(fluxes.universal_function)) -uf_params(fluxes::STTF) = fluxes.universal_function -von_karman_const(fluxes::STTF) = fluxes.von_karman_constant -grav(fluxes::STTF) = fluxes.gravitational_acceleration - -Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" - -function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) - print(io, summary(fluxes), '\n', - "├── gravitational_acceleration: ", prettysummary(fluxes.gravitational_acceleration), '\n', - "├── von_karman_constant: ", prettysummary(fluxes.von_karman_constant), '\n', - "├── bulk_velocity_scale: ", summary(fluxes.bulk_velocity_scale), '\n', - "├── universal_function: ", summary(fluxes.universal_function), '\n', - "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) -end - -const PATP = PrescribedAtmosphereThermodynamicsParameters - -function SimilarityTheoryTurbulentFluxes(FT = Float64; - gravitational_acceleration = 9.80665, - bulk_velocity_scale = nothing, - von_karman_constant = 0.4, - universal_function = default_universal_function_parameters(FT), - thermodynamics_parameters = PATP(FT)) - - return SimilarityTheoryTurbulentFluxes(gravitational_acceleration, - von_karman_constant, - bulk_velocity_scale, - universal_function, - thermodynamics_parameters) -end - -# See SurfaceFluxes.jl for other parameter set options. -default_universal_function_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), - a_m = convert(FT, 4.7), - a_h = convert(FT, 4.7), - ζ_a = convert(FT, 2.5), - γ = convert(FT, 4.42)) - -function surface_saturation_specific_humidity(params, surface_temperature, atmos_state, surface_type) - Tₛ = surface_temperature - ρₛ = atmos_state.ρ # should we extrapolate to obtain this? - p★ = AtmosphericThermodynamics.saturation_vapor_pressure(params, Tₛ, surface_type) - q★ = AtmosphericThermodynamics.q_vap_saturation_from_density(params, Tₛ, ρₛ, p★) - q★ *= 0.98 # TODO: understand this better... - return q★ -end - diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl new file mode 100644 index 00000000..84977970 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -0,0 +1,190 @@ +using Oceananigans.Utils: prettysummary +using Oceananigans.Grids: AbstractGrid + +using Thermodynamics: Liquid +using SurfaceFluxes.Parameters: SurfaceFluxesParameters, AbstractSurfaceFluxesParameters +using SurfaceFluxes.UniversalFunctions: BusingerParams + +using ..PrescribedAtmospheres: PrescribedAtmosphereThermodynamicsParameters + +import Thermodynamics as AtmosphericThermodynamics + +import SurfaceFluxes.Parameters: + thermodynamics_params, + uf_params, + von_karman_const, + universal_func_type, + grav + +##### +##### Bulk turbulent fluxes based on similarity theory +##### + +struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, F} <: AbstractSurfaceFluxesParameters + gravitational_acceleration :: FT + von_karman_constant :: FT + bulk_velocity_scale :: ΔU + universal_function :: UF + thermodynamics_parameters :: TP + water_vapor_saturation :: S + water_mole_fraction :: W + fields :: F +end + +const STTF = SimilarityTheoryTurbulentFluxes +thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters +universal_func_type(fluxes::STTF) = universal_func_type(typeof(fluxes.universal_function)) +uf_params(fluxes::STTF) = fluxes.universal_function +von_karman_const(fluxes::STTF) = fluxes.von_karman_constant +grav(fluxes::STTF) = fluxes.gravitational_acceleration + +Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" + +struct ClasiusClapyeronSaturation end + +@inline function water_saturation_specific_humidity(::ClasiusClapyeronSaturation, ℂₐ, ρₛ, Tₛ) + p★ = AtmosphericThermodynamics.saturation_vapor_pressure(ℂₐ, Tₛ, Liquid()) + q★ = AtmosphericThermodynamics.q_vap_saturation_from_density(ℂₐ, Tₛ, ρₛ, p★) + return q★ +end + +Base.@kwdef struct LargeYeagerSaturation{FT} + c₁ :: FT = 640380.0 # kg m⁻³ + c₂ :: FT = 5107.4 # K +end + +const LYS = LargeYeagerSaturation +@inline water_saturation_specific_humidity(lys::LYS, ℂₐ, ρₛ, Tₛ) = lys.c₁ * exp(-lys.c₂ / Tₛ) / ρₛ + +function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) + print(io, summary(fluxes), '\n', + "├── gravitational_acceleration: ", prettysummary(fluxes.gravitational_acceleration), '\n', + "├── von_karman_constant: ", prettysummary(fluxes.von_karman_constant), '\n', + "├── bulk_velocity_scale: ", summary(fluxes.bulk_velocity_scale), '\n', + "├── universal_function: ", summary(fluxes.universal_function), '\n', + "├── water_mole_fraction: ", summary(fluxes.water_mole_fraction), '\n', + "├── water_vapor_saturation: ", summary(fluxes.water_vapor_saturation), '\n', + "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) +end + +const PATP = PrescribedAtmosphereThermodynamicsParameters + +function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; + gravitational_acceleration = convert(FT, 9.80665), + bulk_velocity_scale = nothing, + von_karman_constant = convert(FT, 0.4), + universal_function = default_universal_function_parameters(FT), + thermodynamics_parameters = PATP(FT), + water_vapor_saturation = ClasiusClapyeronSaturation(), + water_mole_fraction = convert(FT, 0.98), + fields = nothing) + + return SimilarityTheoryTurbulentFluxes(gravitational_acceleration, + von_karman_constant, + bulk_velocity_scale, + universal_function, + thermodynamics_parameters, + water_vapor_saturation, + water_mole_fraction, + fields) +end + +function SimilarityTheoryTurbulentFluxes(grid::AbstractGrid; kw...) + evaporation = Field{Center, Center, Nothing}(grid) + latent_heat_flux = Field{Center, Center, Nothing}(grid) + sensible_heat_flux = Field{Center, Center, Nothing}(grid) + + fields = (; latent_heat_flux, sensible_heat_flux, evaporation) + + return SimilarityTheoryTurbulentFluxes(eltype(grid); kw..., fields) +end + +@inline update_turbulent_flux_fields!(::Nothing, args...) = nothing + +@inline function update_turbulent_flux_fields!(fields, i, j, grid, conditions) + ρᶠ = 1000 # density of freshwater? + @inbounds begin + fields.latent_heat_flux[i, j, 1] = conditions.lhf + fields.sensible_heat_flux[i, j, 1] = conditions.shf + # "Salt flux" has the opposite sign of "freshwater flux" + fields.evaporation[i, j, 1] = - conditions.evaporation / ρᶠ + end + return nothing +end + +# See SurfaceFluxes.jl for other parameter set options. +default_universal_function_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), + a_m = convert(FT, 4.7), + a_h = convert(FT, 4.7), + ζ_a = convert(FT, 2.5), + γ = convert(FT, 4.42)) + +function seawater_saturation_specific_humidity(atmosphere_thermodynamics_parameters, + surface_temperature, + surface_salinity, + atmos_state, + water_mole_fraction, + water_vapor_saturation, + ::Liquid) + + ℂₐ = atmosphere_thermodynamics_parameters + Tₛ = surface_temperature + Sₛ = surface_salinity + ρₛ = atmos_state.ρ # surface density -- should we extrapolate to obtain this? + + q★_H₂O = water_saturation_specific_humidity(water_vapor_saturation, ℂₐ, ρₛ, Tₛ) + x_H₂O = compute_water_mole_fraction(water_mole_fraction, Sₛ) + + # Return saturation specific humidity for salty seawater + return q★_H₂O * x_H₂O +end + +struct SalinityConstituent{FT} + molar_mass :: FT + mass_fraction :: FT +end + +struct WaterMoleFraction{FT, C} + water_molar_mass :: FT + salinity_constituents :: C +end + +function WaterMoleFraction(FT=Float64) + water_molar_mass = convert(FT, 18.02) + + # TODO: find reference for these + salinity_constituents = ( + chloride = SalinityConstituent{FT}(35.45, 0.56), + sodium = SalinityConstituent{FT}(22.99, 0.31), + sulfate = SalinityConstituent{FT}(96.06, 0.08), + magnesium = SalinityConstituent{FT}(24.31, 0.05), + ) + + return SeawaterComposition(water_molar_mass, salinity_constituents) +end + +@inline compute_water_mole_fraction(x_H₂O::Number, S) = x_H₂O + +@inline function compute_water_mole_fraction(wmf::WaterMoleFraction, S) + s = S / 1000 # concentration + + # Molecular weights + μ_H₂O = wmf.water_molar_mass + + # Salinity constituents: Cl, Na, SO₄, Mg + μ_Cl = wmf.salinity_constituents.chloride.molar_mass + μ_Na = wmf.salinity_constituents.sodium.molar_mass + μ_SO₄ = wmf.salinity_constituents.sulfate.molar_mass + μ_Mg = wmf.salinity_constituents.magnesium.molar_mass + + # Salinity constituent fractions + ϵ_Cl = wmf.salinity_constituents.chloride.mass_fraction + ϵ_Na = wmf.salinity_constituents.sodium.mass_fraction + ϵ_SO₄ = wmf.salinity_constituents.sulfate.mass_fraction + ϵ_Mg = wmf.salinity_constituents.magnesium.mass_fraction + + α = μ_H₂O * (ϵ_Cl/μ_Cl + ϵ_Na/μ_Na + ϵ_SO₄/μ_SO₄ + ϵ_Mg/μ_Mg) + + return (1 - s) / (1 - s + α * s) +end + diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 7d3ada77..247096f8 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -4,7 +4,6 @@ using Oceananigans.Utils: prettysummary using Thermodynamics.Parameters: AbstractThermodynamicsParameters -# TODO: write parameter meaning here import Thermodynamics.Parameters: gas_constant, # molmass_dryair, # Molar mass of dry air (without moisture) @@ -13,14 +12,16 @@ import Thermodynamics.Parameters: T_0, # Enthalpy reference temperature LH_v0, # Vaporization enthalpy at the reference temperature LH_s0, # Sublimation enthalpy at the reference temperature - cp_d, # Isobaric specific heat capacity of dry air cp_v, # Isobaric specific heat capacity of gaseous water vapor cp_l, # Isobaric specific heat capacity of liquid water cp_i, # Isobaric specific heat capacity of water ice T_freeze, # Freezing temperature of _pure_ water T_triple, # Triple point temperature of _pure_ water press_triple, # Triple point pressure of pure water - T_icenuc # Temperature of ice nucleation of pure water + T_icenuc, # Lower temperature limit for the presence of liquid condensate + # (below which homogeneous ice nucleation occurs) + pow_icenuc # "Power parameter" that controls liquid/ice condensate partitioning + # during partial ice nucleation import ..OceanSeaIceModels: surface_velocities, @@ -82,9 +83,9 @@ end const CP = ConstitutiveParameters -gas_constant(p::CP) = p.gas_constant -molmass_dryair(p::CP) = p.dry_air_molar_mass -molmass_water(p::CP) = p.water_molar_mass +@inline gas_constant(p::CP) = p.gas_constant +@inline molmass_dryair(p::CP) = p.dry_air_molar_mass +@inline molmass_water(p::CP) = p.water_molar_mass struct HeatCapacityParameters{FT} <: AbstractThermodynamicsParameters{FT} dry_air_adiabatic_exponent :: FT @@ -103,6 +104,15 @@ end Base.show(io::IO, p::HeatCapacityParameters) = print(io, summary(p)) +""" + HeatCapacityParameters(FT = Float64, + dry_air_adiabatic_exponent = 2/7, + water_vapor_heat_capacity = 1859, + liquid_water_heat_capacity = 4181, + water_ice_heat_capacity = 2100) + +Isobaric heat capacities. +""" function HeatCapacityParameters(FT = Float64; dry_air_adiabatic_exponent = 2/7, water_vapor_heat_capacity = 1859, @@ -116,19 +126,19 @@ function HeatCapacityParameters(FT = Float64; end const HCP = HeatCapacityParameters -cp_v(p::HCP) = p.water_vapor_heat_capacity -cp_l(p::HCP) = p.liquid_water_heat_capacity -cp_i(p::HCP) = p.water_ice_heat_capacity -kappa_d(p::HCP) = p.dry_air_adiabatic_exponent +@inline cp_v(p::HCP) = p.water_vapor_heat_capacity +@inline cp_l(p::HCP) = p.liquid_water_heat_capacity +@inline cp_i(p::HCP) = p.water_ice_heat_capacity +@inline kappa_d(p::HCP) = p.dry_air_adiabatic_exponent struct PhaseTransitionParameters{FT} <: AbstractThermodynamicsParameters{FT} - reference_vaporization_enthalpy :: FT - reference_sublimation_enthalpy :: FT - reference_temperature :: FT - triple_point_temperature :: FT - triple_point_pressure :: FT - water_freezing_temperature :: FT - ice_nucleation_temperature :: FT + reference_vaporization_enthalpy :: FT + reference_sublimation_enthalpy :: FT + reference_temperature :: FT + triple_point_temperature :: FT + triple_point_pressure :: FT + water_freezing_temperature :: FT + total_ice_nucleation_temperature :: FT end function Base.summary(p::PhaseTransitionParameters{FT}) where FT @@ -139,7 +149,7 @@ function Base.summary(p::PhaseTransitionParameters{FT}) where FT ", Tᵗʳ=", prettysummary(p.triple_point_temperature), ", pᵗʳ=", prettysummary(p.triple_point_pressure), ", Tᶠ=", prettysummary(p.water_freezing_temperature), - ", Tⁱⁿ=", prettysummary(p.ice_nucleation_temperature), ')') + ", Tⁱⁿ=", prettysummary(p.total_ice_nucleation_temperature), ')') end Base.show(io::IO, p::PhaseTransitionParameters) = print(io, summary(p)) @@ -150,8 +160,8 @@ function PhaseTransitionParameters(FT = Float64; reference_temperature = 273.16, triple_point_temperature = 273.16, triple_point_pressure = 611.657, - water_freezing_temperature = 273.16, - ice_nucleation_temperature = 233) + water_freezing_temperature = 273.15, + total_ice_nucleation_temperature = 233) return PhaseTransitionParameters(convert(FT, reference_vaporization_enthalpy), convert(FT, reference_sublimation_enthalpy), @@ -159,17 +169,18 @@ function PhaseTransitionParameters(FT = Float64; convert(FT, triple_point_temperature), convert(FT, triple_point_pressure), convert(FT, water_freezing_temperature), - convert(FT, ice_nucleation_temperature)) + convert(FT, total_ice_nucleation_temperature)) end const PTP = PhaseTransitionParameters -LH_v0(p::PTP) = p.reference_vaporization_enthalpy -LH_s0(p::PTP) = p.reference_sublimation_enthalpy -T_freeze(p::PTP) = p.water_freezing_temperature -T_triple(p::PTP) = p.triple_point_temperature -T_icenuc(p::PTP) = p.ice_nucleation_temperature -press_triple(p::PTP) = p.triple_point_pressure -T_0(p::PTP) = p.reference_temperature +@inline LH_v0(p::PTP) = p.reference_vaporization_enthalpy +@inline LH_s0(p::PTP) = p.reference_sublimation_enthalpy +@inline T_freeze(p::PTP) = p.water_freezing_temperature +@inline T_triple(p::PTP) = p.triple_point_temperature +@inline T_icenuc(p::PTP) = p.total_ice_nucleation_temperature +@inline pow_icenuc(p::PTP) = convert(eltype(p), 1) # we shouldn't have the need to set this +@inline press_triple(p::PTP) = p.triple_point_pressure +@inline T_0(p::PTP) = p.reference_temperature struct PrescribedAtmosphereThermodynamicsParameters{FT} <: AbstractThermodynamicsParameters{FT} constitutive :: ConstitutiveParameters{FT} @@ -205,33 +216,34 @@ function Base.show(io::IO, p::PrescribedAtmosphereThermodynamicsParameters) " ├── triple_point_temperature (Tᵗʳ): ", prettysummary(pt.triple_point_temperature), '\n', " ├── triple_point_pressure (pᵗʳ): ", prettysummary(pt.triple_point_pressure), '\n', " ├── water_freezing_temperature (Tᶠ): ", prettysummary(pt.water_freezing_temperature), '\n', - " └── ice_nucleation_temperature (Tⁱⁿ): ", prettysummary(pt.ice_nucleation_temperature)) + " └── total_ice_nucleation_temperature (Tⁱ): ", prettysummary(pt.total_ice_nucleation_temperature)) end function PrescribedAtmosphereThermodynamicsParameters(FT = Float64; - constitutive = ConstitutiveParameters(FT), - phase_transitions = PhaseTransitionParameters(FT), - heat_capacity = HeatCapacityParameters(FT)) + constitutive = ConstitutiveParameters(FT), + phase_transitions = PhaseTransitionParameters(FT), + heat_capacity = HeatCapacityParameters(FT)) return PrescribedAtmosphereThermodynamicsParameters(constitutive, heat_capacity, phase_transitions) end const HTP = PrescribedAtmosphereThermodynamicsParameters -gas_constant(p::HTP) = gas_constant(p.constitutive) -molmass_dryair(p::HTP) = molmass_dryair(p.constitutive) -molmass_water(p::HTP) = molmass_water(p.constitutive) -kappa_d(p::HTP) = kappa_d(p.heat_capacity) -LH_v0(p::HTP) = LH_v0(p.phase_transitions) -LH_s0(p::HTP) = LH_s0(p.phase_transitions) -cp_v(p::HTP) = cp_v(p.heat_capacity) -cp_l(p::HTP) = cp_l(p.heat_capacity) -cp_i(p::HTP) = cp_i(p.heat_capacity) -T_freeze(p::HTP) = T_freeze(p.phase_transitions) -T_triple(p::HTP) = T_triple(p.phase_transitions) -T_icenuc(p::HTP) = T_icenuc(p.phase_transitions) -press_triple(p::HTP) = press_triple(p.phase_transitions) -T_0(p::HTP) = T_0(p.phase_transitions) +@inline gas_constant(p::HTP) = gas_constant(p.constitutive) +@inline molmass_dryair(p::HTP) = molmass_dryair(p.constitutive) +@inline molmass_water(p::HTP) = molmass_water(p.constitutive) +@inline kappa_d(p::HTP) = kappa_d(p.heat_capacity) +@inline LH_v0(p::HTP) = LH_v0(p.phase_transitions) +@inline LH_s0(p::HTP) = LH_s0(p.phase_transitions) +@inline cp_v(p::HTP) = cp_v(p.heat_capacity) +@inline cp_l(p::HTP) = cp_l(p.heat_capacity) +@inline cp_i(p::HTP) = cp_i(p.heat_capacity) +@inline T_freeze(p::HTP) = T_freeze(p.phase_transitions) +@inline T_triple(p::HTP) = T_triple(p.phase_transitions) +@inline T_icenuc(p::HTP) = T_icenuc(p.phase_transitions) +@inline pow_icenuc(p::HTP) = pow_icenuc(p.phase_transitions) +@inline press_triple(p::HTP) = press_triple(p.phase_transitions) +@inline T_0(p::HTP) = T_0(p.phase_transitions) ##### ##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic) From fc692105e9e5d40d9d1326abdb28612ad8e7500f Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 22 Jan 2024 08:15:21 -0700 Subject: [PATCH 055/182] Regional simulation script --- .gitignore | 1 + .../CATKE_column_simulations/Manifest.toml | 1696 +++++++++++++++++ .../CATKE_column_simulations/Project.toml | 3 + .../CATKE_column_simulations/take_a_look.jl | 14 + .../regional_omip_simulation.jl | 191 ++ .../single_column_omip_simulation.jl | 17 +- src/DataWrangling/JRA55.jl | 15 +- 7 files changed, 1929 insertions(+), 8 deletions(-) create mode 100644 experiments/prototype_omip_simulation/CATKE_column_simulations/Manifest.toml create mode 100644 experiments/prototype_omip_simulation/CATKE_column_simulations/Project.toml create mode 100644 experiments/prototype_omip_simulation/CATKE_column_simulations/take_a_look.jl create mode 100644 experiments/prototype_omip_simulation/regional_omip_simulation.jl diff --git a/.gitignore b/.gitignore index 96044b04..b2288ea9 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ docs/site/ *.swp *.svg *.gif +*.zip diff --git a/experiments/prototype_omip_simulation/CATKE_column_simulations/Manifest.toml b/experiments/prototype_omip_simulation/CATKE_column_simulations/Manifest.toml new file mode 100644 index 00000000..f8d4c94f --- /dev/null +++ b/experiments/prototype_omip_simulation/CATKE_column_simulations/Manifest.toml @@ -0,0 +1,1696 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.0-beta3" +manifest_format = "2.0" +project_hash = "0729067587159d7fc93e6bd472f23cbb03ba5b95" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.3.0" + +[[deps.AbstractTrees]] +git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.4" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "3.7.2" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "bbec08a37f8722786d87bedf84eae19c020c4efa" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.7.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + 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" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Automa]] +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "1.0.3" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[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 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.2" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm]] +deps = ["CRlibm_jll"] +git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "1.0.1" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.16.1+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "c1deebd76f7a443d527fc0430d5758b8b2112ed8" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.19.1" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "349d9b36250ec19a7da18f838434db7d76c2f131" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.2" + +[[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 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.12.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.0.5+1" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.4" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.2" + +[[deps.DataAPI]] +git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.15.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "ac67408d9ddf207de5cfa9a97e114352430f01ed" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.16" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "26eb8e2331b55735c3d305d949aabd7363f07ba7" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.11" + +[[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 = ["OffsetArrays"] +git-tree-sha1 = "1bfa9de80f35ac63c6c381b2d43c590875896a1f" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.3.22" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.107" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArrays"] +git-tree-sha1 = "e8b8c949551f417e040f16e5c431b6e83e306e54" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.7" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.Extents]] +git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.2" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "4.4.4+1" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "ec22cbbcd01cba8f41eecd7d44aac1f23ee985e3" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.7.2" + +[[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 = "c5c28c245101bd59154f649e19b038d15901b5dc" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.2" + +[[deps.FilePaths]] +deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] +git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" +uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" +version = "0.8.3" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] +git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.21" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra", "Random"] +git-tree-sha1 = "5b93957f6dcd33fc343044af3d48c215be2562f1" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.9.3" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "73d1214fec245096717847c62d389a5d2ac86504" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.22.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Formatting]] +deps = ["Printf"] +git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8" +uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" +version = "0.4.2" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.1" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.1" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GLFW]] +deps = ["GLFW_jll"] +git-tree-sha1 = "35dbc482f0967d8dceaa7ce007d16f9064072166" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "3.4.1" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.3.9+0" + +[[deps.GLMakie]] +deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] +git-tree-sha1 = "e53267e2fc64f81b939849ca7bd70d8f879b5293" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.9.5" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "2d6ca471a6c7b536127afccfa7564b5b39227fe0" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.5" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.3" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "424a5a6ce7c5d97cca7bcc4eac551b97294c54af" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.9" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "e94c92c7bf4819685eb80186d51c43e71d4afa17" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.76.5+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "af13a277efd8a6e716d79ef635d5342ccb75be61" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.10.0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "8156325170d6763b5494c072ac4754214db3e669" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.3+0" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.7" + +[[deps.ImageCore]] +deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "fc5d1d3443a124fde6e92d0260cd9e064eba69f8" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.1" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.0.2+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.15.1" + + [deps.Interpolations.extensions] + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm", "RoundingEmulator"] +git-tree-sha1 = "c274ec586ea58eb7b42afd0c5d67e50ff50229b5" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.22.5" +weakdeps = ["DiffRules", "RecipesBase"] + + [deps.IntervalArithmetic.extensions] + IntervalArithmeticDiffRulesExt = "DiffRules" + IntervalArithmeticRecipesBaseExt = "RecipesBase" + +[[deps.IntervalSets]] +deps = ["Dates", "Random"] +git-tree-sha1 = "3d8866c029dd6b16e69e0d4a939c4dfcb98fac47" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.8" +weakdeps = ["Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsStatisticsExt = "Statistics" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.10.0" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[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.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.5" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "60b1194df0a3298f460063de985eae7b01bc011a" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.1+0" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.8" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.7+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.0.1+1" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.6.0+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.35.0+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.36.0+0" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.1" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] +git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.2.7" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.26" + + [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.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.0.0+0" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "2ee75365ca243c1a39d467e35ffd3d4d32eef11e" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.1.2+1" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.10" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "8eeb3c73bbc0ca203d0dc8dad4008350bbe5797b" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.3.1+1" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "a37c6610dd20425b131caf65d52abdf859da5ab1" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.20.4" + +[[deps.MakieCore]] +deps = ["Observables", "REPL"] +git-tree-sha1 = "ec5db7bb2dc9b85072658dcb2d3ad09569b09ac9" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.7.2" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] +git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.7" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] +git-tree-sha1 = "8be09d84a2d597c7c0c34d7d604c039c9763e48c" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.4.10" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "b01beb91d20b0d1312a9471a36017b5b339d26de" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+1" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "b76ea40b5c0f45790ae09492712dd326208c28b2" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.1.7" + +[[deps.Mods]] +git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "2.2.4" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "4704758e7dd9c843f0a99b18a26aa2d88dd8b8e6" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.0" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "XML2_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "10c612c81eaffdd6b7c28a45a554cdd9d2f40ff1" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "400.902.208+0" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.OffsetArrays]] +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+2" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+2" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "e25c1778a98e34219a00455d6e4384e017ea9762" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "4.1.6+0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.12+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.Optim]] +deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.7.8" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.31" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.3" + +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.20" + +[[deps.PikaParser]] +deps = ["DocStringExtensions"] +git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" +uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" +version = "0.6.1" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "862942baf5663da528f66d24996eb6da85218e76" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.0" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.6" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.0" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.1" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "1d05623b5952aed1307bf8b43bec8b8d1ef94b6e" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.5" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.9.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.4" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "db0219befe4507878b1a90e07820fed3e62c289d" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.4.0" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.6" + +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "e9330391d04241eafdc358713b48396619c83bcb" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.1" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.17" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableHashTraits]] +deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "008ca4718b5b55983dd0ffc63ce1f029c4a88f35" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.1.5" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "f68dd04d131d9a8a8eb836173ee8f105c360b0c5" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.1" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.2" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StructArrays]] +deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] +git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.16" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.0+1" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.8" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.2" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + +[[deps.TupleTools]] +git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.4.3" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.2+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.0+4" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "5.0.3+4" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.7.10+4" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] +git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.4+4" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.2+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.5+0" + +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eddd19a8dea6b139ea97bdc8a0e2667d4b661720" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.0.6+1" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "93284c28274d9e75218a416c65ec49d0e0fcdf3d" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.40+0" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" diff --git a/experiments/prototype_omip_simulation/CATKE_column_simulations/Project.toml b/experiments/prototype_omip_simulation/CATKE_column_simulations/Project.toml new file mode 100644 index 00000000..3ad59e5e --- /dev/null +++ b/experiments/prototype_omip_simulation/CATKE_column_simulations/Project.toml @@ -0,0 +1,3 @@ +[deps] +GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" diff --git a/experiments/prototype_omip_simulation/CATKE_column_simulations/take_a_look.jl b/experiments/prototype_omip_simulation/CATKE_column_simulations/take_a_look.jl new file mode 100644 index 00000000..d642f737 --- /dev/null +++ b/experiments/prototype_omip_simulation/CATKE_column_simulations/take_a_look.jl @@ -0,0 +1,14 @@ +using NCDatasets +using GLMakie + +filename = "single_column_omip_ocean_station_papa.nc" + +ds = Dataset(filename) +K = ds["κᶜ"][1, 1, :, :] +zf = ds["zF"][:] +t = ds["time"][:] + +# close(ds) + +heatmap(t, zf, K') + diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl new file mode 100644 index 00000000..9eaa038a --- /dev/null +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -0,0 +1,191 @@ +using Oceananigans +using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time + +using ClimaOcean +using ClimaOcean.OceanSeaIceModels: Radiation +using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +using GLMakie +using Printf +using Dates + +start_time = time_ns() + +include("omip_ocean_component.jl") + +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 1) +start_seconds = Second(date - epoch).value +# uᵢ = ecco2_field(:u_velocity, date) +# vᵢ = ecco2_field(:v_velocity, date) +Te = ecco2_field(:temperature, date) +Se = ecco2_field(:salinity, date) + +land = interior(Te) .< -10 +interior(Te)[land] .= NaN +interior(Se)[land] .= NaN + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +arch = CPU() + +latitude = (-60, -50) +longitude = (300, 360) + +i₁ = 4 * first(longitude) + 1 +i₂ = 1440 - 4 * (360 - last(longitude)) +Nx = i₂ - i₁ + 1 + +j₁ = 4 * (90 + first(latitude)) + 1 +j₂ = 720 - 4 * (90 - last(latitude)) +Ny = j₂ - j₁ + 1 + +zc = znodes(Te) +zf = znodes(Te.grid, Face()) +Δz = first(zspacings(Te.grid, Center())) + +Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) +Sᵢ = interior(Se, i₁:i₂, j₁:j₂, :) + +# Construct bottom_height depth by analyzing T +Nx, Ny, Nz = size(Tᵢ) +bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) + +for i = 1:Nx, j = 1:Ny + @inbounds for k = Nz:-1:1 + if isnan(Tᵢ[i, j, k]) + bottom_height[i, j] = zf[k+1] + break + end + end +end + +@show Nx Ny Nz zf + +grid = LatitudeLongitudeGrid(arch; latitude, longitude, + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = zf, + topology = (Periodic, Bounded, Bounded)) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + +elapsed = time_ns() - start_time +@info "Grid constructed. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +ocean = omip_ocean_component(grid) +elapsed = time_ns() - start_time +@info "Ocean component built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +Ndays = 365 +Nt = 8 * Ndays +atmosphere = jra55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) +elapsed = time_ns() - start_time +@info "Atmosphere built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +ocean.model.clock.time = start_seconds +ocean.model.clock.iteration = 0 +set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +times = ua.times + +sea_ice = nothing +radiation = Radiation() +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 60days) + +elapsed = time_ns() - start_time +@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +wall_clock = Ref(time_ns()) + +function progress(sim) + msg = string("(", location, ")") + msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + e = sim.model.ocean.model.tracers.e + + τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) + τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) + u★ = (τˣ^2 + τʸ^2)^(1/4) + Q = first(sim.model.fluxes.total.ocean.heat) + + Nz = size(T, 3) + msg *= @sprintf(", u★: %.2f m s⁻¹", u★) + msg *= @sprintf(", Q: %.2f W m⁻²", Q) + msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) + msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) + msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) + + @info msg +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) + +# Build flux outputs +Jᵘ = coupled_model.fluxes.total.ocean.momentum.u +Jᵛ = coupled_model.fluxes.total.ocean.momentum.v +Jᵀ = coupled_model.fluxes.total.ocean.tracers.T +F = coupled_model.fluxes.total.ocean.tracers.S +E = coupled_model.fluxes.turbulent.fields.evaporation +Qse = coupled_model.fluxes.turbulent.fields.sensible_heat_flux +Qla = coupled_model.fluxes.turbulent.fields.latent_heat_flux +ρₒ = coupled_model.fluxes.ocean_reference_density +cₚ = coupled_model.fluxes.ocean_heat_capacity + +Q = ρₒ * cₚ * Jᵀ +τˣ = ρₒ * Jᵘ +τʸ = ρₒ * Jᵛ +N² = buoyancy_frequency(ocean.model) +κᶜ = ocean.model.diffusivity_fields.κᶜ + +fluxes = (; τˣ, τʸ, E, F, Q, Qse, Qla) + +auxiliary_fields = (; N², κᶜ) +fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + +# Slice fields at the surface +outputs = merge(fields, fluxes) + +filename = "single_column_omip_$location" + +coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, + schedule = TimeInterval(3hours), + overwrite_existing = true) + +#= +coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, + schedule = AveragedTimeInterval(1days), + overwrite_existing = true) +=# + +# run!(coupled_simulation) + diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 1dba6ed3..94746a9e 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -214,6 +214,18 @@ for location in keys(locations) # Slice fields at the surface outputs = merge(fields, fluxes) + output_attributes = Dict( + "κᶜ" => Dict("long_name" => "Tracer diffusivity", "units" => "m^2 / s"), + "Q" => Dict("long_name" => "Net heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Qla" => Dict("long_name" => "Latent heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Qse" => Dict("long_name" => "Sensible heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "F" => Dict("long_name" => "Salt flux", "units" => "g kg⁻¹ m s⁻¹", "convention" => "positive upwards"), + "E" => Dict("long_name" => "Freshwater evaporation flux", "units" => "m s⁻¹", "convention" => "positive upwards"), + "e" => Dict("long_name" => "Turbulent kinetic energy", "units" => "m^2 / s^2"), + "τˣ" => Dict("long_name" => "Zonal momentum flux", "units" => "m^2 / s^2"), + "τʸ" => Dict("long_name" => "Meridional momentum flux", "units" => "m^2 / s^2"), + ) + filename = "single_column_omip_$location" coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, @@ -221,11 +233,14 @@ for location in keys(locations) overwrite_existing = true) coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, - schedule = AveragedTimeInterval(1day), + schedule = AveragedTimeInterval(1days), + output_attributes, overwrite_existing = true) run!(coupled_simulation) + filename *= ".jld2" + ut = FieldTimeSeries(filename, "u") vt = FieldTimeSeries(filename, "v") Tt = FieldTimeSeries(filename, "T") diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 1fb454d7..e8932cd5 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -169,12 +169,17 @@ function jra55_field_time_series(variable_name, grid=nothing; throw(ArgumentError(msg)) end - isnothing(url) && (url = urls[variable_name]) - isnothing(filename) && (filename = filenames[variable_name]) isnothing(shortname) && (shortname = shortnames[variable_name]) - isfile(filename) || download(url, filename) + !isnothing(filename) && !isfile(filename) && isnothing(url) && + throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ + If intended, please provide both the filename and url that should be used \n \ + to download the new file.")) + isnothing(filename) && (filename = filenames[variable_name]) + isnothing(url) && (url = urls[variable_name]) + isfile(filename) || download(url, filename) + # Get location if isnothing(location) LX = LY = Center @@ -192,10 +197,6 @@ function jra55_field_time_series(variable_name, grid=nothing; # ds["lat_bnds"]: bounding latitudes between which variables are averaged # ds[shortname]: the variable data - if variable_name == :rain_freshwater_flux - @show ds - end - # Nodes at the variable location λc = ds["lon"][:] φc = ds["lat"][:] From 05e791846c2a9d15c6cccf8b8fa90a8c3c7cebcb Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 22 Jan 2024 08:39:01 -0700 Subject: [PATCH 056/182] Update regional setup --- .../prototype_omip_simulation/regional_omip_simulation.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index 9eaa038a..2638cee3 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -118,8 +118,7 @@ start_time = time_ns() wall_clock = Ref(time_ns()) function progress(sim) - msg = string("(", location, ")") - msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) + msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) elapsed = 1e-9 * (time_ns() - wall_clock[]) msg *= string(", wall time: ", prettytime(elapsed)) @@ -175,7 +174,7 @@ fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) # Slice fields at the surface outputs = merge(fields, fluxes) -filename = "single_column_omip_$location" +filename = "regional_omip_simulation" coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, schedule = TimeInterval(3hours), From e5590cc81376e38fd06164b0f801d397d6e2cada Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 23 Jan 2024 07:05:55 -0700 Subject: [PATCH 057/182] Negative evaporation = deposition? --- .../surface_fluxes.jl | 171 ++++++++++++++++++ .../ocean_sea_ice_surface_fluxes.jl | 19 +- .../similarity_theory_turbulent_fluxes.jl | 15 +- 3 files changed, 196 insertions(+), 9 deletions(-) create mode 100644 experiments/prototype_omip_simulation/surface_fluxes.jl diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl new file mode 100644 index 00000000..190f7954 --- /dev/null +++ b/experiments/prototype_omip_simulation/surface_fluxes.jl @@ -0,0 +1,171 @@ +using Oceananigans +using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time + +using ClimaOcean +using ClimaOcean.OceanSeaIceModels: Radiation +using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +using GLMakie +using Printf +using Dates + +start_time = time_ns() + +include("omip_ocean_component.jl") + +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 1) +start_seconds = Second(date - epoch).value +ue = ecco2_field(:u_velocity, date) +ve = ecco2_field(:v_velocity, date) +Te = ecco2_field(:temperature, date) +Se = ecco2_field(:salinity, date) + +land = interior(Te) .< -10 +interior(Te)[land] .= NaN +interior(Se)[land] .= NaN + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +arch = CPU() + +latitude = (-70, -30) +longitude = (0, 360) + +i₁ = 4 * first(longitude) + 1 +i₂ = 1440 - 4 * (360 - last(longitude)) +Nx = i₂ - i₁ + 1 + +j₁ = 4 * (90 + first(latitude)) + 1 +j₂ = 720 - 4 * (90 - last(latitude)) +Ny = j₂ - j₁ + 1 + +Nz = size(Te, 3) + +Tᵢ = Te[i₁:i₂, j₁:j₂, Nz:Nz] +Sᵢ = Se[i₁:i₂, j₁:j₂, Nz:Nz] +uᵢ = ue[i₁:i₂, j₁:j₂, Nz:Nz] +vᵢ = ve[i₁:i₂, j₁:j₂+1, Nz:Nz] + +# Construct bottom_height depth by analyzing T +Nx, Ny, Nz = size(Tᵢ) +bottom_height = zeros(Nx, Ny) + +for i = 1:Nx, j = 1:Ny + @inbounds bottom_height[i, j] = ifelse(isnan(Tᵢ[i, j, 1]), Inf, -Inf) +end + +grid = LatitudeLongitudeGrid(arch; latitude, longitude, + size = (Nx, Ny, 1), + halo = (7, 7, 7), + z = (-10, 0), + topology = (Periodic, Bounded, Bounded)) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + +elapsed = time_ns() - start_time +@info "Grid constructed. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +ocean = omip_ocean_component(grid) +elapsed = time_ns() - start_time +@info "Ocean component built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +atmosphere = jra55_prescribed_atmosphere(grid, 1:1) +elapsed = time_ns() - start_time +@info "Atmosphere built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +ocean.model.clock.time = start_seconds +ocean.model.clock.iteration = 0 +set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +times = ua.times + +sea_ice = nothing +radiation = Radiation() +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +elapsed = time_ns() - start_time +@info "Coupled model built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +# Build flux outputs +Jᵘ = coupled_model.fluxes.total.ocean.momentum.u +Jᵛ = coupled_model.fluxes.total.ocean.momentum.v +Jᵀ = coupled_model.fluxes.total.ocean.tracers.T +Jˢ = coupled_model.fluxes.total.ocean.tracers.S + +E = coupled_model.fluxes.turbulent.fields.evaporation +Fʳ = atmosphere.freshwater_flux.rain +Fˢ = atmosphere.freshwater_flux.snow + +Qᶜ = coupled_model.fluxes.turbulent.fields.sensible_heat_flux +Qᵉ = coupled_model.fluxes.turbulent.fields.latent_heat_flux +Qˡ = atmosphere.downwelling_radiation.longwave +Qˢ = atmosphere.downwelling_radiation.shortwave + +ρₒ = coupled_model.fluxes.ocean_reference_density +cₚ = coupled_model.fluxes.ocean_heat_capacity + +P = Field(Fʳ[1] + Fˢ[1]) +ΣQ = Field(ρₒ * cₚ * Jᵀ) +u★ = Field(sqrt(sqrt(Jᵘ^2 + Jᵛ^2))) + +N² = buoyancy_frequency(ocean.model) +κᶜ = ocean.model.diffusivity_fields.κᶜ +To = ocean.model.tracers.T +qa = atmosphere.tracers.q + +compute!(ΣQ) +compute!(P) +compute!(u★) + +fig = Figure(resolution=(1200, 1800)) + +axτ = Axis(fig[1, 1], title="u★") +axT = Axis(fig[2, 1], title="T") +axq = Axis(fig[3, 1], title="q") +axE = Axis(fig[4, 1], title="E") +axP = Axis(fig[5, 1], title="P") + +axQt = Axis(fig[1, 2], title="Net heat flux") +axQl = Axis(fig[2, 2], title="Incoming longwave heat flux") +axQs = Axis(fig[3, 2], title="Shortwave / solar heat flux") +axQe = Axis(fig[4, 2], title="Evaporative heat flux") +axQc = Axis(fig[5, 2], title="Conductive / sensible heat flux") + +heatmap!(axτ, interior(u★, :, :, 1), colorrange=(0, 1e-1)) +heatmap!(axT, interior(To, :, :, 1), colorrange=(0, 10)) +heatmap!(axq, interior(qa, :, :, 1, 1)) +heatmap!(axE, interior(E, :, :, 1)) +heatmap!(axP, interior(P, :, :, 1)) + +ΣQi = interior(ΣQ, :, :, 1) +Qˢi = - interior(Qˢ, :, :, 1, 1) +Qˡi = - interior(Qˡ, :, :, 1, 1) +Qᵉi = interior(Qᵉ, :, :, 1) +Qᶜi = interior(Qᶜ, :, :, 1) + +Qlim = 600 +heatmap!(axQt, ΣQi, colormap=:balance, colorrange=(-Qlim, Qlim)) +heatmap!(axQs, Qˢi, colormap=:balance, colorrange=(-Qlim, Qlim)) +heatmap!(axQl, Qˡi, colormap=:balance, colorrange=(-Qlim, Qlim)) +heatmap!(axQe, Qᵉi, colormap=:balance, colorrange=(-Qlim, Qlim)) +heatmap!(axQc, Qᶜi, colormap=:balance, colorrange=(-Qlim, Qlim)) + +display(fig) + diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 7b831e3b..8cebcacd 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -243,21 +243,30 @@ end Ψₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(h, Uₐ, ψₐ) # Roughness lengths... - zᵐ = convert(eltype(grid), 1e-2) - zʰ = convert(eltype(grid), 1e-2) + FT = eltype(grid) + zᵐ = zʰ = convert(FT, 1e-2) Uᵍ = zero(grid) # gustiness β = one(grid) # surface "resistance" values = SurfaceFluxes.ValuesOnly(Ψₐ, Ψ₀, zᵐ, zʰ, Uᵍ, β) conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + + # It's like a fixed point iteration + g = turbulent_fluxes.gravitational_acceleration + α = convert(FT, 0.011) # Charnock parameter + u★ = conditions.ustar + zᵐ = zʰ = α * u★^2 / g + values = SurfaceFluxes.ValuesOnly(Ψₐ, Ψ₀, zᵐ, zʰ, Uᵍ, β) + conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + update_turbulent_flux_fields!(turbulent_fluxes.fields, i, j, grid, conditions) # Compute heat fluxes, bulk flux first Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation_properties) Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state) - Qs = conditions.shf # sensible heat flux - Qℓ = conditions.lhf # latent heat flux - ΣQ = Qd + Qu + Qs + Qℓ + Qc = conditions.shf # sensible or "conductive" heat flux + Qe = max(zero(grid), conditions.lhf) # latent or "evaporative" heat flux + ΣQ = Qd + Qu + Qc + Qe # Accumulate freshwater fluxes. Rain, snow, runoff -- all freshwater. M = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) # mass fluxes apparently? diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 84977970..1d1bd5dd 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -103,11 +103,17 @@ end @inline function update_turbulent_flux_fields!(fields, i, j, grid, conditions) ρᶠ = 1000 # density of freshwater? + Qᵉ = fields.latent_heat_flux + Qᶜ = fields.sensible_heat_flux + E = fields.evaporation @inbounds begin - fields.latent_heat_flux[i, j, 1] = conditions.lhf - fields.sensible_heat_flux[i, j, 1] = conditions.shf + # +0: cooling, -0: heating + Qᵉ[i, j, 1] = max(zero(grid), conditions.lhf) + Qᶜ[i, j, 1] = conditions.shf + # "Salt flux" has the opposite sign of "freshwater flux" - fields.evaporation[i, j, 1] = - conditions.evaporation / ρᶠ + Eᵢ = - conditions.evaporation / ρᶠ # convert to volume flux + E[i, j, 1] = max(zero(grid), Eᵢ) end return nothing end @@ -136,7 +142,8 @@ function seawater_saturation_specific_humidity(atmosphere_thermodynamics_paramet x_H₂O = compute_water_mole_fraction(water_mole_fraction, Sₛ) # Return saturation specific humidity for salty seawater - return q★_H₂O * x_H₂O + #return q★_H₂O * x_H₂O + return 0.98 * q★_H₂O end struct SalinityConstituent{FT} From d5f4ce8e36311c20a114cc103dc9d4a532c8425c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 23 Jan 2024 08:07:13 -0700 Subject: [PATCH 058/182] Freshwater density parameter and some cleanup --- .../ocean_sea_ice_surface_fluxes.jl | 98 +++++++++++-------- .../CrossRealmFluxes/radiation.jl | 5 +- .../similarity_theory_turbulent_fluxes.jl | 27 ++--- 3 files changed, 70 insertions(+), 60 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 8cebcacd..13411a21 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -24,7 +24,7 @@ using KernelAbstractions: @kernel, @index ##### Container for organizing information related to fluxes ##### -struct OceanSeaIceSurfaceFluxes{T, P, C, R, PI, PC, FT} +struct OceanSeaIceSurfaceFluxes{T, P, C, R, PI, PC, FT, UN} turbulent :: T prescribed :: P total :: C @@ -34,8 +34,8 @@ struct OceanSeaIceSurfaceFluxes{T, P, C, R, PI, PC, FT} # The ocean is Boussinesq, so these are _only_ coupled properties: ocean_reference_density :: FT ocean_heat_capacity :: FT - # ocean_temperature_units - # freshwater_density ? + freshwater_density :: FT + ocean_temperature_units :: UN end # Possible units for temperature and salinity @@ -52,6 +52,8 @@ Base.show(io::IO, crf::OceanSeaIceSurfaceFluxes) = print(io, summary(crf)) function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; atmosphere = nothing, radiation = nothing, + freshwater_density = 1000, + ocean_temperature_units = DegreesCelsius(), ocean_reference_density = reference_density(ocean), ocean_heat_capacity = heat_capacity(ocean)) @@ -109,7 +111,9 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; previous_ice_thickness, previous_ice_concentration, ocean_reference_density, - ocean_heat_capacity) + ocean_heat_capacity, + freshwater_density, + ocean_temperature_units) end ##### @@ -170,6 +174,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere.thermodynamics_parameters, coupled_model.fluxes.ocean_reference_density, coupled_model.fluxes.ocean_heat_capacity, + coupled_model.fluxes.freshwater_density, + coupled_model.fluxes.ocean_temperature_units, ice_thickness) # Note: I think this can be avoided if we modify the preceding kernel @@ -196,6 +202,8 @@ end atmosphere_thermodynamics_parameters, ocean_reference_density, ocean_heat_capacity, + freshwater_density, + ocean_temperature_units, ice_thickness) i, j = @index(Global, NTuple) @@ -208,7 +216,8 @@ end uₒ = ℑxᶜᵃᵃ(i, j, 1, grid, ocean_state.u) vₒ = ℑyᵃᶜᵃ(i, j, 1, grid, ocean_state.v) Uₒ = SVector(uₒ, vₒ) - Tₒ = ocean_state.T[i, j, 1] + 273.15 # K + Tₒ = ocean_state.T[i, j, 1] + Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) Sₒ = ocean_state.S[i, j, 1] # Atmos state @@ -221,34 +230,35 @@ end qᵗₐ = atmos_state.q[i, j, 1] # total specific humidity end - # Build atmospheric state + # Build thermodynamic and dynamic states in the atmosphere and surface. + # Notation: + # ⋅ ϕ ≡ thermodynamic state vector + # ⋅ Φ ≡ "dynamic" state vector (thermodynamics + reference height + velocity) ℂ = atmosphere_thermodynamics_parameters - ψₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₐ, qᵗₐ) + hₐ = atmosphere_reference_height # elevation of atmos variables relative to surface + ϕₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₐ, qᵗₐ) + Φₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, ϕₐ) # Build surface state with saturated specific humidity surface_type = AtmosphericThermodynamics.Liquid() - water_mole_fraction = turbulent_fluxes.water_mole_fraction - water_vapor_saturation = turbulent_fluxes.water_vapor_saturation - q★ = seawater_saturation_specific_humidity(ℂ, Tₒ, Sₒ, ψₐ, - water_mole_fraction, - water_vapor_saturation, + q★ = seawater_saturation_specific_humidity(ℂ, Tₒ, Sₒ, ϕₐ, + turbulent_fluxes.water_mole_fraction, + turbulent_fluxes.water_vapor_saturation surface_type) - # Thermodynamic and dynamic state at the surface - ψ₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₒ, q★) - Ψ₀ = dynamic_surface_state = SurfaceFluxes.StateValues(zero(grid), Uₒ, ψ₀) + # Thermodynamic and dynamic surface state + h₀ = zero(grid) # surface height + ϕ₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₒ, q★) + Φ₀ = dynamic_surface_state = SurfaceFluxes.StateValues(h₀, Uₒ, ϕ₀) - # Thermodynamic and dynamic state at reference level h above the surface - h = atmosphere_reference_height # elevation of atmos variables relative to surface - Ψₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(h, Uₐ, ψₐ) - - # Roughness lengths... + # Initial guess for the roughness length. FT = eltype(grid) - zᵐ = zʰ = convert(FT, 1e-2) + zᵐ = zʰ = convert(FT, 5e-4) # τ = 0.3 => u★ = sqrt(τ / ρₐ) ~ z₀ ~ 5e-4 + # Solve for the surface fluxes with initial roughness length guess Uᵍ = zero(grid) # gustiness β = one(grid) # surface "resistance" - values = SurfaceFluxes.ValuesOnly(Ψₐ, Ψ₀, zᵐ, zʰ, Uᵍ, β) + values = SurfaceFluxes.ValuesOnly(Φₐ, Φ₀, zᵐ, zʰ, Uᵍ, β) conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) # It's like a fixed point iteration @@ -256,31 +266,32 @@ end α = convert(FT, 0.011) # Charnock parameter u★ = conditions.ustar zᵐ = zʰ = α * u★^2 / g - values = SurfaceFluxes.ValuesOnly(Ψₐ, Ψ₀, zᵐ, zʰ, Uᵍ, β) + values = SurfaceFluxes.ValuesOnly(Φₐ, Φ₀, zᵐ, zʰ, Uᵍ, β) conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) - - update_turbulent_flux_fields!(turbulent_fluxes.fields, i, j, grid, conditions) # Compute heat fluxes, bulk flux first Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation_properties) - Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state) - Qc = conditions.shf # sensible or "conductive" heat flux - Qe = max(zero(grid), conditions.lhf) # latent or "evaporative" heat flux + Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state, ocean_temperature_units) + Qc = conditions.shf # sensible or "conductive" heat flux + Qe = clip(conditions.lhf) # latent or "evaporative" heat flux ΣQ = Qd + Qu + Qc + Qe # Accumulate freshwater fluxes. Rain, snow, runoff -- all freshwater. - M = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) # mass fluxes apparently? - ρᶠ = 1000 # density of freshwater? - ΣF = M / ρᶠ # convert from a mass flux to a volume flux / velocity + # Note these are mass fluxes, hence the "M". + M = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) + + # Convert from a mass flux to a volume flux / velocity? + ρᶠ = freshwater_density + ΣF = M / ρᶠ # Apparently, conditions.evaporation is a mass flux of water. # So, we divide by the density of freshwater. - E = - conditions.evaporation / ρᶠ # ? - - # Clip evaporation. TODO: figure out why this is needed. - E = min(zero(E), E) # why does this happen? + # But why do we need to clip evaporation rate? + E = - clip(conditions.evaporation) / ρᶠ ΣF += E + update_turbulent_flux_fields!(turbulent_fluxes.fields, i, j, grid, conditions, ρᶠ) + # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes Jᵘ = centered_velocity_fluxes.u Jᵛ = centered_velocity_fluxes.v @@ -300,10 +311,11 @@ end inactive = inactive_node(i, j, kᴺ, grid, c, c, c) @inbounds begin - Jᵘ[i, j, 1] = ifelse(inactive, zero(grid), atmos_ocean_Jᵘ) - Jᵛ[i, j, 1] = ifelse(inactive, zero(grid), atmos_ocean_Jᵛ) - Jᵀ[i, j, 1] = ifelse(inactive, zero(grid), atmos_ocean_Jᵀ) - Jˢ[i, j, 1] = ifelse(inactive, zero(grid), atmos_ocean_Jˢ) + nan = convert(FT, NaN) + Jᵘ[i, j, 1] = ifelse(inactive, nan, atmos_ocean_Jᵘ) + Jᵛ[i, j, 1] = ifelse(inactive, nan, atmos_ocean_Jᵛ) + Jᵀ[i, j, 1] = ifelse(inactive, nan, atmos_ocean_Jᵀ) + Jˢ[i, j, 1] = ifelse(inactive, nan, atmos_ocean_Jˢ) end end @@ -324,16 +336,16 @@ end return @inbounds - (1 - α) * Qˢʷ[i, j, 1, time] - Qˡʷ[i, j, 1, time] end -@inline function net_upwelling_radiation(i, j, grid, time, radiation, ocean_state) +@inline function net_upwelling_radiation(i, j, grid, time, radiation, surface_temperature) σ = radiation.stefan_boltzmann_constant - Tᵣ = radiation.reference_temperature ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) # Ocean surface temperature (departure from reference, typically in ᵒC) - Tₒ = @inbounds ocean_state.T[i, j, 1] + 273.15 # K + Tₒ = @inbounds ocean_state.T[i, j, 1] + Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) # Note: positive implies _upward_ heat flux, and therefore cooling. - return σ * ϵ * Tₒ^4 + return ϵ * σ * Tₒ^4 end @inline cross_realm_flux(i, j, grid, time, ::Nothing, args...) = zero(grid) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index b7b54e0d..f9ca57be 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -2,7 +2,6 @@ struct Radiation{FT, E, R} emission :: E reflection :: R stefan_boltzmann_constant :: FT - reference_temperature :: FT end function Radiation(FT=Float64; @@ -10,7 +9,6 @@ function Radiation(FT=Float64; sea_ice_emissivity = 1.0, ocean_albedo = 0.3, sea_ice_albedo = 0.7, - reference_temperature = 273.15, stefan_boltzmann_constant = 5.67e-8) ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) @@ -23,8 +21,7 @@ function Radiation(FT=Float64; return Radiation(emission, reflection, - convert(FT, stefan_boltzmann_constant), - convert(FT, reference_temperature)) + convert(FT, stefan_boltzmann_constant)) end Base.summary(r::Radiation) = "Radiation" diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 1d1bd5dd..c46544b0 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -101,19 +101,20 @@ end @inline update_turbulent_flux_fields!(::Nothing, args...) = nothing -@inline function update_turbulent_flux_fields!(fields, i, j, grid, conditions) - ρᶠ = 1000 # density of freshwater? +@inline clip(x::FT) = max(zero(FT), x) + +@inline function update_turbulent_flux_fields!(fields, i, j, grid, conditions, ρᶠ) Qᵉ = fields.latent_heat_flux Qᶜ = fields.sensible_heat_flux E = fields.evaporation @inbounds begin # +0: cooling, -0: heating - Qᵉ[i, j, 1] = max(zero(grid), conditions.lhf) + Qᵉ[i, j, 1] = clip(conditions.lhf) Qᶜ[i, j, 1] = conditions.shf # "Salt flux" has the opposite sign of "freshwater flux" Eᵢ = - conditions.evaporation / ρᶠ # convert to volume flux - E[i, j, 1] = max(zero(grid), Eᵢ) + E[i, j, 1] = clip(Eᵢ) end return nothing end @@ -126,12 +127,12 @@ default_universal_function_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = co γ = convert(FT, 4.42)) function seawater_saturation_specific_humidity(atmosphere_thermodynamics_parameters, - surface_temperature, - surface_salinity, - atmos_state, - water_mole_fraction, - water_vapor_saturation, - ::Liquid) + surface_temperature, + surface_salinity, + atmos_state, + water_mole_fraction, + water_vapor_saturation, + ::Liquid) ℂₐ = atmosphere_thermodynamics_parameters Tₛ = surface_temperature @@ -142,8 +143,7 @@ function seawater_saturation_specific_humidity(atmosphere_thermodynamics_paramet x_H₂O = compute_water_mole_fraction(water_mole_fraction, Sₛ) # Return saturation specific humidity for salty seawater - #return q★_H₂O * x_H₂O - return 0.98 * q★_H₂O + return q★_H₂O * x_H₂O end struct SalinityConstituent{FT} @@ -173,7 +173,8 @@ end @inline compute_water_mole_fraction(x_H₂O::Number, S) = x_H₂O @inline function compute_water_mole_fraction(wmf::WaterMoleFraction, S) - s = S / 1000 # concentration + # TODO: express the concept of "ocean_salinity_units"? + s = S / 1000 # convert g/kg to concentration # Molecular weights μ_H₂O = wmf.water_molar_mass From c03487ef5fad1c39184ee31de90457b703165c31 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 23 Jan 2024 13:11:12 -0700 Subject: [PATCH 059/182] Fiddle with flux convention --- .../surface_fluxes.jl | 45 ++++++++++----- .../CrossRealmFluxes/CrossRealmFluxes.jl | 4 -- .../ocean_sea_ice_surface_fluxes.jl | 12 ++-- .../ocean_sea_ice_surfaces.jl | 55 ------------------- .../similarity_theory_turbulent_fluxes.jl | 15 +++-- 5 files changed, 48 insertions(+), 83 deletions(-) delete mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surfaces.jl diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl index 190f7954..dce8678f 100644 --- a/experiments/prototype_omip_simulation/surface_fluxes.jl +++ b/experiments/prototype_omip_simulation/surface_fluxes.jl @@ -38,7 +38,7 @@ start_time = time_ns() arch = CPU() -latitude = (-70, -30) +latitude = (-75, +65) longitude = (0, 360) i₁ = 4 * first(longitude) + 1 @@ -121,7 +121,7 @@ Qˢ = atmosphere.downwelling_radiation.shortwave ρₒ = coupled_model.fluxes.ocean_reference_density cₚ = coupled_model.fluxes.ocean_heat_capacity -P = Field(Fʳ[1] + Fˢ[1]) +P = Field(- Fʳ[1] - Fˢ[1]) ΣQ = Field(ρₒ * cₚ * Jᵀ) u★ = Field(sqrt(sqrt(Jᵘ^2 + Jᵛ^2))) @@ -148,11 +148,24 @@ axQs = Axis(fig[3, 2], title="Shortwave / solar heat flux") axQe = Axis(fig[4, 2], title="Evaporative heat flux") axQc = Axis(fig[5, 2], title="Conductive / sensible heat flux") -heatmap!(axτ, interior(u★, :, :, 1), colorrange=(0, 1e-1)) -heatmap!(axT, interior(To, :, :, 1), colorrange=(0, 10)) -heatmap!(axq, interior(qa, :, :, 1, 1)) -heatmap!(axE, interior(E, :, :, 1)) -heatmap!(axP, interior(P, :, :, 1)) +u★i = interior(u★, :, :, 1) +Toi = interior(To, :, :, 1) +qai = interior(qa, :, :, 1, 1) +Ei = interior(E, :, :, 1) +Pi = interior(P, :, :, 1) + +Flim = 1e-6 +hmτ = heatmap!(axτ, u★i, colormap=:solar, colorrange=(0, 1e-1)) +hmT = heatmap!(axT, Toi, colormap=:thermal, colorrange=(0, 10)) +hmq = heatmap!(axq, qai, colormap=:grays) +hmE = heatmap!(axE, Ei, colormap=:balance, colorrange=(-Flim, Flim)) +hmP = heatmap!(axP, Pi, colormap=:balance, colorrange=(-Flim, Flim)) + +Colorbar(fig[1, 0], hmτ, label="Friction velocity (m s⁻¹)") +Colorbar(fig[2, 0], hmT, label="Ocean surface temperature (ᵒC)") +Colorbar(fig[3, 0], hmq, label="Atmosphere specific humidity") +Colorbar(fig[4, 0], hmE, label="Evaporation freshwater flux (m s⁻¹)") +Colorbar(fig[5, 0], hmP, label="Precipitation freshwater flux (m s⁻¹)") ΣQi = interior(ΣQ, :, :, 1) Qˢi = - interior(Qˢ, :, :, 1, 1) @@ -160,12 +173,18 @@ Qˡi = - interior(Qˡ, :, :, 1, 1) Qᵉi = interior(Qᵉ, :, :, 1) Qᶜi = interior(Qᶜ, :, :, 1) -Qlim = 600 -heatmap!(axQt, ΣQi, colormap=:balance, colorrange=(-Qlim, Qlim)) -heatmap!(axQs, Qˢi, colormap=:balance, colorrange=(-Qlim, Qlim)) -heatmap!(axQl, Qˡi, colormap=:balance, colorrange=(-Qlim, Qlim)) -heatmap!(axQe, Qᵉi, colormap=:balance, colorrange=(-Qlim, Qlim)) -heatmap!(axQc, Qᶜi, colormap=:balance, colorrange=(-Qlim, Qlim)) +Qlim = 1000 +hmt = heatmap!(axQt, ΣQi, colormap=:balance, colorrange=(-Qlim, Qlim)) +hms = heatmap!(axQs, Qˢi, colormap=:balance, colorrange=(-Qlim, Qlim)) +hml = heatmap!(axQl, Qˡi, colormap=:balance, colorrange=(-Qlim, Qlim)) +hme = heatmap!(axQe, Qᵉi, colormap=:balance, colorrange=(-Qlim, Qlim)) +hmc = heatmap!(axQc, Qᶜi, colormap=:balance, colorrange=(-Qlim, Qlim)) + +Colorbar(fig[1, 3], hmt, label="Net heat flux") +Colorbar(fig[2, 3], hml, label="Incoming longwave heat flux") +Colorbar(fig[3, 3], hms, label="Shortwave / solar heat flux") +Colorbar(fig[4, 3], hme, label="Evaporative heat flux") +Colorbar(fig[5, 3], hmc, label="Conductive / sensible heat flux") display(fig) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index c41aec12..f14c8b56 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -62,11 +62,7 @@ end include("radiation.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") - -# include("ocean_sea_ice_model_fluxes.jl") -# include("ocean_sea_ice_surfaces.jl") # include("atmosphere_sea_ice_fluxes.jl") -# include("atmosphere_ocean_momentum_flux.jl") # include("sea_ice_ocean_fluxes.jl") end # module diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 13411a21..4d658d6d 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -62,6 +62,7 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; ocean_reference_density = convert(FT, ocean_reference_density) ocean_heat_capacity = convert(FT, ocean_heat_capacity) + freshwater_density = convert(FT, freshwater_density) # It's the "thermodynamics gravitational acceleration" # (as opposed to the one used for the free surface) @@ -243,7 +244,7 @@ end surface_type = AtmosphericThermodynamics.Liquid() q★ = seawater_saturation_specific_humidity(ℂ, Tₒ, Sₒ, ϕₐ, turbulent_fluxes.water_mole_fraction, - turbulent_fluxes.water_vapor_saturation + turbulent_fluxes.water_vapor_saturation, surface_type) # Thermodynamic and dynamic surface state @@ -281,13 +282,14 @@ end M = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) # Convert from a mass flux to a volume flux / velocity? + # Also switch the sign, for some reason we are given freshwater as positive down. ρᶠ = freshwater_density - ΣF = M / ρᶠ + ΣF = - M / ρᶠ # Apparently, conditions.evaporation is a mass flux of water. # So, we divide by the density of freshwater. # But why do we need to clip evaporation rate? - E = - clip(conditions.evaporation) / ρᶠ + E = clip(conditions.evaporation) / ρᶠ ΣF += E update_turbulent_flux_fields!(turbulent_fluxes.fields, i, j, grid, conditions, ρᶠ) @@ -304,7 +306,7 @@ end atmos_ocean_Jᵘ = conditions.ρτxz / ρₒ atmos_ocean_Jᵛ = conditions.ρτyz / ρₒ atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) - atmos_ocean_Jˢ = Sₒ * ΣF + atmos_ocean_Jˢ = - Sₒ * ΣF # Mask fluxes over land for convenience kᴺ = size(grid, 3) # index of the top ocean cell @@ -336,7 +338,7 @@ end return @inbounds - (1 - α) * Qˢʷ[i, j, 1, time] - Qˡʷ[i, j, 1, time] end -@inline function net_upwelling_radiation(i, j, grid, time, radiation, surface_temperature) +@inline function net_upwelling_radiation(i, j, grid, time, radiation, ocean_state, ocean_temperature_units) σ = radiation.stefan_boltzmann_constant ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surfaces.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surfaces.jl deleted file mode 100644 index 745614ea..00000000 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surfaces.jl +++ /dev/null @@ -1,55 +0,0 @@ -##### -##### Extractors for differnet models (maybe this belongs in the model repo's) -##### - -function extract_top_surface_fluxes(model::HydrostaticFreeSurfaceModel) - u_flux = surface_flux(model.velocities.u) - v_flux = surface_flux(model.velocities.v) - - ocean_momentum_fluxes = (u = u_flux, v = v_flux) - - ocean_tracers = model.tracers - - ocean_tracer_fluxes = NamedTuple(name => surface_flux(ocean_tracers[name]) - for name in keys(ocean_tracers) - if surface_flux(ocean_tracers[name]) isa AbstractArray) - - ocean_fluxes = CrossRealmFluxes(momentum = ocean_momentum_fluxes, - tracers = ocean_tracer_fluxes) - - return ocean_fluxes -end - -extract_top_surface_fluxes(model::SlabSeaIceModel) = nothing -extract_bottom_surface_fluxes(model::SlabSeaIceModel) = nothing - -##### -##### Total flux across each surface -##### - -struct OceanSeaIceSurfaces{O, IT, IB} - ocean :: O - sea_ice_top :: IT - sea_ice_bottom :: IB -end - -Base.summary(osis::OceanSeaIceSurfaces) = "OceanSeaIceSurfaces" -Base.show(io::IO, osis::OceanSeaIceSurfaces) = print(io, summary(osis)) - -function OceanSeaIceSurfaces(ocean, sea_ice=nothing) - ocean_fluxes = extract_top_surface_fluxes(ocean.model) - - if isnothing(sea_ice) - sea_ice_top_fluxes = nothing - sea_ice_bottom_fluxes = nothing - else - sea_ice_top_fluxes = extract_top_surface_fluxes(sea_ice.model) - sea_ice_bottom_fluxes = extract_bottom_surface_fluxes(sea_ice.model) - end - - return OceanSeaIceSurfaces(ocean_fluxes, - sea_ice_top_fluxes, - sea_ice_bottom_fluxes) -end - - diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index c46544b0..adc4dd9b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -101,20 +101,23 @@ end @inline update_turbulent_flux_fields!(::Nothing, args...) = nothing -@inline clip(x::FT) = max(zero(FT), x) +@inline clip(x::FT) where FT = max(zero(FT), x) @inline function update_turbulent_flux_fields!(fields, i, j, grid, conditions, ρᶠ) Qᵉ = fields.latent_heat_flux Qᶜ = fields.sensible_heat_flux E = fields.evaporation + kᴺ = size(grid, 3) # index of the top ocean cell + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) @inbounds begin # +0: cooling, -0: heating - Qᵉ[i, j, 1] = clip(conditions.lhf) - Qᶜ[i, j, 1] = conditions.shf + Qᵉ[i, j, 1] = ifelse(inactive, 0, clip(conditions.lhf)) + Qᶜ[i, j, 1] = ifelse(inactive, 0, conditions.shf) - # "Salt flux" has the opposite sign of "freshwater flux" - Eᵢ = - conditions.evaporation / ρᶠ # convert to volume flux - E[i, j, 1] = clip(Eᵢ) + # "Salt flux" has the opposite sign of "freshwater flux". + # E > 0 implies that freshwater is fluxing upwards. + Eᵢ = clip(conditions.evaporation) / ρᶠ # convert to volume flux + E[i, j, 1] = ifelse(inactive, Eᵢ, 0) end return nothing end From 3b709058c87851ada9eb2ba7138af74962b00393 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 23 Jan 2024 13:26:23 -0700 Subject: [PATCH 060/182] Delete OMIP atmosphere --- .../omip_atmosphere.jl | 49 ------------------- .../ocean_sea_ice_surface_fluxes.jl | 16 +++--- 2 files changed, 10 insertions(+), 55 deletions(-) delete mode 100644 experiments/prototype_omip_simulation/omip_atmosphere.jl diff --git a/experiments/prototype_omip_simulation/omip_atmosphere.jl b/experiments/prototype_omip_simulation/omip_atmosphere.jl deleted file mode 100644 index 83ed8749..00000000 --- a/experiments/prototype_omip_simulation/omip_atmosphere.jl +++ /dev/null @@ -1,49 +0,0 @@ -using Oceananigans.Fields: interpolate! - -using ClimaOcean.JRA55: jra55_field_time_series - -using ClimaOcean.OceanSeaIceModels: - PrescribedAtmosphere, - TwoStreamDownwellingRadiation - -function prescribed_jra55_atmosphere(grid, time_indices=:; - reference_height = 2) # meters - - architecture = Oceananigans.architecture(grid) - - u_jra55 = jra55_field_time_series(:eastward_velocity, grid; time_indices, architecture) - v_jra55 = jra55_field_time_series(:northward_velocity, grid; time_indices, architecture) - T_jra55 = jra55_field_time_series(:temperature, grid; time_indices, architecture) - p_jra55 = jra55_field_time_series(:surface_pressure, grid; time_indices, architecture) - q_jra55 = jra55_field_time_series(:specific_humidity, grid; time_indices, architecture) - Fr_jra55 = jra55_field_time_series(:freshwater_rain_flux, grid; time_indices, architecture) - Fs_jra55 = jra55_field_time_series(:freshwater_snow_flux, grid; time_indices, architecture) - Fv_jra55 = jra55_field_time_series(:freshwater_river_flux, grid; time_indices, architecture) - Fi_jra55 = jra55_field_time_series(:freshwater_iceberg_flux, grid; time_indices, architecture) - Qlw_jra55 = jra55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) - Qsw_jra55 = jra55_field_time_series(:downwelling_shortwave_radiation, grid; time_indices, architecture) - - times = u_jra55.times - - velocities = (u = u_jra55, - v = v_jra55) - - tracers = (T = T_jra55, - q = q_jra55) - - freshwater_flux = (rain = Fr_jra55, - snow = Fs_jra55, - rivers = Fv_jra55, - icebergs = Fi_jra55) - - downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qsw_jra55) - - atmosphere = PrescribedAtmosphere(times; velocities, - freshwater_flux, - tracers, - downwelling_radiation, - reference_height, - pressure = p_jra55) - - return atmosphere -end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 4d658d6d..aad20e56 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -277,12 +277,17 @@ end Qe = clip(conditions.lhf) # latent or "evaporative" heat flux ΣQ = Qd + Qu + Qc + Qe + if i == j == 1 + @show conditions + @show propertynames(conditions) + end + # Accumulate freshwater fluxes. Rain, snow, runoff -- all freshwater. # Note these are mass fluxes, hence the "M". M = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) # Convert from a mass flux to a volume flux / velocity? - # Also switch the sign, for some reason we are given freshwater as positive down. + # Also switch the sign, for some reason we are given freshwater flux as positive down. ρᶠ = freshwater_density ΣF = - M / ρᶠ @@ -313,11 +318,10 @@ end inactive = inactive_node(i, j, kᴺ, grid, c, c, c) @inbounds begin - nan = convert(FT, NaN) - Jᵘ[i, j, 1] = ifelse(inactive, nan, atmos_ocean_Jᵘ) - Jᵛ[i, j, 1] = ifelse(inactive, nan, atmos_ocean_Jᵛ) - Jᵀ[i, j, 1] = ifelse(inactive, nan, atmos_ocean_Jᵀ) - Jˢ[i, j, 1] = ifelse(inactive, nan, atmos_ocean_Jˢ) + Jᵘ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵘ) + Jᵛ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵛ) + Jᵀ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵀ) + Jˢ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jˢ) end end From 98a07862f866f3f46fc477c3ffb197b1c383d07f Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 23 Jan 2024 14:07:15 -0700 Subject: [PATCH 061/182] Clean up --- .../analyze_omip_columns.jl | 106 --------- .../prototype_omip_simulation/ecco2_stuff.jl | 36 --- ...obally_distributed_single_column_models.jl | 212 ------------------ 3 files changed, 354 deletions(-) delete mode 100644 experiments/prototype_omip_simulation/analyze_omip_columns.jl delete mode 100644 experiments/prototype_omip_simulation/ecco2_stuff.jl delete mode 100644 experiments/prototype_omip_simulation/globally_distributed_single_column_models.jl diff --git a/experiments/prototype_omip_simulation/analyze_omip_columns.jl b/experiments/prototype_omip_simulation/analyze_omip_columns.jl deleted file mode 100644 index 6bfe3ca8..00000000 --- a/experiments/prototype_omip_simulation/analyze_omip_columns.jl +++ /dev/null @@ -1,106 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.BuoyancyModels: buoyancy_frequency - -using ClimaOcean -using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere -using ClimaOcean.DataWrangling.ECCO2: ecco2_field - -using GLMakie -using Printf -using Dates - -start_time = time_ns() - -include("single_column_omip_ocean_component.jl") - -epoch = Date(1992, 1, 1) -date = Date(1992, 10, 01) -start_seconds = Second(date - epoch).value -uᵢ = ecco2_field(:u_velocity, date) -vᵢ = ecco2_field(:v_velocity, date) -Tᵢ = ecco2_field(:temperature, date) -Sᵢ = ecco2_field(:salinity, date) - -land = interior(Tᵢ) .< -10 -interior(Tᵢ)[land] .= NaN -interior(Sᵢ)[land] .= NaN - -teos10 = TEOS10EquationOfState() -buoyancy = SeawaterBuoyancy(equation_of_state=teos10) -tracers = (T=Tᵢ, S=Sᵢ) -N²_op = buoyancy_frequency(buoyancy, Tᵢ.grid, tracers) -N² = Field(N²_op) -compute!(N²) - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### - -zc = znodes(Tᵢ) -zf = znodes(N²) - -arch = CPU() - -Δ = 1/4 # resolution in degrees -φ₁ = -90 + Δ/2 -φ₂ = +90 - Δ/2 -λ₁ = 0 + Δ/2 -λ₂ = 360 - Δ/2 -φe = φ₁:Δ:φ₂ -λe = λ₁:Δ:λ₂ - -Nz = size(Tᵢ, 3) -fig = Figure(resolution=(1200, 1200)) -map = Axis(fig[1, 1:3], xlabel="λ (degrees)", ylabel="φ (degrees)") -hm = heatmap!(map, λe, φe, interior(Tᵢ, :, :, Nz), colorrange=(0, 30), nan_color=:gray) -Colorbar(fig[1, 4], hm, label="Surface temperature (ᵒC)") - -axT = Axis(fig[2, 1], ylabel="z (m)", xlabel="Temperature (ᵒC)") -axS = Axis(fig[2, 2], ylabel="z (m)", xlabel="Salinity (g/kg)") -axN = Axis(fig[2, 3], ylabel="z (m)", xlabel="Buoyancy frequency (s⁻²)") - -φs = [50, 55, 0, -30, -65, 34] -λs = [215, 310, 210, 160, 160, 34] - -# Mediterranean locations -# λs = [34, 33, 5, 20, 30] -# φs = [34, 32, 38, 35, 33] - -Nc = length(φs) - -for n = 1:Nc - local φ★ - local λ★ - local i★ - local j★ - - φ★ = φs[n] - λ★ = λs[n] - - i★ = searchsortedfirst(λe, λ★) - j★ = searchsortedfirst(φe, φ★) - - scatter!(map, λ★, φ★, strokewidth=4, strokecolor=:black, - color=:pink, markersize=20) - - label = string("λ = ", λ★, ", φ = ", φ★) - scatterlines!(axT, interior(Tᵢ, i★, j★, :), zc; label) - scatterlines!(axS, interior(Sᵢ, i★, j★, :), zc; label) - scatterlines!(axN, interior(N², i★, j★, :), zf; label) -end - -zm = -500 - -xlims!(axT, -2, 30) -xlims!(axS, 32, 40) -ylims!(axT, zm, 30) -ylims!(axS, zm, 30) -axislegend(axT, position=:rb) - -display(fig) - diff --git a/experiments/prototype_omip_simulation/ecco2_stuff.jl b/experiments/prototype_omip_simulation/ecco2_stuff.jl deleted file mode 100644 index 6ef611de..00000000 --- a/experiments/prototype_omip_simulation/ecco2_stuff.jl +++ /dev/null @@ -1,36 +0,0 @@ -temperature_filename = "THETA.1440x720x50.19920102.nc" -salinity_filename = "SALT.1440x720x50.19920102.nc" - -# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N -temperature_url = "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * - "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0" - -salinity_url = "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * - "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0" - -isfile(temperature_filename) || download(temperature_url, temperature_filename) -isfile(salinity_filename) || download(salinity_url, salinity_filename) - -temperature_ds = Dataset(temperature_filename) -salinity_ds = Dataset(salinity_filename) - -# Construct vertical coordinate -depth = temperature_ds["DEPTH_T"][:] -zc = -reverse(depth) - -# Interface depths from cell center depths -zf = (zc[1:end-1] .+ zc[2:end]) ./ 2 -push!(zf, 0) - -Δz = zc[2] - zc[1] -pushfirst!(zf, zf[1] - Δz) - -Tᵢ = temperature_ds["THETA"][:, :, :, 1] -Sᵢ = salinity_ds["SALT"][:, :, :, 1] - -Tᵢ = convert(Array{Float32, 3}, Tᵢ) -Sᵢ = convert(Array{Float32, 3}, Sᵢ) - -Tᵢ = reverse(Tᵢ, dims=3) -Sᵢ = reverse(Sᵢ, dims=3) - diff --git a/experiments/prototype_omip_simulation/globally_distributed_single_column_models.jl b/experiments/prototype_omip_simulation/globally_distributed_single_column_models.jl deleted file mode 100644 index fd0e7b8c..00000000 --- a/experiments/prototype_omip_simulation/globally_distributed_single_column_models.jl +++ /dev/null @@ -1,212 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity -using Oceananigans.Fields: ConstantField, ZeroField, interpolate! -using Oceananigans.Models.HydrostaticFreeSurfaceModels: ColumnEnsembleSize - -using ClimaOcean -using ClimaOcean.OceanSeaIceModels: TwoStreamDownwellingRadiation, - PrescribedAtmosphere, - SurfaceRadiation - -using ClimaOcean.JRA55: jra55_field_time_series - -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState - -using NCDatasets -using GLMakie -using Printf - -using Downloads: download - -temperature_filename = "THETA.1440x720x50.19920102.nc" -salinity_filename = "SALT.1440x720x50.19920102.nc" -ice_thickness_filename = "SIheff.1440x720.19920102.nc" - -# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N - -temperature_url = "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * - "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0" - -salinity_url = "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * - "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0" - -ice_thickness_url = "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/" * - "SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am&dl=0" - -isfile(temperature_filename) || download(temperature_url, temperature_filename) -isfile(salinity_filename) || download(salinity_url, salinity_filename) -isfile(ice_thickness_filename) || download(ice_thickness_url, ice_thickness_filename) - -temperature_ds = Dataset(temperature_filename) -salinity_ds = Dataset(salinity_filename) -ice_thickness_ds = Dataset(ice_thickness_filename) - -# Construct vertical coordinate -depth = temperature_ds["DEPTH_T"][:] -zc = -reverse(depth) - -# Interface depths from cell center depths -zf = (zc[1:end-1] .+ zc[2:end]) ./ 2 -push!(zf, 0) - -Δz = zc[2] - zc[1] -pushfirst!(zf, zf[1] - Δz) - -Tᵢ = temperature_ds["THETA"][:, :, :, 1] -Sᵢ = salinity_ds["SALT"][:, :, :, 1] -ℋᵢ = ice_thickness_ds["SIheff"][:, :, 1] - -Nx′, Ny′, Nz = size(Tᵢ) - -##### -##### Construct the grid -##### - -arch = CPU() - -Nx = 1 -target_longitude = 180 -western_limit = target_longitude -eastern_limit = target_longitude + 1/4 -i₁ = 4 * western_limit -i₂ = i₁ + 1 - -southern_limit = -70 -northern_limit = +55 -j₁ = 4 * (90 + southern_limit) -j₂ = 720 - 4 * (90 - northern_limit) + 1 - -Ny = j₂ - j₁ + 1 - -Tᵢ = Tᵢ[i₁:i₂, j₁:j₂, :] -Sᵢ = Sᵢ[i₁:i₂, j₁:j₂, :] - -Tᵢ = convert(Array{Float32, 3}, Tᵢ) -Sᵢ = convert(Array{Float32, 3}, Sᵢ) -ℋᵢ = convert(Array{Float32, 2}, ℋᵢ) - -Tᵢ = reverse(Tᵢ, dims=3) -Sᵢ = reverse(Sᵢ, dims=3) - -# missing_value = Float32(-9.9e22) - -grid = LatitudeLongitudeGrid(arch, - size = (Nx, Ny, Nz), - halo = (1, 1, 1), - longitude = (western_limit, eastern_limit), - latitude = (southern_limit, northern_limit), - z = zf, - topology = (Periodic, Bounded, Bounded)) - -include("omip_atmosphere.jl") - -column_ensemble_size = ColumnEnsembleSize(Nz=Nz, ensemble=(Nx, Ny)) -column_ensemble_halo_size = ColumnEnsembleSize(Nz=0, Hz=1) - -single_column_grid = RectilinearGrid(arch, - size = column_ensemble_size, - halo = column_ensemble_halo_size, - z = zf, - topology = (Flat, Flat, Bounded)) - -Ω = Oceananigans.Coriolis.Ω_Earth -f(i, j) = 2Ω * sind(φnode(i, j, 1, grid)) -coriolis = [FPlane(f=f(i, j)) for i=1:Nx, j=1:Ny] - -top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(single_column_grid) -top_salt_flux = Fˢ = Field{Center, Center, Nothing}(single_column_grid) -top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(single_column_grid) -top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(single_column_grid) - -ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), - v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), - T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), - S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) - -# Model construction -teos10 = TEOS10EquationOfState() -buoyancy = SeawaterBuoyancy(equation_of_state=teos10) -closure = CATKEVerticalDiffusivity() - -ocean_model = HydrostaticFreeSurfaceModel(; buoyancy, closure, coriolis, - grid = single_column_grid, - tracers = (:T, :S, :e), - boundary_conditions = ocean_boundary_conditions) - -#= -##### -##### Setup JRA55 atmosphere -##### - -time_indices = 1:10 - -ua_jra55 = jra55_field_time_series(:eastward_velocity; time_indices, architecture=arch) -va_jra55 = jra55_field_time_series(:northward_velocity; time_indices, architecture=arch) -Ta_jra55 = jra55_field_time_series(:temperature; time_indices, architecture=arch) -qa_jra55 = jra55_field_time_series(:relative_humidity; time_indices, architecture=arch) -Fr_jra55 = jra55_field_time_series(:freshwater_rain_flux; time_indices, architecture=arch) -Fs_jra55 = jra55_field_time_series(:freshwater_snow_flux; time_indices, architecture=arch) -Qlw_jra55 = jra55_field_time_series(:downwelling_longwave_radiation; time_indices, architecture=arch) -Qsw_jra55 = jra55_field_time_series(:downwelling_shortwave_radiation; time_indices, architecture=arch) - -times = ua_jra55.times - -u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing)) -v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing)) -c_bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing)) - -ua_jra55 = FieldTimeSeries{Face, Center, Nothing}(grid, times; boundary_conditions=u_bcs) -va_jra55 = FieldTimeSeries{Center, Face, Nothing}(grid, times; boundary_conditions=v_bcs) -Ta_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -qa_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Fr_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Fs_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Qlw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) -Qsw_jra55 = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=c_bcs) - -interpolate!(ua_jra55, u_jra55_native) -interpolate!(va_jra55, v_jra55_native) -interpolate!(Ta_jra55, T_jra55_native) -interpolate!(qa_jra55, q_jra55_native) -interpolate!(Fr_jra55, Fr_jra55_native) -interpolate!(Fs_jra55, Fs_jra55_native) -interpolate!(Qlw_jra55, Qlw_jra55_native) -interpolate!(Qsw_jra55, Qsw_jra55_native) - - ua_scm = FieldTimeSeries{Face, Center, Nothing}(single_column_grid, times) - va_scm = FieldTimeSeries{Center, Face, Nothing}(single_column_grid, times) - Ta_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) - qa_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) - Fr_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) - Fs_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) -Qlw_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) -Qsw_scm = FieldTimeSeries{Center, Center, Nothing}(single_column_grid, times) - -interior( u_scm, :, :, :) .= interior( u_jra55, :, :, :) -interior( v_scm, :, :, :) .= interior( v_jra55, :, :, :) -interior( T_scm, :, :, :) .= interior( T_jra55, :, :, :) -interior( q_scm, :, :, :) .= interior( q_jra55, :, :, :) -interior( Fr_scm, :, :, :) .= interior( Fr_jra55, :, :, :) -interior( Fs_scm, :, :, :) .= interior( Fs_jra55, :, :, :) -interior(Qlw_scm, :, :, :) .= interior(Qlw_jra55, :, :, :) -interior(Qsw_scm, :, :, :) .= interior(Qsw_jra55, :, :, :) - -velocities = (u = u_scm, v = v_scm) -tracers = (T = T_scm, q = q_scm) -freshwater_flux = (rain = Fr_scm, snow = Fs_scm) -downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_scm, longwave=Qsw_scm) -atmosphere = PrescribedAtmosphere(times; velocities, freshwater_flux, tracers, downwelling_radiation) -=# - -set!(ocean_model, T=Tᵢ, S=Sᵢ) - -surface_radiation = SurfaceRadiation() - -coupled_model = OceanSeaIceModel(ocean; - atmosphere = atmosphere - surface_radiation = surface_radiation) - -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) #stop_time=30days) - -run!(coupled_simulation) From 0f7bf44e2c6aae65adccecb52ceb386c9901a081 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 23 Jan 2024 17:35:54 -0500 Subject: [PATCH 062/182] Update packages --- Manifest.toml | 110 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 40 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 69c4ab57..9dd6b029 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -15,6 +15,25 @@ weakdeps = ["ChainRulesCore", "Test"] AbstractFFTsChainRulesCoreExt = "ChainRulesCore" AbstractFFTsTestExt = "Test" +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Test"] +git-tree-sha1 = "cb96992f1bec110ad211b7e410e57ddf7944c16f" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.35" + + [deps.Accessors.extensions] + AccessorsAxisKeysExt = "AxisKeys" + AccessorsIntervalSetsExt = "IntervalSets" + AccessorsStaticArraysExt = "StaticArrays" + AccessorsStructArraysExt = "StructArrays" + + [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" + [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" @@ -76,9 +95,9 @@ version = "0.1.8" [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.8+0" +version = "1.0.8+1" [[deps.CEnum]] git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" @@ -99,9 +118,9 @@ version = "0.7.26" [[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", "Statistics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "76582ae19006b1186e87dadd781747f76cead72c" +git-tree-sha1 = "95ac638373ac40e29c1b6d086a3698f5026ff6a6" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.1.1" +version = "5.1.2" weakdeps = ["ChainRulesCore", "SpecialFunctions"] [deps.CUDA.extensions] @@ -128,9 +147,9 @@ version = "0.10.1+0" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "2118cb2765f8197b08e5958cdd17c165427425ee" +git-tree-sha1 = "c1deebd76f7a443d527fc0430d5758b8b2112ed8" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.19.0" +version = "1.19.1" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -180,10 +199,10 @@ uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" version = "0.3.0" [[deps.Compat]] -deps = ["UUIDs"] -git-tree-sha1 = "886826d76ea9e72b35fcd000e535588f7b60f21d" +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.10.1" +version = "4.12.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -194,6 +213,15 @@ deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.0.5+1" +[[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 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" @@ -232,15 +260,15 @@ uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" version = "0.2.1" [[deps.DataAPI]] -git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.15.0" +version = "1.16.0" [[deps.DataDeps]] -deps = ["HTTP", "Libdl", "Reexport", "SHA", "p7zip_jll"] -git-tree-sha1 = "6e8d74545d34528c30ccd3fa0f3c00f8ed49584c" +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "d481f6419c262edcb7294179bd63249d123eb081" uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.11" +version = "0.7.12" [[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"] @@ -325,9 +353,9 @@ version = "0.1.10" [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "ec22cbbcd01cba8f41eecd7d44aac1f23ee985e3" +git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.7.2" +version = "1.8.0" [[deps.FFTW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -432,6 +460,12 @@ version = "2024.0.2+0" deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "68772f49f54b479fa88ace904f6127f0a3bb2e46" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.12" + [[deps.InvertedIndices]] git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" @@ -455,9 +489,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "e65d2bd5754885e97407ff686da66a58b1e20df8" +git-tree-sha1 = "7c0008f0b7622c6c0ee5c65cbc667b69f8a65672" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.41" +version = "0.4.45" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -485,9 +519,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "653e0824fc9ab55b3beec67a6dbbe514a65fb954" +git-tree-sha1 = "4e0cb2f5aad44dcfdc91088e85dee4ecb22c791c" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.15" +version = "0.9.16" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -633,9 +667,9 @@ version = "5.3.1+1" [[deps.MacroTools]] deps = ["Markdown", "Random"] -git-tree-sha1 = "b211c553c199c111d998ecdaf7623d1b89b69f93" +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.12" +version = "0.5.13" [[deps.Markdown]] deps = ["Base64"] @@ -679,9 +713,9 @@ version = "0.13.2" [[deps.NVTX]] deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] -git-tree-sha1 = "8bc9ce4233be3c63f8dcd78ccaf1b63a9c0baa34" +git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" -version = "0.3.3" +version = "0.3.4" [[deps.NVTX_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -707,11 +741,11 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "eeca396589a53c957bcf5a9847e02c2eb915fe29" +git-tree-sha1 = "117d0d9331a738ded226eb702a7d30e3ab348dc6" repo-rev = "glw/better-interpolate2" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.4" +version = "0.90.5" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -906,10 +940,10 @@ uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" version = "0.4.1" [[deps.Roots]] -deps = ["ChainRulesCore", "CommonSolve", "Printf", "Setfield"] -git-tree-sha1 = "0f1d92463a020321983d04c110f476c274bafe2e" +deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] +git-tree-sha1 = "af540898b1e6ca7aa6ba7213c05052809c6c522a" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.0.22" +version = "2.1.0" [deps.Roots.extensions] RootsForwardDiffExt = "ForwardDiff" @@ -955,12 +989,6 @@ version = "1.4.1" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -[[deps.Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.1" - [[deps.SimpleBufferStream]] git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" @@ -1009,9 +1037,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "4e17a790909b17f7bf1496e3aec138cf01b60b3b" +git-tree-sha1 = "f68dd04d131d9a8a8eb836173ee8f105c360b0c5" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.0" +version = "1.9.1" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -1063,9 +1091,9 @@ version = "0.3.4" [[deps.StructArrays]] deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" +git-tree-sha1 = "1b0b1205a56dc288b71b1961d48e351520702e24" uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.16" +version = "0.6.17" [[deps.StructTypes]] deps = ["Dates", "UUIDs"] @@ -1130,7 +1158,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Printf", "Random", "RootSolvers"] -path = "/Users/gregorywagner/Projects/Thermodynamics.jl" +git-tree-sha1 = "c951709d33e7d530241501de56cb87c7d8861dac" +repo-rev = "glw/hierarchical-params-example" +repo-url = "https://github.com/CliMA/Thermodynamics.jl.git" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" version = "0.11.2" From ae86c0364d219d574a52051a0472bf8d74aba52a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 23 Jan 2024 18:23:37 -0500 Subject: [PATCH 063/182] Package gymnastics --- Manifest.toml | 22 +- Project.toml | 1 - .../prototype_omip_simulation/Manifest.toml | 560 +++++++++--------- .../prototype_omip_simulation/Project.toml | 1 - .../regional_omip_simulation.jl | 6 +- 5 files changed, 283 insertions(+), 307 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 9dd6b029..d9231b54 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0-beta3" manifest_format = "2.0" -project_hash = "5d2ac82a7066017c63d34437c6eed8b514474918" +project_hash = "bcfc95e502c18276c6e7315f722ad6f48d7698c2" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -112,9 +112,9 @@ version = "0.1.2" [[deps.CLIMAParameters]] deps = ["DocStringExtensions", "TOML", "Test"] -git-tree-sha1 = "a085251dfe4b0f732fe2b65d5354e6af91a8e931" +git-tree-sha1 = "0c8c49ca2b7992490ab2a5292ed23aeae8b0768f" uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" -version = "0.7.26" +version = "0.8.2" [[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", "Statistics", "UnsafeAtomicsLLVM"] @@ -1112,7 +1112,7 @@ version = "7.2.0+1" [[deps.SurfaceFluxes]] deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "dac64dc26093ed511d9f11d82fde437acdc540a4" +git-tree-sha1 = "3b54de787d5f07b56a34578174174c99dc30beda" repo-rev = "glw/generalize-parameters" repo-url = "https://github.com/glwagner/SurfaceFluxes.jl.git" uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" @@ -1157,12 +1157,16 @@ deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] -deps = ["DocStringExtensions", "KernelAbstractions", "Printf", "Random", "RootSolvers"] -git-tree-sha1 = "c951709d33e7d530241501de56cb87c7d8861dac" -repo-rev = "glw/hierarchical-params-example" -repo-url = "https://github.com/CliMA/Thermodynamics.jl.git" +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "e5f6bf517ab1d28af577ac2acf42f24020c7d086" +repo-rev = "glw/density-example" +repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.11.2" +version = "0.11.4" +weakdeps = ["CLIMAParameters"] + + [deps.Thermodynamics.extensions] + CreateParametersExt = "CLIMAParameters" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] diff --git a/Project.toml b/Project.toml index c9a2f81d..5018ab52 100644 --- a/Project.toml +++ b/Project.toml @@ -6,7 +6,6 @@ version = "0.1.0" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" CubicSplines = "9c784101-8907-5a6d-9be6-98f00873c89b" diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 58cf6a36..ba947ca3 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0-beta3" manifest_format = "2.0" -project_hash = "7c534a264b9c4e557224dee6d48b112d23aa3745" +project_hash = "6533489dd3ea9e5b8f9155148c8dcd78d68604f0" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -16,20 +16,39 @@ weakdeps = ["ChainRulesCore", "Test"] AbstractFFTsTestExt = "Test" [[deps.AbstractLattices]] -git-tree-sha1 = "f35684b7349da49fcc8a9e520e30e45dbb077166" +git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" -version = "0.2.1" +version = "0.3.0" [[deps.AbstractTrees]] git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" version = "0.4.4" +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Test"] +git-tree-sha1 = "cb96992f1bec110ad211b7e410e57ddf7944c16f" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.35" + + [deps.Accessors.extensions] + AccessorsAxisKeysExt = "AxisKeys" + AccessorsIntervalSetsExt = "IntervalSets" + AccessorsStaticArraysExt = "StaticArrays" + AccessorsStructArraysExt = "StructArrays" + + [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" + [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "02f731463748db57cc2ebfbd9fbc9ce8280d3433" +git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.7.1" +version = "3.7.2" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] @@ -47,9 +66,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "16267cf279190ca7c1b30d020758ced95db89cd0" +git-tree-sha1 = "bbec08a37f8722786d87bedf84eae19c020c4efa" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.5.1" +version = "7.7.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -77,16 +96,16 @@ uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" version = "0.1.0" [[deps.Automa]] -deps = ["TranscodingStreams"] -git-tree-sha1 = "ef9997b3d5547c48b41c7bd8899e812a917b409d" +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "0.8.4" +version = "1.0.3" [[deps.AxisAlgorithms]] deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] -git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7" +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "1.0.1" +version = "1.1.0" [[deps.AxisArrays]] deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] @@ -103,21 +122,16 @@ version = "0.4.2" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" -[[deps.BitFlags]] -git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.8" - [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.8+0" +version = "1.0.8+1" [[deps.CEnum]] -git-tree-sha1 = "eb4cb44a499229b3b8426dcfb5dd85333951ff90" +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.4.2" +version = "0.5.0" [[deps.CFTime]] deps = ["Dates", "Printf"] @@ -125,12 +139,6 @@ git-tree-sha1 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" uuid = "179af706-886a-5703-950a-314cd64e0468" version = "0.1.2" -[[deps.CLIMAParameters]] -deps = ["DocStringExtensions", "TOML", "Test"] -git-tree-sha1 = "a085251dfe4b0f732fe2b65d5354e6af91a8e931" -uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" -version = "0.7.26" - [[deps.CRC32c]] uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" @@ -148,9 +156,9 @@ version = "1.0.1+0" [[deps.CUDA]] deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "Statistics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "64461b0e9df3069248979113ce8ab6d11bd371cf" +git-tree-sha1 = "95ac638373ac40e29c1b6d086a3698f5026ff6a6" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.1.0" +version = "5.1.2" weakdeps = ["ChainRulesCore", "SpecialFunctions"] [deps.CUDA.extensions] @@ -159,9 +167,9 @@ weakdeps = ["ChainRulesCore", "SpecialFunctions"] [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "1e42ef1bdb45487ff28de16182c0df4920181dc3" +git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.7.0+0" +version = "0.7.0+1" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] @@ -171,9 +179,9 @@ version = "0.2.2" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "92394521ec4582c11d089a3b15b76ef2cb850994" +git-tree-sha1 = "9704e50c9158cf8896c2776b8dbc5edd136caf80" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.10.0+1" +version = "0.10.1+0" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -189,20 +197,14 @@ version = "0.5.1" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "e0af648f0692ec1691b5d094b8724ba1346281cf" +git-tree-sha1 = "c1deebd76f7a443d527fc0430d5758b8b2112ed8" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.18.0" +version = "1.19.1" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] ChainRulesCoreSparseArraysExt = "SparseArrays" -[[deps.ClimaOcean]] -deps = ["Adapt", "CLIMAParameters", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] -path = "../.." -uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -version = "0.1.0" - [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" @@ -211,12 +213,6 @@ repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.3" - [[deps.ColorBrewer]] deps = ["Colors", "JSON", "Test"] git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" @@ -236,10 +232,14 @@ uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.11.4" [[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"] -git-tree-sha1 = "600cc5508d66b78aae350f7accdb58763ac18589" +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.9.10" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] @@ -270,10 +270,10 @@ uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" version = "0.3.0" [[deps.Compat]] -deps = ["UUIDs"] -git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.10.0" +version = "4.12.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -284,11 +284,14 @@ deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.0.5+1" -[[deps.ConcurrentUtilities]] -deps = ["Serialization", "Sockets"] -git-tree-sha1 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.3.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.ConstructionBase]] deps = ["LinearAlgebra"] @@ -317,22 +320,10 @@ git-tree-sha1 = "253193dfb0384646936c5ff3230b27a20d91261e" uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" version = "0.2.4" -[[deps.CubicSplines]] -deps = ["Random", "Test"] -git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" -uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" -version = "0.2.1" - [[deps.DataAPI]] -git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.15.0" - -[[deps.DataDeps]] -deps = ["HTTP", "Libdl", "Reexport", "SHA", "p7zip_jll"] -git-tree-sha1 = "6e8d74545d34528c30ccd3fa0f3c00f8ed49584c" -uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.11" +version = "1.16.0" [[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"] @@ -342,9 +333,9 @@ version = "1.6.1" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" +git-tree-sha1 = "ac67408d9ddf207de5cfa9a97e114352430f01ed" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.15" +version = "0.18.16" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -357,9 +348,9 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelaunayTriangulation]] deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] -git-tree-sha1 = "7cb0d72a53c1d93665eeadfa9d51af9df60bf6b2" +git-tree-sha1 = "26eb8e2331b55735c3d305d949aabd7363f07ba7" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "0.8.10" +version = "0.8.11" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -381,9 +372,9 @@ version = "0.3.22" [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.10" +version = "0.10.11" weakdeps = ["ChainRulesCore", "SparseArrays"] [deps.Distances.extensions] @@ -396,9 +387,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.Distributions]] deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "a6c00f894f24460379cb7136633cef54ac9f6f4a" +git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.103" +version = "0.25.107" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" @@ -454,12 +445,6 @@ git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" version = "2.2.5" -[[deps.ExceptionUnwrapping]] -deps = ["Test"] -git-tree-sha1 = "e90caa41f5a86296e014e148ee061bd6c3edec96" -uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" -version = "0.1.9" - [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" @@ -484,9 +469,9 @@ version = "4.4.4+1" [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "b4fbdd20c889804969571cc589900803edda16b7" +git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.7.1" +version = "1.8.0" [[deps.FFTW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -502,29 +487,42 @@ version = "0.3.1" [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "299dc33549f68299137e51e6d49a13b5b1da9673" +git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc" uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.1" +version = "1.16.2" + +[[deps.FilePaths]] +deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] +git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" +uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" +version = "0.8.3" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] +git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.21" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FillArrays]] deps = ["LinearAlgebra", "Random"] -git-tree-sha1 = "35f0c0f345bff2c6d636f95fdb136323b5a796ef" +git-tree-sha1 = "5b93957f6dcd33fc343044af3d48c215be2562f1" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.7.0" -weakdeps = ["SparseArrays", "Statistics"] +version = "1.9.3" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" FillArraysSparseArraysExt = "SparseArrays" FillArraysStatisticsExt = "Statistics" [[deps.FiniteDiff]] deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "c6e4a1fbe73b31a3dea94b1da449503b8830c306" +git-tree-sha1 = "73d1214fec245096717847c62d389a5d2ac86504" uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.21.1" +version = "2.22.0" [deps.FiniteDiff.extensions] FiniteDiffBandedMatricesExt = "BandedMatrices" @@ -566,9 +564,9 @@ weakdeps = ["StaticArrays"] [[deps.FreeType]] deps = ["CEnum", "FreeType2_jll"] -git-tree-sha1 = "50351f83f95282cf903e968d7c6e8d44a5f83d0b" +git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "4.1.0" +version = "4.1.1" [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] @@ -578,9 +576,9 @@ version = "2.13.1+0" [[deps.FreeTypeAbstraction]] deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] -git-tree-sha1 = "38a92e40157100e796690421e34a11c107205c86" +git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.0" +version = "0.10.1" [[deps.FriBidi_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -599,16 +597,16 @@ uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" version = "3.4.1" [[deps.GLFW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] -git-tree-sha1 = "d972031d28c8c8d9d7b41a536ad7bb0c2579caca" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" -version = "3.3.8+0" +version = "3.3.9+0" [[deps.GLMakie]] deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "8236ce4eda9837d15bab49573bba16ba0652b486" +git-tree-sha1 = "e53267e2fc64f81b939849ca7bd70d8f879b5293" uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.8.12" +version = "0.9.5" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] @@ -630,9 +628,9 @@ version = "0.25.0" [[deps.GeoInterface]] deps = ["Extents"] -git-tree-sha1 = "d53480c0793b13341c40199190f92c611aa2e93c" +git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.2" +version = "1.3.3" [[deps.GeometryBasics]] deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] @@ -657,12 +655,6 @@ git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" version = "1.3.1" -[[deps.Graphics]] -deps = ["Colors", "LinearAlgebra", "NaNMath"] -git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" -uuid = "a2bd30eb-e257-5431-a919-1863eab51364" -version = "1.1.2" - [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" @@ -671,9 +663,9 @@ version = "1.3.14+0" [[deps.GridLayoutBase]] deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" +git-tree-sha1 = "af13a277efd8a6e716d79ef635d5342ccb75be61" uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.9.2" +version = "0.10.0" [[deps.Grisu]] git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" @@ -686,12 +678,6 @@ 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 = "5eab648309e2e060198b45820af1a37182de3cce" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.0" - [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" @@ -700,9 +686,9 @@ version = "2.8.1+1" [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8ecb0b34472a3c98f945e3c75fc7d5428d165511" +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.9.3+0" +version = "2.10.0+0" [[deps.HypergeometricFunctions]] deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] @@ -723,15 +709,15 @@ version = "0.6.11" [[deps.ImageBase]] deps = ["ImageCore", "Reexport"] -git-tree-sha1 = "b51bb8cae22c66d0f6357e3bcb6363145ef20835" +git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" uuid = "c817782e-172a-44cc-b673-b171935fbb9e" -version = "0.1.5" +version = "0.1.7" [[deps.ImageCore]] -deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"] -git-tree-sha1 = "acf614720ef026d38400b3817614c45882d75500" +deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "fc5d1d3443a124fde6e92d0260cd9e064eba69f8" uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.9.4" +version = "0.10.1" [[deps.ImageIO]] deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] @@ -779,10 +765,10 @@ uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" version = "0.1.2" [[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ad37c091f7d7daf900963171600d7c1c5c3ede32" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2023.2.0+0" +version = "2024.0.2+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -790,9 +776,15 @@ uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[deps.Interpolations]] deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "721ec2cf720536ad005cb38f50dbba7b02419a15" +git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.14.7" +version = "0.15.1" + + [deps.Interpolations.extensions] + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [[deps.IntervalArithmetic]] deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] @@ -810,6 +802,12 @@ weakdeps = ["Statistics"] [deps.IntervalSets.extensions] IntervalSetsStatisticsExt = "Statistics" +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "68772f49f54b479fa88ace904f6127f0a3bb2e46" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.12" + [[deps.InvertedIndices]] git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" @@ -827,9 +825,9 @@ uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" version = "0.1.1" [[deps.IterTools]] -git-tree-sha1 = "4ced6667f9974fc5c5943fa5e2ef1ca43ea9e450" +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.8.0" +version = "1.10.0" [[deps.IterativeSolvers]] deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] @@ -844,9 +842,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "9bbb5130d3b4fa52846546bca4791ecbdfb52730" +git-tree-sha1 = "7c0008f0b7622c6c0ee5c65cbc667b69f8a65672" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.38" +version = "0.4.45" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -862,21 +860,27 @@ version = "0.21.4" [[deps.JSON3]] deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] -git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -version = "1.13.2" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" [[deps.JpegTurbo]] deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] -git-tree-sha1 = "d65930fa2bc96b07d7691c652d701dcbe7d9cf0b" +git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" -version = "0.1.4" +version = "0.1.5" [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6f2675ef130a300a112286de91973805fcc5ffbc" +git-tree-sha1 = "60b1194df0a3298f460063de985eae7b01bc011a" uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "2.1.91+0" +version = "3.0.1+0" [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -886,9 +890,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "95063c5bc98ba0c47e75e05ae71f1fed4deac6f6" +git-tree-sha1 = "4e0cb2f5aad44dcfdc91088e85dee4ecb22c791c" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.12" +version = "0.9.16" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -898,9 +902,9 @@ version = "0.9.12" [[deps.KernelDensity]] deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "90442c50e202a5cdf21a7899c66b240fdef14035" +git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.7" +version = "0.6.8" [[deps.LAME_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -910,9 +914,9 @@ version = "3.100.1+0" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "c879e47398a7ab671c782e02b51a4456794a7fa3" +git-tree-sha1 = "cb4619f7353fc62a1a22ffa3d7ed9791cfb47ad8" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.4.0" +version = "6.4.2" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -920,9 +924,9 @@ weakdeps = ["BFloat16s"] [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "a84f8f1e8caaaa4e3b4c101306b9e801d3883ace" +git-tree-sha1 = "98eaee04d96d973e79c25d49167668c5c8fb50e2" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.27+0" +version = "0.0.27+1" [[deps.LLVMLoopInfo]] git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" @@ -930,10 +934,10 @@ uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" version = "1.0.0" [[deps.LLVMOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f689897ccbe049adb19a065c495e75f372ecd42b" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "15.0.4+0" +version = "15.0.7+0" [[deps.LZO_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1026,9 +1030,9 @@ version = "2.36.0+0" [[deps.LightXML]] deps = ["Libdl", "XML2_jll"] -git-tree-sha1 = "e129d9391168c677cd4800f5c0abb1ed8cb3794f" +git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" -version = "0.9.0" +version = "0.9.1" [[deps.LineSearches]] deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] @@ -1041,10 +1045,10 @@ deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LinearAlgebraX]] -deps = ["LinearAlgebra", "Mods", "Permutations", "Primes", "SimplePolynomials"] -git-tree-sha1 = "558a338f1eeabe933f9c2d4052aa7c2c707c3d52" +deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] +git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" -version = "0.1.12" +version = "0.2.7" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] @@ -1065,17 +1069,11 @@ version = "0.3.26" [[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.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "eb006abbd7041c28e0d16260e50a24f8f9104913" +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2023.2.0+0" +version = "2024.0.0+0" [[deps.MPI]] deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] @@ -1093,9 +1091,9 @@ version = "0.20.16" [[deps.MPICH_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "8a5b4d2220377d1ece13f49438d71ad20cf1ba83" +git-tree-sha1 = "2ee75365ca243c1a39d467e35ffd3d4d32eef11e" uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.1.2+0" +version = "4.1.2+1" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] @@ -1105,27 +1103,27 @@ version = "0.1.10" [[deps.MPItrampoline_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "6979eccb6a9edbbb62681e158443e79ecc0d056a" +git-tree-sha1 = "8eeb3c73bbc0ca203d0dc8dad4008350bbe5797b" uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.3.1+0" +version = "5.3.1+1" [[deps.MacroTools]] deps = ["Markdown", "Random"] -git-tree-sha1 = "9ee1618cbf5240e6d4e0371d6f24065083f60c48" +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.11" +version = "0.5.13" [[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "35fa3c150cd96fd77417a23965b7037b90d6ffc9" +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "a37c6610dd20425b131caf65d52abdf859da5ab1" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.19.12" +version = "0.20.4" [[deps.MakieCore]] deps = ["Observables", "REPL"] -git-tree-sha1 = "9b11acd07f21c4d035bd4156e789532e8ee2cc70" +git-tree-sha1 = "ec5db7bb2dc9b85072658dcb2d3ad09569b09ac9" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.6.9" +version = "0.7.2" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -1137,16 +1135,10 @@ deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[deps.MathTeXEngine]] -deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "Test", "UnicodeFun"] -git-tree-sha1 = "8f52dbaa1351ce4cb847d95568cb29e62a307d93" +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] +git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.5.6" - -[[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "f512dc13e64e96f703fd92ce617755ee6b5adf0f" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.8" +version = "0.5.7" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] @@ -1181,9 +1173,9 @@ uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" version = "1.1.7" [[deps.Mods]] -git-tree-sha1 = "61be59e4daffff43a8cec04b5e0dc773cbb5db3a" +git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" -version = "1.3.3" +version = "2.2.4" [[deps.MosaicViews]] deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] @@ -1202,9 +1194,9 @@ version = "0.4.4" [[deps.NCDatasets]] deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "7fcb4378f9c648a186bcb996fa29acc929a179ed" +git-tree-sha1 = "173a378f357e9bb24b22019efb5e4778223ce8cf" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.13.1" +version = "0.13.2" [[deps.NLSolversBase]] deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] @@ -1214,9 +1206,9 @@ version = "7.8.3" [[deps.NVTX]] deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] -git-tree-sha1 = "8bc9ce4233be3c63f8dcd78ccaf1b63a9c0baa34" +git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" -version = "0.3.3" +version = "0.3.4" [[deps.NVTX_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1253,11 +1245,11 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "eeca396589a53c957bcf5a9847e02c2eb915fe29" +git-tree-sha1 = "117d0d9331a738ded226eb702a7d30e3ab348dc6" repo-rev = "glw/better-interpolate2" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.4" +version = "0.90.5" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -1266,10 +1258,13 @@ version = "0.90.4" EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" [[deps.OffsetArrays]] -deps = ["Adapt"] -git-tree-sha1 = "2ac17d29c523ce1cd38e27785a7d23024853a4bb" +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.12.10" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" [[deps.Ogg_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1301,15 +1296,9 @@ version = "0.8.1+2" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] -git-tree-sha1 = "694458ae803b684f09c07f90459cb79655fb377d" +git-tree-sha1 = "1d1421618bab0e820bdc7ae1a2b46ce576981273" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.0+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.1" +version = "5.0.1+0" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1336,9 +1325,9 @@ uuid = "91d4177d-7536-5919-b921-800302f37372" version = "1.3.2+0" [[deps.OrderedCollections]] -git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.2" +version = "1.6.3" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] @@ -1347,9 +1336,9 @@ version = "10.42.0+1" [[deps.PDMats]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "f6f85a2edb9c356b829934ad3caed2ad0ebbfc99" +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.29" +version = "0.11.31" [[deps.PMIx_jll]] deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] @@ -1359,9 +1348,9 @@ version = "4.2.7+0" [[deps.PNGFiles]] deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] -git-tree-sha1 = "5ded86ccaf0647349231ed6c0822c10886d4a1ee" +git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" -version = "0.4.1" +version = "0.4.3" [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" @@ -1389,15 +1378,15 @@ version = "0.12.3" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "a935806434c9d4c506ba941871b327b96d41f2bf" +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.0" +version = "2.8.1" [[deps.PencilArrays]] deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] -git-tree-sha1 = "1a473d028436947e08436275ff3fcc2f3e9c5b06" +git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.2" +version = "0.19.3" [deps.PencilArrays.extensions] PencilArraysDiffEqExt = ["DiffEqBase"] @@ -1415,9 +1404,15 @@ version = "0.15.1" [[deps.Permutations]] deps = ["Combinatorics", "LinearAlgebra", "Random"] -git-tree-sha1 = "4f69b02cf40a0f494d0438ab29de32e14ef96e7b" +git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" -version = "0.4.18" +version = "0.4.20" + +[[deps.PikaParser]] +deps = ["DocStringExtensions"] +git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" +uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" +version = "0.6.1" [[deps.Pixman_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] @@ -1438,9 +1433,9 @@ version = "0.3.3" [[deps.PlotUtils]] deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] -git-tree-sha1 = "f92e1315dadf8c46561fb9396e525f7200cdc227" +git-tree-sha1 = "862942baf5663da528f66d24996eb6da85218e76" uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.3.5" +version = "1.4.0" [[deps.PolygonOps]] git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" @@ -1449,9 +1444,9 @@ version = "0.1.2" [[deps.Polynomials]] deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "5a95b69396b77fdb2c48970a535610c4743810e2" +git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "4.0.5" +version = "4.0.6" [deps.Polynomials.extensions] PolynomialsChainRulesCoreExt = "ChainRulesCore" @@ -1490,10 +1485,10 @@ uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.1" [[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "6842ce83a836fbbc0cfeca0b5a4de1a4dcbdb8d1" +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.2.8" +version = "2.3.1" [[deps.Primes]] deps = ["IntegerMathUtils"] @@ -1525,15 +1520,15 @@ version = "1.0.0" [[deps.QuadGK]] deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9ebcd48c498668c7fa0e97a9cae873fbee7bfee1" +git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.9.1" +version = "2.9.4" [[deps.Quaternions]] deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "da095158bdc8eaccb7890f9884048555ab771019" +git-tree-sha1 = "9a46862d248ea548e340e30e2894118749dc7f51" uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.4" +version = "0.7.5" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] @@ -1545,9 +1540,9 @@ uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[deps.Random123]] deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "552f30e847641591ba3f39fd1bed559b9deb0ef3" +git-tree-sha1 = "c860e84651f58ce240dd79e5d9e055d55234c35a" uuid = "74087812-796a-5b5d-8853-05524746bad3" -version = "1.6.1" +version = "1.6.2" [[deps.RandomNumbers]] deps = ["Random", "Requires"] @@ -1624,10 +1619,10 @@ uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" version = "0.4.1" [[deps.Roots]] -deps = ["ChainRulesCore", "CommonSolve", "Printf", "Setfield"] -git-tree-sha1 = "0f1d92463a020321983d04c110f476c274bafe2e" +deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] +git-tree-sha1 = "af540898b1e6ca7aa6ba7213c05052809c6c522a" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.0.22" +version = "2.1.0" [deps.Roots.extensions] RootsForwardDiffExt = "ForwardDiff" @@ -1711,28 +1706,23 @@ git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" version = "0.4.0" -[[deps.SimpleBufferStream]] -git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.1.0" - [[deps.SimpleGraphs]] deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] -git-tree-sha1 = "b608903049d11cc557c45e03b3a53e9260579c19" +git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" -version = "0.8.4" +version = "0.8.6" [[deps.SimplePartitions]] deps = ["AbstractLattices", "DataStructures", "Permutations"] -git-tree-sha1 = "dcc02923a53f316ab97da8ef3136e80b4543dbf1" +git-tree-sha1 = "e9330391d04241eafdc358713b48396619c83bcb" uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" -version = "0.3.0" +version = "0.3.1" [[deps.SimplePolynomials]] deps = ["Mods", "Multisets", "Polynomials", "Primes"] -git-tree-sha1 = "d537c31cf9995236166e3e9afc424a5a1c59ff9d" +git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" -version = "0.2.14" +version = "0.2.17" [[deps.SimpleRandom]] deps = ["Distributions", "LinearAlgebra", "Random"] @@ -1757,9 +1747,9 @@ uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "5165dfb9fd131cf0c6957a3a7605dede376e7b63" +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.0" +version = "1.2.1" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] @@ -1777,10 +1767,10 @@ weakdeps = ["ChainRulesCore"] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" [[deps.StableHashTraits]] -deps = ["Compat", "SHA", "Tables", "TupleTools"] -git-tree-sha1 = "d29023a76780bb8a3f2273b29153fd00828cb73f" +deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "662f56ffe22b3985f3be7474f0aecbaf214ecf0f" uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" -version = "1.1.1" +version = "1.1.6" [[deps.StackViews]] deps = ["OffsetArrays"] @@ -1796,9 +1786,9 @@ version = "0.8.8" [[deps.StaticArrayInterface]] deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] -git-tree-sha1 = "03fec6800a986d191f64f5c0996b59ed526eda25" +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.4.1" +version = "1.5.0" weakdeps = ["OffsetArrays", "StaticArrays"] [deps.StaticArrayInterface.extensions] @@ -1806,13 +1796,14 @@ weakdeps = ["OffsetArrays", "StaticArrays"] StaticArrayInterfaceStaticArraysExt = "StaticArrays" [[deps.StaticArrays]] -deps = ["LinearAlgebra", "Random", "StaticArraysCore"] -git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "f68dd04d131d9a8a8eb836173ee8f105c360b0c5" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.6.5" -weakdeps = ["Statistics"] +version = "1.9.1" +weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" StaticArraysStatisticsExt = "Statistics" [[deps.StaticArraysCore]] @@ -1847,15 +1838,12 @@ deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Re git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" version = "1.3.0" +weakdeps = ["ChainRulesCore", "InverseFunctions"] [deps.StatsFuns.extensions] StatsFunsChainRulesCoreExt = "ChainRulesCore" StatsFunsInverseFunctionsExt = "InverseFunctions" - [deps.StatsFuns.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - [[deps.Strided]] deps = ["LinearAlgebra", "StridedViews", "TupleTools"] git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" @@ -1864,9 +1852,9 @@ version = "2.0.4" [[deps.StridedViews]] deps = ["LinearAlgebra", "PackageExtensionCompat"] -git-tree-sha1 = "cf857ff7de76f39e5daef6d032e8a74279ddff6a" +git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" -version = "0.2.1" +version = "0.2.2" weakdeps = ["CUDA"] [deps.StridedViews.extensions] @@ -1880,9 +1868,9 @@ version = "0.3.4" [[deps.StructArrays]] deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" +git-tree-sha1 = "1b0b1205a56dc288b71b1961d48e351520702e24" uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.16" +version = "0.6.17" [[deps.StructTypes]] deps = ["Dates", "UUIDs"] @@ -1899,12 +1887,6 @@ deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.0+1" -[[deps.SurfaceFluxes]] -deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] -path = "../../../SurfaceFluxes.jl" -uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.8.0" - [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" @@ -1929,9 +1911,9 @@ version = "1.10.0" [[deps.TaylorSeries]] deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] -git-tree-sha1 = "50718b4fc1ce20cecf28d85215028c78b4d875c2" +git-tree-sha1 = "9138fdc8ee4e3b8839eca696a76d15e16c9c7af0" uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.15.2" +version = "0.15.4" weakdeps = ["IntervalArithmetic"] [deps.TaylorSeries.extensions] @@ -1947,12 +1929,6 @@ version = "0.1.1" deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -[[deps.Thermodynamics]] -deps = ["DocStringExtensions", "KernelAbstractions", "Printf", "Random", "RootSolvers"] -path = "../../../Thermodynamics.jl" -uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.11.2" - [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" @@ -1966,10 +1942,13 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.23" [[deps.TranscodingStreams]] -deps = ["Random", "Test"] -git-tree-sha1 = "9a6ae7ed916312b41236fcef7e0af564ef934769" +git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.9.13" +version = "0.10.2" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] [[deps.TriplotBase]] git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" @@ -1981,11 +1960,6 @@ git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" version = "1.4.3" -[[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" @@ -2022,15 +1996,15 @@ version = "1.3.0" [[deps.WoodburyMatrices]] deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3" +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "0.5.5" +version = "1.0.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "24b81b59bd35b3c42ab84fa589086e19be919916" +git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.11.5+0" +version = "2.12.2+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] @@ -2169,10 +2143,10 @@ uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" version = "2.0.2+0" [[deps.libpng_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "93284c28274d9e75218a416c65ec49d0e0fcdf3d" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.38+0" +version = "1.6.40+0" [[deps.libsixel_jll]] deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml index 15628622..611b2bb2 100644 --- a/experiments/prototype_omip_simulation/Project.toml +++ b/experiments/prototype_omip_simulation/Project.toml @@ -1,5 +1,4 @@ [deps] -ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index 2638cee3..9f13ba2e 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -36,10 +36,10 @@ start_time = time_ns() ##### Construct the grid ##### -arch = CPU() +arch = GPU() -latitude = (-60, -50) -longitude = (300, 360) +latitude = (-75, -75) +longitude = (0, 360) i₁ = 4 * first(longitude) + 1 i₂ = 1440 - 4 * (360 - last(longitude)) From d09aa99df93de98a7c25a8e8fd258098bd3cf2cc Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 23 Jan 2024 16:24:33 -0700 Subject: [PATCH 064/182] Its condensation of course --- .../ocean_sea_ice_surface_fluxes.jl | 16 +++++----------- .../similarity_theory_turbulent_fluxes.jl | 16 +++++++++------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index aad20e56..6c10153a 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -228,7 +228,7 @@ end Tₐ = atmos_state.T[i, j, 1, time] pₐ = atmos_state.p[i, j, 1, time] - qᵗₐ = atmos_state.q[i, j, 1] # total specific humidity + qₐ = atmos_state.q[i, j, 1, time] # total specific humidity end # Build thermodynamic and dynamic states in the atmosphere and surface. @@ -237,7 +237,7 @@ end # ⋅ Φ ≡ "dynamic" state vector (thermodynamics + reference height + velocity) ℂ = atmosphere_thermodynamics_parameters hₐ = atmosphere_reference_height # elevation of atmos variables relative to surface - ϕₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₐ, qᵗₐ) + ϕₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₐ, qₐ) Φₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, ϕₐ) # Build surface state with saturated specific humidity @@ -273,15 +273,10 @@ end # Compute heat fluxes, bulk flux first Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation_properties) Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state, ocean_temperature_units) - Qc = conditions.shf # sensible or "conductive" heat flux - Qe = clip(conditions.lhf) # latent or "evaporative" heat flux + Qc = conditions.shf # sensible or "conductive" heat flux + Qe = conditions.lhf # latent or "evaporative" heat flux ΣQ = Qd + Qu + Qc + Qe - if i == j == 1 - @show conditions - @show propertynames(conditions) - end - # Accumulate freshwater fluxes. Rain, snow, runoff -- all freshwater. # Note these are mass fluxes, hence the "M". M = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) @@ -293,8 +288,7 @@ end # Apparently, conditions.evaporation is a mass flux of water. # So, we divide by the density of freshwater. - # But why do we need to clip evaporation rate? - E = clip(conditions.evaporation) / ρᶠ + E = conditions.evaporation / ρᶠ ΣF += E update_turbulent_flux_fields!(turbulent_fluxes.fields, i, j, grid, conditions, ρᶠ) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index adc4dd9b..faca8a2f 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -48,9 +48,13 @@ struct ClasiusClapyeronSaturation end return q★ end -Base.@kwdef struct LargeYeagerSaturation{FT} - c₁ :: FT = 640380.0 # kg m⁻³ - c₂ :: FT = 5107.4 # K +struct LargeYeagerSaturation{FT} + c₁ :: FT + c₂ :: FT +end + +function LargeYeagerSaturation(FT=Float64; c₁ = 640380, c₂ = 5107.4) + return LargeYeagerSaturation(convert(FT, c₁), convert(FT, c₂)) end const LYS = LargeYeagerSaturation @@ -101,8 +105,6 @@ end @inline update_turbulent_flux_fields!(::Nothing, args...) = nothing -@inline clip(x::FT) where FT = max(zero(FT), x) - @inline function update_turbulent_flux_fields!(fields, i, j, grid, conditions, ρᶠ) Qᵉ = fields.latent_heat_flux Qᶜ = fields.sensible_heat_flux @@ -111,12 +113,12 @@ end inactive = inactive_node(i, j, kᴺ, grid, c, c, c) @inbounds begin # +0: cooling, -0: heating - Qᵉ[i, j, 1] = ifelse(inactive, 0, clip(conditions.lhf)) + Qᵉ[i, j, 1] = ifelse(inactive, 0, conditions.lhf) Qᶜ[i, j, 1] = ifelse(inactive, 0, conditions.shf) # "Salt flux" has the opposite sign of "freshwater flux". # E > 0 implies that freshwater is fluxing upwards. - Eᵢ = clip(conditions.evaporation) / ρᶠ # convert to volume flux + Eᵢ = conditions.evaporation / ρᶠ # convert to volume flux E[i, j, 1] = ifelse(inactive, Eᵢ, 0) end return nothing From bff00b05de317e13ba8ff4a17fb94190e4392433 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 24 Jan 2024 13:13:05 -0700 Subject: [PATCH 065/182] Update default date for ecco2_field --- src/DataWrangling/ECCO2.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 4a014ae1..590a5a0d 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -132,7 +132,7 @@ shortnames = Dict( surface_variable(variable_name) = variable_name == :sea_ice_thickness -function ecco2_field(variable_name, date=Date(1992, 01, 01); +function ecco2_field(variable_name, date=Date(1992, 01, 02); architecture = CPU(), filename = filenames[string(date)][variable_name], url = urls[string(date)][variable_name], From 876879de9db44691b051b905063a2ef4f8ff3b71 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 24 Jan 2024 23:34:43 -0500 Subject: [PATCH 066/182] Fix chunked halo filling --- src/DataWrangling/JRA55.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index de19f289..1e4a2d30 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -290,12 +290,12 @@ function jra55_field_time_series(variable_name, grid=nothing; Nt = length(times) chunk_size = 100 if Nt <= chunk_size # one chunk will do - fill_halo_regions!(fts) + fill_halo_regions!(native_fts) else # need multiple chunks start = 1 while start < Nt stop = min(Nt, start + chunk_size - 1) - fts_chunk = Tuple(fts[n] for n = start:stop) + fts_chunk = Tuple(native_fts[n] for n = start:stop) fill_halo_regions!(fts_chunk) start += chunk_size end @@ -306,9 +306,7 @@ function jra55_field_time_series(variable_name, grid=nothing; else # make a new FieldTimeSeries and interpolate native data onto it. boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; boundary_conditions) - interpolate!(fts, native_fts) - return fts end end From 0c382d0660ae25e10ca488974c4f7f8307c02aed Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 26 Jan 2024 00:25:55 -0500 Subject: [PATCH 067/182] Add adapt method for similarity turbulent fluxes --- .../prototype_omip_simulation/Manifest.toml | 107 +++++++++++++++++- .../prototype_omip_simulation/Project.toml | 2 + .../regional_omip_simulation.jl | 10 +- .../similarity_theory_turbulent_fluxes.jl | 10 ++ 4 files changed, 122 insertions(+), 7 deletions(-) diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index ba947ca3..6329b20b 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0-beta3" manifest_format = "2.0" -project_hash = "6533489dd3ea9e5b8f9155148c8dcd78d68604f0" +project_hash = "a2a450f285334f2fe90a5a74f427515e12a6d318" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -122,6 +122,11 @@ version = "0.4.2" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" @@ -205,6 +210,12 @@ weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] ChainRulesCoreSparseArraysExt = "SparseArrays" +[[deps.ClimaOcean]] +deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +path = "../.." +uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +version = "0.1.0" + [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" @@ -213,6 +224,12 @@ repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.3" + [[deps.ColorBrewer]] deps = ["Colors", "JSON", "Test"] git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" @@ -293,6 +310,12 @@ weakdeps = ["InverseFunctions"] [deps.CompositionsBase.extensions] CompositionsBaseInverseFunctionsExt = "InverseFunctions" +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.3.0" + [[deps.ConstructionBase]] deps = ["LinearAlgebra"] git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" @@ -320,11 +343,23 @@ git-tree-sha1 = "253193dfb0384646936c5ff3230b27a20d91261e" uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" version = "0.2.4" +[[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 = "d481f6419c262edcb7294179bd63249d123eb081" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.12" + [[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" @@ -445,6 +480,12 @@ git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" version = "2.2.5" +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" @@ -678,6 +719,12 @@ 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 = "abbbb9ec3afd783a7cbd82ef01dcd088ea051398" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.1" + [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" @@ -1069,6 +1116,12 @@ version = "0.3.26" [[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.MKL_jll]] deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" @@ -1140,6 +1193,12 @@ git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" version = "0.5.7" +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" @@ -1245,9 +1304,7 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "117d0d9331a738ded226eb702a7d30e3ab348dc6" -repo-rev = "glw/better-interpolate2" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +path = "/home/greg/Projects/Oceananigans.jl" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.5" @@ -1300,6 +1357,12 @@ git-tree-sha1 = "1d1421618bab0e820bdc7ae1a2b46ce576981273" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" version = "5.0.1+0" +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.1" + [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" @@ -1706,6 +1769,11 @@ git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" version = "0.4.0" +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + [[deps.SimpleGraphs]] deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" @@ -1887,6 +1955,18 @@ deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.0+1" +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "6431256ee7c06ed2900fd46688f355e5a43e90eb" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.9.1" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "CLIMAParameters" + + [deps.SurfaceFluxes.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" @@ -1929,6 +2009,20 @@ version = "0.1.1" deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "f4555e1302df12011b836fbdcdd3e10e5df7329a" +repo-rev = "glw/density-example" +repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.11.5" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "CLIMAParameters" + + [deps.Thermodynamics.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" @@ -1960,6 +2054,11 @@ git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" version = "1.4.3" +[[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" diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml index 611b2bb2..3c31c917 100644 --- a/experiments/prototype_omip_simulation/Project.toml +++ b/experiments/prototype_omip_simulation/Project.toml @@ -1,4 +1,5 @@ [deps] +ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" @@ -6,3 +7,4 @@ GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index 9f13ba2e..d71047ec 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -1,4 +1,5 @@ using Oceananigans +using Oceananigans.Architectures: arch_array using Oceananigans.Units using Oceananigans.BuoyancyModels: buoyancy_frequency using Oceananigans.Units: Time @@ -8,7 +9,7 @@ using ClimaOcean.OceanSeaIceModels: Radiation using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere using ClimaOcean.DataWrangling.ECCO2: ecco2_field -using GLMakie +# using GLMakie using Printf using Dates @@ -38,7 +39,7 @@ start_time = time_ns() arch = GPU() -latitude = (-75, -75) +latitude = (-30, +30) longitude = (0, 360) i₁ = 4 * first(longitude) + 1 @@ -69,6 +70,9 @@ for i = 1:Nx, j = 1:Ny end end +Tᵢ = arch_array(arch, Tᵢ) +Sᵢ = arch_array(arch, Sᵢ) + @show Nx Ny Nz zf grid = LatitudeLongitudeGrid(arch; latitude, longitude, @@ -88,7 +92,7 @@ elapsed = time_ns() - start_time @info "Ocean component built. " * prettytime(elapsed * 1e-9) start_time = time_ns() -Ndays = 365 +Ndays = 3 Nt = 8 * Ndays atmosphere = jra55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) elapsed = time_ns() - start_time diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index faca8a2f..c81b2d47 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -1,6 +1,7 @@ using Oceananigans.Utils: prettysummary using Oceananigans.Grids: AbstractGrid +using Adapt using Thermodynamics: Liquid using SurfaceFluxes.Parameters: SurfaceFluxesParameters, AbstractSurfaceFluxesParameters using SurfaceFluxes.UniversalFunctions: BusingerParams @@ -38,6 +39,15 @@ uf_params(fluxes::STTF) = fluxes.universal_function von_karman_const(fluxes::STTF) = fluxes.von_karman_constant grav(fluxes::STTF) = fluxes.gravitational_acceleration +Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), + adapt(to, fluxes.von_karman_constant), + adapt(to, fluxes.bulk_velocity_scale), + adapt(to, fluxes.universal_function), + adapt(to, fluxes.thermodynamics_parameters), + adapt(to, fluxes.water_vapor_saturation), + adapt(to, fluxes.water_mole_fraction), + adapt(to, fluxes.fields)) + Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" struct ClasiusClapyeronSaturation end From 160358c95aee62b6786b9ab36f0d8fd5cd8bcb2c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 25 Jan 2024 22:27:57 -0700 Subject: [PATCH 068/182] Adds adapt method for TwoStreamRadiation --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 247096f8..96a1f1c2 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -2,6 +2,7 @@ module PrescribedAtmospheres using Oceananigans.Utils: prettysummary +using Adapt using Thermodynamics.Parameters: AbstractThermodynamicsParameters import Thermodynamics.Parameters: @@ -309,5 +310,9 @@ or sea ice. TwoStreamDownwellingRadiation(; shortwave=nothing, longwave=nothing) = TwoStreamDownwellingRadiation(shortwave, longwave) +Adapt.adapt_structure(to, tsdr::TwoStreamDownwellingRadiation) = + TwoStreamDownwellingRadiation(adapt(to, tsdr.shortwave), + adapt(to, tsdr.longwave)) + end # module From bc80140f5a50f56c21d0dae18903e53b6aabfc48 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 25 Jan 2024 22:47:24 -0700 Subject: [PATCH 069/182] Add functionality to compute R_v --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 96a1f1c2..f4515621 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -87,6 +87,7 @@ const CP = ConstitutiveParameters @inline gas_constant(p::CP) = p.gas_constant @inline molmass_dryair(p::CP) = p.dry_air_molar_mass @inline molmass_water(p::CP) = p.water_molar_mass +@inline R_v(p::CP) = gas_constant(p) / molmass_water(p) struct HeatCapacityParameters{FT} <: AbstractThermodynamicsParameters{FT} dry_air_adiabatic_exponent :: FT @@ -230,6 +231,7 @@ end const HTP = PrescribedAtmosphereThermodynamicsParameters +@inline R_v(p::HTP) = R_v(p.constitutive) @inline gas_constant(p::HTP) = gas_constant(p.constitutive) @inline molmass_dryair(p::HTP) = molmass_dryair(p.constitutive) @inline molmass_water(p::HTP) = molmass_water(p.constitutive) From 3a2e220f0f3e058c8df702dad90e2417c5f95a7f Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 25 Jan 2024 22:52:51 -0700 Subject: [PATCH 070/182] Import R_v into PrescribedAtmospheres --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index f4515621..82edc870 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -9,6 +9,7 @@ import Thermodynamics.Parameters: gas_constant, # molmass_dryair, # Molar mass of dry air (without moisture) molmass_water, # Molar mass of gaseous water vapor + R_v, # Specific gas constant for water vapor kappa_d, # Ideal gas adiabatic exponent for dry air T_0, # Enthalpy reference temperature LH_v0, # Vaporization enthalpy at the reference temperature From a2352a61bc549e58ef2c278077f2b8f4899eb38d Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 26 Jan 2024 06:50:52 -0700 Subject: [PATCH 071/182] Import R_d --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 82edc870..cc3892c4 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -10,6 +10,7 @@ import Thermodynamics.Parameters: molmass_dryair, # Molar mass of dry air (without moisture) molmass_water, # Molar mass of gaseous water vapor R_v, # Specific gas constant for water vapor + R_d, # Specific gas constant for dry air kappa_d, # Ideal gas adiabatic exponent for dry air T_0, # Enthalpy reference temperature LH_v0, # Vaporization enthalpy at the reference temperature @@ -89,6 +90,7 @@ const CP = ConstitutiveParameters @inline molmass_dryair(p::CP) = p.dry_air_molar_mass @inline molmass_water(p::CP) = p.water_molar_mass @inline R_v(p::CP) = gas_constant(p) / molmass_water(p) +@inline R_d(p::CP) = gas_constant(p) / molmass_dryair(p) struct HeatCapacityParameters{FT} <: AbstractThermodynamicsParameters{FT} dry_air_adiabatic_exponent :: FT @@ -232,6 +234,7 @@ end const HTP = PrescribedAtmosphereThermodynamicsParameters +@inline R_d(p::HTP) = R_d(p.constitutive) @inline R_v(p::HTP) = R_v(p.constitutive) @inline gas_constant(p::HTP) = gas_constant(p.constitutive) @inline molmass_dryair(p::HTP) = molmass_dryair(p.constitutive) From 34b897a8441fd53cc57261603cdb201a56d4964b Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 26 Jan 2024 07:09:27 -0700 Subject: [PATCH 072/182] Add the molmass ratio --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index cc3892c4..7940826c 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -9,6 +9,7 @@ import Thermodynamics.Parameters: gas_constant, # molmass_dryair, # Molar mass of dry air (without moisture) molmass_water, # Molar mass of gaseous water vapor + molmass_ratio, # Ratio of the molar masses of dry air to water vapor R_v, # Specific gas constant for water vapor R_d, # Specific gas constant for dry air kappa_d, # Ideal gas adiabatic exponent for dry air @@ -86,11 +87,12 @@ end const CP = ConstitutiveParameters -@inline gas_constant(p::CP) = p.gas_constant -@inline molmass_dryair(p::CP) = p.dry_air_molar_mass -@inline molmass_water(p::CP) = p.water_molar_mass -@inline R_v(p::CP) = gas_constant(p) / molmass_water(p) -@inline R_d(p::CP) = gas_constant(p) / molmass_dryair(p) +@inline gas_constant(p::CP) = p.gas_constant +@inline molmass_dryair(p::CP) = p.dry_air_molar_mass +@inline molmass_water(p::CP) = p.water_molar_mass +@inline molmass_ratio(p::CP) = molmass_dryair(p) / molmass_water(p) +@inline R_v(p::CP) = gas_constant(p) / molmass_water(p) +@inline R_d(p::CP) = gas_constant(p) / molmass_dryair(p) struct HeatCapacityParameters{FT} <: AbstractThermodynamicsParameters{FT} dry_air_adiabatic_exponent :: FT @@ -239,6 +241,7 @@ const HTP = PrescribedAtmosphereThermodynamicsParameters @inline gas_constant(p::HTP) = gas_constant(p.constitutive) @inline molmass_dryair(p::HTP) = molmass_dryair(p.constitutive) @inline molmass_water(p::HTP) = molmass_water(p.constitutive) +@inline molmass_ratio(p::HTP) = molmass_ratio(p.constitutive) @inline kappa_d(p::HTP) = kappa_d(p.heat_capacity) @inline LH_v0(p::HTP) = LH_v0(p.phase_transitions) @inline LH_s0(p::HTP) = LH_s0(p.phase_transitions) From 06b4e5f665591a9dc1abbc4b7c2723e4def902bf Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:03:28 -0500 Subject: [PATCH 073/182] Offload JRA55 on disk --- src/DataWrangling/JRA55.jl | 111 ++++++++++++++++++++++++++++++++----- 1 file changed, 98 insertions(+), 13 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 1e4a2d30..3b453a48 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -281,36 +281,121 @@ function jra55_field_time_series(variable_name, grid=nothing; topology = (TX, Bounded, Flat)) boundary_conditions = FieldBoundaryConditions(jra55_native_grid, (Center, Center, Nothing)) + + grid = isnothing(grid) ? jra55_native_grid : grid + loc = (LX, LY, Nothing) + + fts = retrieve_and_maybe_write_jra55_data(time_chunks_in_memory, grid, times, loc, boundary_conditions, data, jra55_native_grid; + interpolated_file, shortname) + + return fts +end + +""" + retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_conditions, data, jra55_native_grid; + interpolated_file = nothing, shortname = nothing) + +Retrieve JRA55 data and optionally write it to a file in an Oceananigans compatible format. + +## Arguments +- `chunks`: Chunk size for the in-memory backend of the `FieldTimeSeries`. +- `grid`: Grid for the `FieldTimeSeries`. +- `times`: Time values for the `FieldTimeSeries`. +- `loc`: Location of the JRA55 data. +- `boundary_conditions`: Boundary conditions for the `FieldTimeSeries`. +- `data`: JRA55 data to be retrieved. +- `jra55_native_grid`: Native grid of the JRA55 data. +- `interpolated_file`: Optional. Path to the file where the interpolated data will be written. +- `shortname`: Optional. Shortname for the interpolated data. + +## Returns +- `fts`: `FieldTimeSeries` object containing the retrieved or interpolated data. + +If `interpolated_file` is not a `Nothing`: +(1) If the `interpolated_file` does not exist, the JRA55 data will be written to the file in an Oceananigans compatible format. +(2) If the `interpolated_file` exists but is on a different grid, the file will be deleted and rewritten. +(3) If the `shortname` is already present in the file, the data will not be written again. +""" +function retrieve_and_maybe_write_jra55_data(::Nothing, grid, times, loc, boundary_conditions, data, jra55_native_grid; kwargs...) native_fts = FieldTimeSeries{Center, Center, Nothing}(jra55_native_grid, times; boundary_conditions) # Fill the data in a GPU-friendly manner copyto!(interior(native_fts, :, :, 1, :), data[:, :, :]) # Fill halo regions so we can interpolate to finer grids - Nt = length(times) - chunk_size = 100 - if Nt <= chunk_size # one chunk will do - fill_halo_regions!(native_fts) - else # need multiple chunks - start = 1 - while start < Nt - stop = min(Nt, start + chunk_size - 1) - fts_chunk = Tuple(native_fts[n] for n = start:stop) - fill_halo_regions!(fts_chunk) - start += chunk_size - end - end + fill_halo_regions!(native_fts) if isnothing(grid) return native_fts else # make a new FieldTimeSeries and interpolate native data onto it. boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; boundary_conditions) + interpolate!(fts, native_fts) + return fts end end +function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_conditions, data, jra55_native_grid; + interpolated_file = nothing, + shortname = nothing) + + if !isfile(interpolated_file) # File does not exist, let's rewrite it + + @info "rewriting the jra55 data into an Oceananigans compatible format" + write_jra55_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + + elseif jldopen(interpolated_file)["serialized/grid"] != grid # File is there but on another grid, remove it and rewrite it + + @info "the saved boundary data is on another grid, deleting the old boundary file" + rm(interpolated_file; force=true) + + @info "rewriting the jra55 data into an Oceananigans compatible format" + write_jra55_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + + else # File is there and on the correct grid + if shortname ∈ keys(interpolated_file["timeseries"]) # `shortname` is not in the file + write_jra55_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + end + + # File is there and `shortname` is in the file + end + + fts = FieldTimeSeries(interpolated_file, shortname; backend = InMemory(; chunk_size = chunks)) + return fts +end + +""" + write_jra55_timeseries!(data, loc, grid, times, path, name, bcs, jra55_native_grid) + +Write JRA55 timeseries `data` to disk in `path` under `name` +""" +function write_jra55_timeseries!(data, loc, grid, times, path, name, bcs, jra55_native_grid) + + dims = length(size(data)) - 1 + spatial_indices = Tuple(Colon() for i in 1:dims) + + native_field = Field{Center, Center, Nothing}(jra55_native_grid) + + f_tmp = Field{loc...}(grid) + fts_tmp = FieldTimeSeries(loc, grid, times; + backend = OnDisk(), + path, + name, + boundary_conditions = bcs) + + for t in eachindex(times) + set!(native_field, data[spatial_indices..., t]) + fill_halo_regions!(native_field) + interpolate!(f_tmp, native_field) + fill_halo_regions!(f_tmp) + set!(fts_tmp, f_tmp, t) + end + + return nothing +end + # TODO: allow the user to pass dates function jra55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # meters architecture = Oceananigans.architecture(grid) From 88cc9bd4dae69005b4561d2ce761f7a26f69f054 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:05:50 -0500 Subject: [PATCH 074/182] docstring --- src/DataWrangling/JRA55.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 3b453a48..fb5ac9fa 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -344,7 +344,7 @@ function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_ if !isfile(interpolated_file) # File does not exist, let's rewrite it @info "rewriting the jra55 data into an Oceananigans compatible format" - write_jra55_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) elseif jldopen(interpolated_file)["serialized/grid"] != grid # File is there but on another grid, remove it and rewrite it @@ -352,11 +352,11 @@ function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_ rm(interpolated_file; force=true) @info "rewriting the jra55 data into an Oceananigans compatible format" - write_jra55_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) else # File is there and on the correct grid if shortname ∈ keys(interpolated_file["timeseries"]) # `shortname` is not in the file - write_jra55_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) end # File is there and `shortname` is in the file @@ -367,16 +367,16 @@ function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_ end """ - write_jra55_timeseries!(data, loc, grid, times, path, name, bcs, jra55_native_grid) + interpolate_and_write_timeseries!(data, loc, grid, times, path, name, bcs, native_grid) -Write JRA55 timeseries `data` to disk in `path` under `name` +Interpolates and writes a time series of `data` at `times` onto disk in an Oceananigans compatible format. """ -function write_jra55_timeseries!(data, loc, grid, times, path, name, bcs, jra55_native_grid) +function interpolate_and_write_timeseries!(data, loc, grid, times, path, name, bcs, native_grid) dims = length(size(data)) - 1 spatial_indices = Tuple(Colon() for i in 1:dims) - native_field = Field{Center, Center, Nothing}(jra55_native_grid) + native_field = Field{Center, Center, Nothing}(native_grid) f_tmp = Field{loc...}(grid) fts_tmp = FieldTimeSeries(loc, grid, times; From 40d832dbfc97ec236dc4e88b18b2d0921428938b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:07:48 -0500 Subject: [PATCH 075/182] fix --- src/DataWrangling/JRA55.jl | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index fb5ac9fa..fd243e50 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -149,14 +149,22 @@ Keyword arguments - `shortname`: The "short name" of `variable_name` inside its NetCDF file. Default: `ClimaOcean.JRA55.shortnames[variable_name]`. + + - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. + If it does not exist it will be generated. + + - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is + loaded (not recommended). """ function jra55_field_time_series(variable_name, grid=nothing; - architecture = CPU(), - location = nothing, - time_indices = :, - url = nothing, - filename = nothing, - shortname = nothing) + architecture = CPU(), + location = nothing, + time_indices = :, + url = nothing, + filename = nothing, + shortname = nothing, + interpolated_file = "jra55_boundary_conditions.jld2", + time_chunks_in_memory = nothing) if isnothing(filename) && !(variable_name ∈ jra55_variable_names) variable_strs = Tuple(" - :$name \n" for name in jra55_variable_names) From 09cec7ab83060eeeddf8ef4c793e4b0cf4d400d8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:17:09 -0500 Subject: [PATCH 076/182] alignment --- src/DataWrangling/JRA55.jl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index fd243e50..a9b6170d 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -157,14 +157,14 @@ Keyword arguments loaded (not recommended). """ function jra55_field_time_series(variable_name, grid=nothing; - architecture = CPU(), - location = nothing, - time_indices = :, - url = nothing, - filename = nothing, - shortname = nothing, - interpolated_file = "jra55_boundary_conditions.jld2", - time_chunks_in_memory = nothing) + architecture = CPU(), + location = nothing, + time_indices = :, + url = nothing, + filename = nothing, + shortname = nothing, + interpolated_file = "jra55_boundary_conditions.jld2", + time_chunks_in_memory = nothing) if isnothing(filename) && !(variable_name ∈ jra55_variable_names) variable_strs = Tuple(" - :$name \n" for name in jra55_variable_names) From 340c6ff687a59104e6e962033828dca4f9f4b627 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:25:01 -0500 Subject: [PATCH 077/182] bugs fixed --- src/DataWrangling/JRA55.jl | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index a9b6170d..8e73a983 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -12,6 +12,7 @@ using ClimaOcean.OceanSeaIceModels: TwoStreamDownwellingRadiation using NCDatasets +using JLD2 # A list of all variables provided in the JRA55 dataset: jra55_variable_names = (:freshwater_river_flux, @@ -345,6 +346,7 @@ function retrieve_and_maybe_write_jra55_data(::Nothing, grid, times, loc, bounda end end +# TODO: check also the time indices function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_conditions, data, jra55_native_grid; interpolated_file = nothing, shortname = nothing) @@ -353,24 +355,32 @@ function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_ @info "rewriting the jra55 data into an Oceananigans compatible format" interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + end + + file = jldopen(interpolated_file) - elseif jldopen(interpolated_file)["serialized/grid"] != grid # File is there but on another grid, remove it and rewrite it + if file["serialized/grid"] != grid # File exists but the data is on another grid, remove it and rewrite it + close(file) @info "the saved boundary data is on another grid, deleting the old boundary file" rm(interpolated_file; force=true) @info "rewriting the jra55 data into an Oceananigans compatible format" interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) - else # File is there and on the correct grid - if shortname ∈ keys(interpolated_file["timeseries"]) # `shortname` is not in the file + else # File exists and the data is on the correct grid + + if shortname ∈ keys(file["timeseries"]) # `shortname` is not in the file + close(file) interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) end - # File is there and `shortname` is in the file + # File is there and `shortname` is in the file (probably the time indices are not there) + # check_time_indices!(args...) end fts = FieldTimeSeries(interpolated_file, shortname; backend = InMemory(; chunk_size = chunks)) + return fts end From e64cfb7798af6e8ade6913ecc1604237985f9a5b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:25:32 -0500 Subject: [PATCH 078/182] more info --- src/DataWrangling/JRA55.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 8e73a983..af6862e5 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -372,6 +372,8 @@ function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_ if shortname ∈ keys(file["timeseries"]) # `shortname` is not in the file close(file) + + @info "rewriting the jra55 data into an Oceananigans compatible format" interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) end @@ -380,7 +382,7 @@ function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_ end fts = FieldTimeSeries(interpolated_file, shortname; backend = InMemory(; chunk_size = chunks)) - + return fts end From 3f35743d5f3eb4bbf3aca218088d7537b5b997a2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:33:23 -0500 Subject: [PATCH 079/182] last fix --- src/DataWrangling/JRA55.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index af6862e5..c253e593 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -370,7 +370,7 @@ function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_ else # File exists and the data is on the correct grid - if shortname ∈ keys(file["timeseries"]) # `shortname` is not in the file + if !(shortname ∈ keys(file["timeseries"])) # `shortname` is not in the file close(file) @info "rewriting the jra55 data into an Oceananigans compatible format" From 515b288716246f1d4dfe0760e9b7c35c2f0fe6bc Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jan 2024 11:33:59 -0500 Subject: [PATCH 080/182] coment --- src/DataWrangling/JRA55.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index c253e593..e1f3ff96 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -377,7 +377,8 @@ function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_ interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) end - # File is there and `shortname` is in the file (probably the time indices are not there) + # File is there and `shortname` is in the file (probably the time indices are not correct) + # TODO: check the time range includes the time range of the simulation # check_time_indices!(args...) end From e0c0a9e04ed2ca06e301a54e0835d0e256113932 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sat, 27 Jan 2024 09:13:39 -0700 Subject: [PATCH 081/182] Add cp_d --- .../PrescribedAtmospheres.jl | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 7940826c..d694c518 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -12,6 +12,7 @@ import Thermodynamics.Parameters: molmass_ratio, # Ratio of the molar masses of dry air to water vapor R_v, # Specific gas constant for water vapor R_d, # Specific gas constant for dry air + cp_d, # Heat capacity of dry air at constant pressure kappa_d, # Ideal gas adiabatic exponent for dry air T_0, # Enthalpy reference temperature LH_v0, # Vaporization enthalpy at the reference temperature @@ -234,26 +235,27 @@ function PrescribedAtmosphereThermodynamicsParameters(FT = Float64; return PrescribedAtmosphereThermodynamicsParameters(constitutive, heat_capacity, phase_transitions) end -const HTP = PrescribedAtmosphereThermodynamicsParameters - -@inline R_d(p::HTP) = R_d(p.constitutive) -@inline R_v(p::HTP) = R_v(p.constitutive) -@inline gas_constant(p::HTP) = gas_constant(p.constitutive) -@inline molmass_dryair(p::HTP) = molmass_dryair(p.constitutive) -@inline molmass_water(p::HTP) = molmass_water(p.constitutive) -@inline molmass_ratio(p::HTP) = molmass_ratio(p.constitutive) -@inline kappa_d(p::HTP) = kappa_d(p.heat_capacity) -@inline LH_v0(p::HTP) = LH_v0(p.phase_transitions) -@inline LH_s0(p::HTP) = LH_s0(p.phase_transitions) -@inline cp_v(p::HTP) = cp_v(p.heat_capacity) -@inline cp_l(p::HTP) = cp_l(p.heat_capacity) -@inline cp_i(p::HTP) = cp_i(p.heat_capacity) -@inline T_freeze(p::HTP) = T_freeze(p.phase_transitions) -@inline T_triple(p::HTP) = T_triple(p.phase_transitions) -@inline T_icenuc(p::HTP) = T_icenuc(p.phase_transitions) -@inline pow_icenuc(p::HTP) = pow_icenuc(p.phase_transitions) -@inline press_triple(p::HTP) = press_triple(p.phase_transitions) -@inline T_0(p::HTP) = T_0(p.phase_transitions) +const PATP = PrescribedAtmosphereThermodynamicsParameters + +@inline R_d(p::PATP) = R_d(p.constitutive) +@inline R_v(p::PATP) = R_v(p.constitutive) +@inline kappa_d(p::PATP) = kappa_d(p.heat_capacity) +@inline gas_constant(p::PATP) = gas_constant(p.constitutive) +@inline molmass_dryair(p::PATP) = molmass_dryair(p.constitutive) +@inline molmass_water(p::PATP) = molmass_water(p.constitutive) +@inline molmass_ratio(p::PATP) = molmass_ratio(p.constitutive) +@inline LH_v0(p::PATP) = LH_v0(p.phase_transitions) +@inline LH_s0(p::PATP) = LH_s0(p.phase_transitions) +@inline cp_d(p::PATP) = R_d(p) / kappa_d(p) +@inline cp_v(p::PATP) = cp_v(p.heat_capacity) +@inline cp_l(p::PATP) = cp_l(p.heat_capacity) +@inline cp_i(p::PATP) = cp_i(p.heat_capacity) +@inline T_freeze(p::PATP) = T_freeze(p.phase_transitions) +@inline T_triple(p::PATP) = T_triple(p.phase_transitions) +@inline T_icenuc(p::PATP) = T_icenuc(p.phase_transitions) +@inline pow_icenuc(p::PATP) = pow_icenuc(p.phase_transitions) +@inline press_triple(p::PATP) = press_triple(p.phase_transitions) +@inline T_0(p::PATP) = T_0(p.phase_transitions) ##### ##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic) From 9832d2ee96cef6eb702457ead17702ef77a2eca2 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sat, 27 Jan 2024 09:59:55 -0700 Subject: [PATCH 082/182] Try to fix JRA55.jl --- src/DataWrangling/JRA55.jl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index e1f3ff96..038a0f6c 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -294,12 +294,32 @@ function jra55_field_time_series(variable_name, grid=nothing; grid = isnothing(grid) ? jra55_native_grid : grid loc = (LX, LY, Nothing) + #= fts = retrieve_and_maybe_write_jra55_data(time_chunks_in_memory, grid, times, loc, boundary_conditions, data, jra55_native_grid; interpolated_file, shortname) + =# + + native_fts = FieldTimeSeries{Center, Center, Nothing}(jra55_native_grid, times; boundary_conditions) + + # Fill the data in a GPU-friendly manner + copyto!(interior(native_fts, :, :, 1, :), data[:, :, :]) + + # Fill halo regions so we can interpolate to finer grids + fill_halo_regions!(native_fts) + + if isnothing(grid) + return native_fts + else # make a new FieldTimeSeries and interpolate native data onto it. + boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) + fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; boundary_conditions) + interpolate!(fts, native_fts) + return fts + end return fts end +#= """ retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_conditions, data, jra55_native_grid; interpolated_file = nothing, shortname = nothing) @@ -416,6 +436,7 @@ function interpolate_and_write_timeseries!(data, loc, grid, times, path, name, b return nothing end +=# # TODO: allow the user to pass dates function jra55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # meters From 7092553523039a17e1fbc546afce9430c57f5d8a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sat, 27 Jan 2024 10:34:29 -0700 Subject: [PATCH 083/182] Add cv_v --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index d694c518..dbb2ec94 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -13,6 +13,7 @@ import Thermodynamics.Parameters: R_v, # Specific gas constant for water vapor R_d, # Specific gas constant for dry air cp_d, # Heat capacity of dry air at constant pressure + cv_v, # Heat capacity of dry air at constant volume kappa_d, # Ideal gas adiabatic exponent for dry air T_0, # Enthalpy reference temperature LH_v0, # Vaporization enthalpy at the reference temperature @@ -246,7 +247,6 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters @inline molmass_ratio(p::PATP) = molmass_ratio(p.constitutive) @inline LH_v0(p::PATP) = LH_v0(p.phase_transitions) @inline LH_s0(p::PATP) = LH_s0(p.phase_transitions) -@inline cp_d(p::PATP) = R_d(p) / kappa_d(p) @inline cp_v(p::PATP) = cp_v(p.heat_capacity) @inline cp_l(p::PATP) = cp_l(p.heat_capacity) @inline cp_i(p::PATP) = cp_i(p.heat_capacity) @@ -257,6 +257,9 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters @inline press_triple(p::PATP) = press_triple(p.phase_transitions) @inline T_0(p::PATP) = T_0(p.phase_transitions) +@inline cp_d(p::PATP) = R_d(p) / kappa_d(p) +@inline cv_v(p::PATP) = cp_v(p) - R_v(p) + ##### ##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic) ##### From ef0915440c707d55952be861d5e0d0068f21eeef Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sat, 27 Jan 2024 13:56:32 -0700 Subject: [PATCH 084/182] Add some more accessor functions --- .../PrescribedAtmospheres.jl | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index dbb2ec94..61a4cdf9 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -12,15 +12,17 @@ import Thermodynamics.Parameters: molmass_ratio, # Ratio of the molar masses of dry air to water vapor R_v, # Specific gas constant for water vapor R_d, # Specific gas constant for dry air - cp_d, # Heat capacity of dry air at constant pressure - cv_v, # Heat capacity of dry air at constant volume kappa_d, # Ideal gas adiabatic exponent for dry air T_0, # Enthalpy reference temperature LH_v0, # Vaporization enthalpy at the reference temperature LH_s0, # Sublimation enthalpy at the reference temperature + cp_d, # Heat capacity of dry air at constant pressure cp_v, # Isobaric specific heat capacity of gaseous water vapor cp_l, # Isobaric specific heat capacity of liquid water cp_i, # Isobaric specific heat capacity of water ice + cv_v, # Heat capacity of dry air at constant volume + cv_l, # Isobaric specific heat capacity of liquid water + cv_i, # Isobaric specific heat capacity of liquid water T_freeze, # Freezing temperature of _pure_ water T_triple, # Triple point temperature of _pure_ water press_triple, # Triple point pressure of pure water @@ -138,6 +140,8 @@ const HCP = HeatCapacityParameters @inline cp_v(p::HCP) = p.water_vapor_heat_capacity @inline cp_l(p::HCP) = p.liquid_water_heat_capacity @inline cp_i(p::HCP) = p.water_ice_heat_capacity +@inline cv_l(p::PATP) = cp_l(p) +@inline cv_i(p::PATP) = cp_i(p) @inline kappa_d(p::HCP) = p.dry_air_adiabatic_exponent struct PhaseTransitionParameters{FT} <: AbstractThermodynamicsParameters{FT} @@ -240,16 +244,12 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters @inline R_d(p::PATP) = R_d(p.constitutive) @inline R_v(p::PATP) = R_v(p.constitutive) -@inline kappa_d(p::PATP) = kappa_d(p.heat_capacity) @inline gas_constant(p::PATP) = gas_constant(p.constitutive) @inline molmass_dryair(p::PATP) = molmass_dryair(p.constitutive) @inline molmass_water(p::PATP) = molmass_water(p.constitutive) @inline molmass_ratio(p::PATP) = molmass_ratio(p.constitutive) @inline LH_v0(p::PATP) = LH_v0(p.phase_transitions) @inline LH_s0(p::PATP) = LH_s0(p.phase_transitions) -@inline cp_v(p::PATP) = cp_v(p.heat_capacity) -@inline cp_l(p::PATP) = cp_l(p.heat_capacity) -@inline cp_i(p::PATP) = cp_i(p.heat_capacity) @inline T_freeze(p::PATP) = T_freeze(p.phase_transitions) @inline T_triple(p::PATP) = T_triple(p.phase_transitions) @inline T_icenuc(p::PATP) = T_icenuc(p.phase_transitions) @@ -257,7 +257,17 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters @inline press_triple(p::PATP) = press_triple(p.phase_transitions) @inline T_0(p::PATP) = T_0(p.phase_transitions) + +@inline cp_v(p::PATP) = cp_v(p.heat_capacity) +@inline cp_l(p::PATP) = cp_l(p.heat_capacity) +@inline cp_i(p::PATP) = cp_i(p.heat_capacity) + +@inline cv_l(p::PATP) = cv_l(p.heat_capacity) +@inline cv_i(p::PATP) = cv_i(p.heat_capacity) + +@inline kappa_d(p::PATP) = kappa_d(p.heat_capacity) @inline cp_d(p::PATP) = R_d(p) / kappa_d(p) +@inline cv_d(p::PATP) = cp_d(p) - R_d(p) @inline cv_v(p::PATP) = cp_v(p) - R_v(p) ##### From c0c1c50de892c219538086c73ec148a9dcc57e72 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sat, 27 Jan 2024 14:16:17 -0700 Subject: [PATCH 085/182] Fix bug PrescribedAtmospheres --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 61a4cdf9..03388fc1 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -140,8 +140,8 @@ const HCP = HeatCapacityParameters @inline cp_v(p::HCP) = p.water_vapor_heat_capacity @inline cp_l(p::HCP) = p.liquid_water_heat_capacity @inline cp_i(p::HCP) = p.water_ice_heat_capacity -@inline cv_l(p::PATP) = cp_l(p) -@inline cv_i(p::PATP) = cp_i(p) +@inline cv_l(p::HCP) = cp_l(p) +@inline cv_i(p::HCP) = cp_i(p) @inline kappa_d(p::HCP) = p.dry_air_adiabatic_exponent struct PhaseTransitionParameters{FT} <: AbstractThermodynamicsParameters{FT} From 0710e96fd328423f8ee474065d915947c46ced18 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sun, 28 Jan 2024 18:36:56 -0700 Subject: [PATCH 086/182] Add e_int_v0 --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 03388fc1..3320b67c 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -23,6 +23,7 @@ import Thermodynamics.Parameters: cv_v, # Heat capacity of dry air at constant volume cv_l, # Isobaric specific heat capacity of liquid water cv_i, # Isobaric specific heat capacity of liquid water + e_int_v0, # what? someting about reference internal energy of water vapor T_freeze, # Freezing temperature of _pure_ water T_triple, # Triple point temperature of _pure_ water press_triple, # Triple point pressure of pure water @@ -257,6 +258,7 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters @inline press_triple(p::PATP) = press_triple(p.phase_transitions) @inline T_0(p::PATP) = T_0(p.phase_transitions) +@inline e_int_v0(p::PATP) = LH_v0(p) - R_v(p) * T_0(p) @inline cp_v(p::PATP) = cp_v(p.heat_capacity) @inline cp_l(p::PATP) = cp_l(p.heat_capacity) From dfb97509702990966f2c4f562a66b5ff9fcb9a3a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sun, 28 Jan 2024 18:47:42 -0700 Subject: [PATCH 087/182] Add LH_f0 --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 3320b67c..a35c3cc9 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -16,6 +16,7 @@ import Thermodynamics.Parameters: T_0, # Enthalpy reference temperature LH_v0, # Vaporization enthalpy at the reference temperature LH_s0, # Sublimation enthalpy at the reference temperature + LH_f0, # Fusionn enthalpy at the reference temperature cp_d, # Heat capacity of dry air at constant pressure cp_v, # Isobaric specific heat capacity of gaseous water vapor cp_l, # Isobaric specific heat capacity of liquid water @@ -189,6 +190,7 @@ end const PTP = PhaseTransitionParameters @inline LH_v0(p::PTP) = p.reference_vaporization_enthalpy @inline LH_s0(p::PTP) = p.reference_sublimation_enthalpy +@inline LH_f0(p::PTP) = LH_s0(p) - p.LH_v0 @inline T_freeze(p::PTP) = p.water_freezing_temperature @inline T_triple(p::PTP) = p.triple_point_temperature @inline T_icenuc(p::PTP) = p.total_ice_nucleation_temperature @@ -251,6 +253,7 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters @inline molmass_ratio(p::PATP) = molmass_ratio(p.constitutive) @inline LH_v0(p::PATP) = LH_v0(p.phase_transitions) @inline LH_s0(p::PATP) = LH_s0(p.phase_transitions) +@inline LH_f0(p::PATP) = LH_f0(p.phase_transitions) @inline T_freeze(p::PATP) = T_freeze(p.phase_transitions) @inline T_triple(p::PATP) = T_triple(p.phase_transitions) @inline T_icenuc(p::PATP) = T_icenuc(p.phase_transitions) From 41c68fc0b1d3d4cf79aeb69391d3324395ccea46 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sun, 28 Jan 2024 20:26:12 -0700 Subject: [PATCH 088/182] Fix bug in PrescribedAtmospheres --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index a35c3cc9..0821c75e 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -190,7 +190,7 @@ end const PTP = PhaseTransitionParameters @inline LH_v0(p::PTP) = p.reference_vaporization_enthalpy @inline LH_s0(p::PTP) = p.reference_sublimation_enthalpy -@inline LH_f0(p::PTP) = LH_s0(p) - p.LH_v0 +@inline LH_f0(p::PTP) = LH_s0(p) - LH_v0(p) @inline T_freeze(p::PTP) = p.water_freezing_temperature @inline T_triple(p::PTP) = p.triple_point_temperature @inline T_icenuc(p::PTP) = p.total_ice_nucleation_temperature From 63f0c5d71125d08f1b93d2dd430df6de9cf43658 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sun, 28 Jan 2024 20:41:00 -0700 Subject: [PATCH 089/182] inline getter functions for SimilarityTurbulentFluxes --- .../similarity_theory_turbulent_fluxes.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index c81b2d47..651ba1fb 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -33,11 +33,11 @@ struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, F} <: AbstractSurf end const STTF = SimilarityTheoryTurbulentFluxes -thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters -universal_func_type(fluxes::STTF) = universal_func_type(typeof(fluxes.universal_function)) -uf_params(fluxes::STTF) = fluxes.universal_function -von_karman_const(fluxes::STTF) = fluxes.von_karman_constant -grav(fluxes::STTF) = fluxes.gravitational_acceleration +@inline thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters +@inline universal_func_type(fluxes::STTF) = universal_func_type(typeof(fluxes.universal_function)) +@inline uf_params(fluxes::STTF) = fluxes.universal_function +@inline von_karman_const(fluxes::STTF) = fluxes.von_karman_constant +@inline grav(fluxes::STTF) = fluxes.gravitational_acceleration Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), adapt(to, fluxes.von_karman_constant), From 012813799b19e3ce671e57af589a512671967926 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sun, 28 Jan 2024 21:01:33 -0700 Subject: [PATCH 090/182] Make universal_func_type non-dynamic --- .../CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 651ba1fb..c3017ea0 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -34,11 +34,12 @@ end const STTF = SimilarityTheoryTurbulentFluxes @inline thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters -@inline universal_func_type(fluxes::STTF) = universal_func_type(typeof(fluxes.universal_function)) @inline uf_params(fluxes::STTF) = fluxes.universal_function @inline von_karman_const(fluxes::STTF) = fluxes.von_karman_constant @inline grav(fluxes::STTF) = fluxes.gravitational_acceleration +@inline universal_func_type(fluxes::STTF{<:Any, <:Any, UF}) where UF = universal_func_type(UF) + Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), adapt(to, fluxes.von_karman_constant), adapt(to, fluxes.bulk_velocity_scale), From 7826a93b51cfa02faea5caba7e96b9114c09544a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sun, 28 Jan 2024 21:16:09 -0700 Subject: [PATCH 091/182] Hard code BusingerType --- .../CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index c3017ea0..8fd453e9 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -4,7 +4,7 @@ using Oceananigans.Grids: AbstractGrid using Adapt using Thermodynamics: Liquid using SurfaceFluxes.Parameters: SurfaceFluxesParameters, AbstractSurfaceFluxesParameters -using SurfaceFluxes.UniversalFunctions: BusingerParams +using SurfaceFluxes.UniversalFunctions: BusingerParams, BusingerType using ..PrescribedAtmospheres: PrescribedAtmosphereThermodynamicsParameters @@ -38,7 +38,7 @@ const STTF = SimilarityTheoryTurbulentFluxes @inline von_karman_const(fluxes::STTF) = fluxes.von_karman_constant @inline grav(fluxes::STTF) = fluxes.gravitational_acceleration -@inline universal_func_type(fluxes::STTF{<:Any, <:Any, UF}) where UF = universal_func_type(UF) +@inline universal_func_type(fluxes::STTF{<:Any, <:Any, <:BusingerParams}) = BusingerType() Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), adapt(to, fluxes.von_karman_constant), From 2d7e90dd04f09e07e37cd640a34f39552f4add83 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 11:34:37 -0500 Subject: [PATCH 092/182] Update packages --- Manifest.toml | 14 ++--- .../regional_omip_simulation.jl | 53 +++++++++++-------- .../similarity_theory_turbulent_fluxes.jl | 22 ++++---- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 5b8090be..4b2f72e1 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0-rc1" +julia_version = "1.10.0-beta3" manifest_format = "2.0" project_hash = "bcfc95e502c18276c6e7315f722ad6f48d7698c2" @@ -573,7 +573,7 @@ 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" +version = "8.0.1+1" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -741,11 +741,9 @@ 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 = "117d0d9331a738ded226eb702a7d30e3ab348dc6" -repo-rev = "glw/better-interpolate2" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +git-tree-sha1 = "ead1d8ec6911ff84ef52c387c827553bbc859c1b" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.5" +version = "0.90.6" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -975,8 +973,6 @@ version = "1.2.1" [[deps.SeawaterPolynomials]] git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" -repo-rev = "main" -repo-url = "https://github.com/CliMA/SeawaterPolynomials.jl.git" uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" version = "0.3.4" @@ -1114,7 +1110,7 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" +version = "7.2.0+1" [[deps.SurfaceFluxes]] deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index d71047ec..ca0410a0 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -39,7 +39,7 @@ start_time = time_ns() arch = GPU() -latitude = (-30, +30) +latitude = (-60, +60) longitude = (0, 360) i₁ = 4 * first(longitude) + 1 @@ -121,6 +121,11 @@ start_time = time_ns() wall_clock = Ref(time_ns()) +Nz = size(grid, 3) +Ts = view(ocean.model.tracers.T, :, :, Nz) +Ss = view(ocean.model.tracers.S, :, :, Nz) +es = view(ocean.model.tracers.e, :, :, Nz) + function progress(sim) msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) @@ -131,15 +136,11 @@ function progress(sim) u, v, w = sim.model.ocean.model.velocities msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + #= T = sim.model.ocean.model.tracers.T S = sim.model.ocean.model.tracers.S e = sim.model.ocean.model.tracers.e - τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) - τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) - u★ = (τˣ^2 + τʸ^2)^(1/4) - Q = first(sim.model.fluxes.total.ocean.heat) - Nz = size(T, 3) msg *= @sprintf(", u★: %.2f m s⁻¹", u★) msg *= @sprintf(", Q: %.2f W m⁻²", Q) @@ -147,6 +148,7 @@ function progress(sim) msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) + =# @info msg end @@ -154,35 +156,41 @@ end coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) # Build flux outputs -Jᵘ = coupled_model.fluxes.total.ocean.momentum.u -Jᵛ = coupled_model.fluxes.total.ocean.momentum.v -Jᵀ = coupled_model.fluxes.total.ocean.tracers.T -F = coupled_model.fluxes.total.ocean.tracers.S -E = coupled_model.fluxes.turbulent.fields.evaporation -Qse = coupled_model.fluxes.turbulent.fields.sensible_heat_flux -Qla = coupled_model.fluxes.turbulent.fields.latent_heat_flux -ρₒ = coupled_model.fluxes.ocean_reference_density -cₚ = coupled_model.fluxes.ocean_heat_capacity - -Q = ρₒ * cₚ * Jᵀ +Jᵘ = coupled_model.fluxes.total.ocean.momentum.u +Jᵛ = coupled_model.fluxes.total.ocean.momentum.v +Jᵀ = coupled_model.fluxes.total.ocean.tracers.T +Jˢ = coupled_model.fluxes.total.ocean.tracers.S +Fv = coupled_model.fluxes.turbulent.fields.freshwater +Qc = coupled_model.fluxes.turbulent.fields.sensible_heat +Qv = coupled_model.fluxes.turbulent.fields.latent_heat +ρₒ = coupled_model.fluxes.ocean_reference_density +cₚ = coupled_model.fluxes.ocean_heat_capacity + +ΣQ = ρₒ * cₚ * Jᵀ τˣ = ρₒ * Jᵘ τʸ = ρₒ * Jᵛ N² = buoyancy_frequency(ocean.model) κᶜ = ocean.model.diffusivity_fields.κᶜ -fluxes = (; τˣ, τʸ, E, F, Q, Qse, Qla) +fluxes = (; τˣ, τʸ, Fv, Jˢ, ΣQ, Qc, Qv) auxiliary_fields = (; N², κᶜ) fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) # Slice fields at the surface +#outputs = merge(fields, fluxes) outputs = merge(fields, fluxes) filename = "regional_omip_simulation" -coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, - schedule = TimeInterval(3hours), - overwrite_existing = true) +coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, fluxes; filename * "_fluxes", + schedule = TimeInterval(1day), + overwrite_existing = true) + +coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; filename * "_fields", + indices = (:, :, Nz), + schedule = TimeInterval(1day), + overwrite_existing = true) #= coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, @@ -190,5 +198,6 @@ coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs overwrite_existing = true) =# -# run!(coupled_simulation) +run!(coupled_simulation) + diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 8fd453e9..52756a5c 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -105,11 +105,11 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; end function SimilarityTheoryTurbulentFluxes(grid::AbstractGrid; kw...) - evaporation = Field{Center, Center, Nothing}(grid) - latent_heat_flux = Field{Center, Center, Nothing}(grid) - sensible_heat_flux = Field{Center, Center, Nothing}(grid) + freshwater = Field{Center, Center, Nothing}(grid) + latent_heat = Field{Center, Center, Nothing}(grid) + sensible_heat = Field{Center, Center, Nothing}(grid) - fields = (; latent_heat_flux, sensible_heat_flux, evaporation) + fields = (; latent_heat, sensible_heat, freshwater) return SimilarityTheoryTurbulentFluxes(eltype(grid); kw..., fields) end @@ -117,20 +117,20 @@ end @inline update_turbulent_flux_fields!(::Nothing, args...) = nothing @inline function update_turbulent_flux_fields!(fields, i, j, grid, conditions, ρᶠ) - Qᵉ = fields.latent_heat_flux - Qᶜ = fields.sensible_heat_flux - E = fields.evaporation + Qv = fields.latent_heat + Qc = fields.sensible_heat + Fv = fields.freshwater kᴺ = size(grid, 3) # index of the top ocean cell inactive = inactive_node(i, j, kᴺ, grid, c, c, c) @inbounds begin # +0: cooling, -0: heating - Qᵉ[i, j, 1] = ifelse(inactive, 0, conditions.lhf) - Qᶜ[i, j, 1] = ifelse(inactive, 0, conditions.shf) + Qv[i, j, 1] = ifelse(inactive, 0, conditions.lhf) + Qc[i, j, 1] = ifelse(inactive, 0, conditions.shf) # "Salt flux" has the opposite sign of "freshwater flux". # E > 0 implies that freshwater is fluxing upwards. - Eᵢ = conditions.evaporation / ρᶠ # convert to volume flux - E[i, j, 1] = ifelse(inactive, Eᵢ, 0) + Fvᵢ = conditions.evaporation / ρᶠ # convert to volume flux + Fv[i, j, 1] = ifelse(inactive, Fvᵢ, 0) end return nothing end From 5dee8052d827b12dbeb1c149b0e7282d7c82a52b Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Mon, 29 Jan 2024 19:17:09 +0200 Subject: [PATCH 093/182] update variable names --- .../single_column_omip_simulation.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 94746a9e..d1103e23 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -194,9 +194,9 @@ for location in keys(locations) Jᵛ = coupled_model.fluxes.total.ocean.momentum.v Jᵀ = coupled_model.fluxes.total.ocean.tracers.T F = coupled_model.fluxes.total.ocean.tracers.S - E = coupled_model.fluxes.turbulent.fields.evaporation - Qse = coupled_model.fluxes.turbulent.fields.sensible_heat_flux - Qla = coupled_model.fluxes.turbulent.fields.latent_heat_flux + E = coupled_model.fluxes.turbulent.fields.freshwater + Qse = coupled_model.fluxes.turbulent.fields.sensible_heat + Qla = coupled_model.fluxes.turbulent.fields.latent_heat ρₒ = coupled_model.fluxes.ocean_reference_density cₚ = coupled_model.fluxes.ocean_heat_capacity From 68cf30b71474d941d5f13d615b5fc04ed3d5dfb2 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Mon, 29 Jan 2024 19:19:30 +0200 Subject: [PATCH 094/182] =?UTF-8?q?F=20->=20J=CB=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../single_column_omip_simulation.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index d1103e23..da8a35ca 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -193,7 +193,7 @@ for location in keys(locations) Jᵘ = coupled_model.fluxes.total.ocean.momentum.u Jᵛ = coupled_model.fluxes.total.ocean.momentum.v Jᵀ = coupled_model.fluxes.total.ocean.tracers.T - F = coupled_model.fluxes.total.ocean.tracers.S + Jˢ = coupled_model.fluxes.total.ocean.tracers.S E = coupled_model.fluxes.turbulent.fields.freshwater Qse = coupled_model.fluxes.turbulent.fields.sensible_heat Qla = coupled_model.fluxes.turbulent.fields.latent_heat @@ -219,7 +219,7 @@ for location in keys(locations) "Q" => Dict("long_name" => "Net heat flux", "units" => "W / m^2", "convention" => "positive upwards"), "Qla" => Dict("long_name" => "Latent heat flux", "units" => "W / m^2", "convention" => "positive upwards"), "Qse" => Dict("long_name" => "Sensible heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "F" => Dict("long_name" => "Salt flux", "units" => "g kg⁻¹ m s⁻¹", "convention" => "positive upwards"), + "Jˢ" => Dict("long_name" => "Salt flux", "units" => "g kg⁻¹ m s⁻¹", "convention" => "positive upwards"), "E" => Dict("long_name" => "Freshwater evaporation flux", "units" => "m s⁻¹", "convention" => "positive upwards"), "e" => Dict("long_name" => "Turbulent kinetic energy", "units" => "m^2 / s^2"), "τˣ" => Dict("long_name" => "Zonal momentum flux", "units" => "m^2 / s^2"), @@ -252,7 +252,7 @@ for location in keys(locations) Qt = FieldTimeSeries(filename, "Q") Qset = FieldTimeSeries(filename, "Qse") Qlat = FieldTimeSeries(filename, "Qla") - Ft = FieldTimeSeries(filename, "F") + Ft = FieldTimeSeries(filename, "Jˢ") Et = FieldTimeSeries(filename, "E") τˣt = FieldTimeSeries(filename, "τˣ") τʸt = FieldTimeSeries(filename, "τʸ") @@ -280,10 +280,10 @@ for location in keys(locations) for n = 1:Nt t = times[n] - uat[n] = ua[1, 1, 1, Time(t)] - vat[n] = va[1, 1, 1, Time(t)] - Tat[n] = Ta[1, 1, 1, Time(t)] - qat[n] = qa[1, 1, 1, Time(t)] + uat[n] = ua[1, 1, 1, Time(t)] + vat[n] = va[1, 1, 1, Time(t)] + Tat[n] = Ta[1, 1, 1, Time(t)] + qat[n] = qa[1, 1, 1, Time(t)] Qswt[n] = Qsw[1, 1, 1, Time(t)] Qlwt[n] = Qlw[1, 1, 1, Time(t)] Pt[n] = Pr[1, 1, 1, Time(t)] + Ps[1, 1, 1, Time(t)] From a50598fb15cc8430fda7df4c614418d5c755dbd2 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Mon, 29 Jan 2024 19:28:45 +0200 Subject: [PATCH 095/182] =?UTF-8?q?some=20more=20F=20->=20J=CB=A2=20+=20fi?= =?UTF-8?q?x=20NC=20output=5Fattributes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../single_column_omip_simulation.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index da8a35ca..49fb6f82 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -206,7 +206,7 @@ for location in keys(locations) N² = buoyancy_frequency(ocean.model) κᶜ = ocean.model.diffusivity_fields.κᶜ - fluxes = (; τˣ, τʸ, E, F, Q, Qse, Qla) + fluxes = (; τˣ, τʸ, E, Jˢ, Q, Qse, Qla) auxiliary_fields = (; N², κᶜ) fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) @@ -214,7 +214,7 @@ for location in keys(locations) # Slice fields at the surface outputs = merge(fields, fluxes) - output_attributes = Dict( + output_attributes = Dict{String, Any}( "κᶜ" => Dict("long_name" => "Tracer diffusivity", "units" => "m^2 / s"), "Q" => Dict("long_name" => "Net heat flux", "units" => "W / m^2", "convention" => "positive upwards"), "Qla" => Dict("long_name" => "Latent heat flux", "units" => "W / m^2", "convention" => "positive upwards"), @@ -252,7 +252,7 @@ for location in keys(locations) Qt = FieldTimeSeries(filename, "Q") Qset = FieldTimeSeries(filename, "Qse") Qlat = FieldTimeSeries(filename, "Qla") - Ft = FieldTimeSeries(filename, "Jˢ") + Jˢt = FieldTimeSeries(filename, "Jˢ") Et = FieldTimeSeries(filename, "E") τˣt = FieldTimeSeries(filename, "τˣ") τʸt = FieldTimeSeries(filename, "τʸ") @@ -350,7 +350,7 @@ for location in keys(locations) vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) axislegend(axQ) - #lines!(axF, times, interior(Ft, 1, 1, 1, :), label="Net freshwater flux") + #lines!(axF, times, interior(Jˢt, 1, 1, 1, :), label="Net freshwater flux") lines!(axF, times, Pt, label="Prescribed freshwater flux") lines!(axF, times, - interior(Et, 1, 1, 1, :), label="Evaporation") vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) From cb3190f73b69c5355d526edb554dfa151e62aef5 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Mon, 29 Jan 2024 19:32:03 +0200 Subject: [PATCH 096/182] Makie new syntax: Figure(resolution=...) -> Figure(size=...) --- examples/generate_bathymetry.jl | 4 ++-- examples/inspect_JRA55_data.jl | 2 +- examples/inspect_ecco2_data.jl | 2 +- .../inspect_one_degree_near_global_simulation.jl | 2 +- experiments/prototype_omip_simulation/omip_simulation.jl | 2 +- .../single_column_omip_simulation.jl | 4 ++-- experiments/prototype_omip_simulation/surface_fluxes.jl | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 64ebc579..5ded7e62 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -20,7 +20,7 @@ h = regrid_bathymetry(grid, height_above_water=1, minimum_depth=5) land = interior(h) .> 0 interior(h)[land] .= NaN -fig = Figure(resolution=(2400, 1200)) +fig = Figure(size=(2400, 1200)) ax = Axis(fig[1, 1]) heatmap!(ax, λ, φ, interior(h, :, :, 1), nan_color=:white, colorrange=(-5000, 0)) @@ -49,7 +49,7 @@ h = regrid_bathymetry(grid, height_above_water=1) land = interior(h) .> 0 interior(h)[land] .= NaN -fig = Figure(resolution=(2400, 1200)) +fig = Figure(size=(2400, 1200)) ax = Axis(fig[1, 1]) heatmap!(ax, λ, φ, interior(h, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) diff --git a/examples/inspect_JRA55_data.jl b/examples/inspect_JRA55_data.jl index f4f031ea..1c1f0ccb 100644 --- a/examples/inspect_JRA55_data.jl +++ b/examples/inspect_JRA55_data.jl @@ -32,7 +32,7 @@ n = Observable(1) Qswn = @lift interior(Qswt[$n], :, :, 1) rhn = @lift interior(rht[$n], :, :, 1) -fig = Figure(resolution=(1400, 700)) +fig = Figure(size=(1400, 700)) axsw = Axis3(fig[1, 1], aspect=(1, 1, 1)) axrh = Axis3(fig[1, 2], aspect=(1, 1, 1)) diff --git a/examples/inspect_ecco2_data.jl b/examples/inspect_ecco2_data.jl index def71eab..4c61392b 100644 --- a/examples/inspect_ecco2_data.jl +++ b/examples/inspect_ecco2_data.jl @@ -35,7 +35,7 @@ Tp[Tp .< -10] .= NaN # We're ready to plot. We'll make an animation # that depicts how the ECCO2 data changes with depth. -fig = Figure(resolution=(1200, 1400)) +fig = Figure(size=(1200, 1400)) axT = Axis(fig[1, 1]) axS = Axis(fig[2, 1]) diff --git a/experiments/one_degree_simulations/inspect_one_degree_near_global_simulation.jl b/experiments/one_degree_simulations/inspect_one_degree_near_global_simulation.jl index 4fc09c47..13654f4e 100644 --- a/experiments/one_degree_simulations/inspect_one_degree_near_global_simulation.jl +++ b/experiments/one_degree_simulations/inspect_one_degree_near_global_simulation.jl @@ -33,7 +33,7 @@ grid = Tt.grid Nx, Ny, Nz = size(grid) Nt = length(times) -fig = Figure(resolution=(2400, 1800)) +fig = Figure(size=(2400, 1800)) ax_T = Axis(fig[2, 2], xlabel="Longitude", ylabel="Latitude") ax_S = Axis(fig[3, 2], xlabel="Longitude", ylabel="Latitude") diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 3affb45e..989560f6 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -248,7 +248,7 @@ end λc, φc, zc = nodes(Qt) λf, φf, zc = nodes(ζt) -fig = Figure(resolution=(2400, 1200)) +fig = Figure(size=(2400, 1200)) Nt = length(Tt.times) slider = Slider(fig[5, 2:3], range=1:Nt, startvalue=1) diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 49fb6f82..4b290f14 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -131,7 +131,7 @@ for location in keys(locations) times = ua.times #= - fig = Figure(resolution=(1200, 1800)) + fig = Figure(size=(1200, 1800)) axu = Axis(fig[1, 1]) axT = Axis(fig[2, 1]) axq = Axis(fig[3, 1]) @@ -291,7 +291,7 @@ for location in keys(locations) set_theme!(Theme(linewidth=3)) - fig = Figure(resolution=(2400, 1800)) + fig = Figure(size=(2400, 1800)) axτ = Axis(fig[1, 1:2], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") axu = Axis(fig[2, 1:2], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl index dce8678f..4d59c262 100644 --- a/experiments/prototype_omip_simulation/surface_fluxes.jl +++ b/experiments/prototype_omip_simulation/surface_fluxes.jl @@ -134,7 +134,7 @@ compute!(ΣQ) compute!(P) compute!(u★) -fig = Figure(resolution=(1200, 1800)) +fig = Figure(size=(1200, 1800)) axτ = Axis(fig[1, 1], title="u★") axT = Axis(fig[2, 1], title="T") From c4fdadb4b89a8d6827d094af8788788fd5818a30 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 10:56:53 -0700 Subject: [PATCH 097/182] Start working on JRA55 field time series on disk --- src/DataWrangling/JRA55.jl | 50 ++++++++++++++++++++++++++------------ test/test_jra55.jl | 27 +++++++++++++++++++- 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 038a0f6c..ec6c0f0f 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -155,17 +155,15 @@ Keyword arguments If it does not exist it will be generated. - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is - loaded (not recommended). + loaded (not recommended). """ function jra55_field_time_series(variable_name, grid=nothing; architecture = CPU(), location = nothing, - time_indices = :, url = nothing, filename = nothing, shortname = nothing, - interpolated_file = "jra55_boundary_conditions.jld2", - time_chunks_in_memory = nothing) + time_indices = 1:1) if isnothing(filename) && !(variable_name ∈ jra55_variable_names) variable_strs = Tuple(" - :$name \n" for name in jra55_variable_names) @@ -283,22 +281,15 @@ function jra55_field_time_series(variable_name, grid=nothing; stop_time = Δt * (Nt - 1) times = start_time:Δt:stop_time - jra55_native_grid = LatitudeLongitudeGrid(architecture, - size = (Nrx, Nry); + jra55_native_grid = LatitudeLongitudeGrid(architecture; + halo = (1, 1), + size = (Nrx, Nry), longitude = λr, latitude = φr, topology = (TX, Bounded, Flat)) boundary_conditions = FieldBoundaryConditions(jra55_native_grid, (Center, Center, Nothing)) - grid = isnothing(grid) ? jra55_native_grid : grid - loc = (LX, LY, Nothing) - - #= - fts = retrieve_and_maybe_write_jra55_data(time_chunks_in_memory, grid, times, loc, boundary_conditions, data, jra55_native_grid; - interpolated_file, shortname) - =# - native_fts = FieldTimeSeries{Center, Center, Nothing}(jra55_native_grid, times; boundary_conditions) # Fill the data in a GPU-friendly manner @@ -316,9 +307,36 @@ function jra55_field_time_series(variable_name, grid=nothing; return fts end + #= + if backend isa OnDisk +arch = CPU() +longname = :downwelling_shortwave_radiation +time_indices = 1:3 +jra55_fts = ClimaOcean.JRA55.jra55_field_time_series(longname; architecture=arch, time_indices) + +jld2_filename = string("JRA55_repeat_year_", longname, ".jld2") +shortname = :Qs +backend = OnDisk() +LX, LY, LZ = location(jra55_fts) + +Δt = 3hours # just what it is +Nt = 2920 # just what it is +start_time = 0 # Note: the forcing start at Jan 1 of the repeat year. +stop_time = Δt * (Nt - 1) +jra55_times = start_time:Δt:stop_time + +ondisk_fts = FieldTimeSeries{LX, LY, LZ}(jra55_fts.grid; backend, + path = jld2_filename, + name = shortname) + +set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) +=# + + return fts end + #= """ retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_conditions, data, jra55_native_grid; @@ -442,8 +460,8 @@ end function jra55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # meters architecture = Oceananigans.architecture(grid) - u_jra55 = jra55_field_time_series(:eastward_velocity, grid; time_indices, architecture, location=(Face, Center)) - v_jra55 = jra55_field_time_series(:northward_velocity, grid; time_indices, architecture, location=(Center, Face)) + u_jra55 = jra55_field_time_series(:eastward_velocity, grid; time_indices, architecture) + v_jra55 = jra55_field_time_series(:northward_velocity, grid; time_indices, architecture) T_jra55 = jra55_field_time_series(:temperature, grid; time_indices, architecture) q_jra55 = jra55_field_time_series(:specific_humidity, grid; time_indices, architecture) p_jra55 = jra55_field_time_series(:sea_level_pressure, grid; time_indices, architecture) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 6e686e4f..e77dffdb 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -1,5 +1,30 @@ include("runtests_setup.jl") +using Oceananigans.Units + +arch = CPU() +longname = :downwelling_shortwave_radiation +time_indices = 1:3 +jra55_fts = ClimaOcean.JRA55.jra55_field_time_series(longname; architecture=arch, time_indices) + +jld2_filename = string("JRA55_repeat_year_", longname, ".jld2") +shortname = :Qs +backend = OnDisk() +LX, LY, LZ = location(jra55_fts) + +Δt = 3hours # just what it is +Nt = 2920 # just what it is +start_time = 0 # Note: the forcing start at Jan 1 of the repeat year. +stop_time = Δt * (Nt - 1) +jra55_times = start_time:Δt:stop_time + +ondisk_fts = FieldTimeSeries{LX, LY, LZ}(jra55_fts.grid; backend, + path = jld2_filename, + name = shortname) + +set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) + +#= @testset "JRA55 and data wrangling utilities" begin for arch in test_architectures A = typeof(arch) @@ -79,4 +104,4 @@ include("runtests_setup.jl") rm(filepath) end end - +=# From 8bfa3007e04b9977abc161d13d484065b96ec3c7 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 10:57:43 -0700 Subject: [PATCH 098/182] More work ondisk JRA55 --- src/DataWrangling/JRA55.jl | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index ec6c0f0f..1e83e1e1 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -309,28 +309,28 @@ function jra55_field_time_series(variable_name, grid=nothing; #= if backend isa OnDisk -arch = CPU() -longname = :downwelling_shortwave_radiation -time_indices = 1:3 -jra55_fts = ClimaOcean.JRA55.jra55_field_time_series(longname; architecture=arch, time_indices) - -jld2_filename = string("JRA55_repeat_year_", longname, ".jld2") -shortname = :Qs -backend = OnDisk() -LX, LY, LZ = location(jra55_fts) - -Δt = 3hours # just what it is -Nt = 2920 # just what it is -start_time = 0 # Note: the forcing start at Jan 1 of the repeat year. -stop_time = Δt * (Nt - 1) -jra55_times = start_time:Δt:stop_time - -ondisk_fts = FieldTimeSeries{LX, LY, LZ}(jra55_fts.grid; backend, - path = jld2_filename, - name = shortname) - -set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) -=# + longname = :downwelling_shortwave_radiation + time_indices = 1:3 + jra55_fts = ClimaOcean.JRA55.jra55_field_time_series(longname; architecture=arch, time_indices) + + jld2_filename = string("JRA55_repeat_year_", longname, ".jld2") + shortname = :Qs + backend = OnDisk() + LX, LY, LZ = location(jra55_fts) + + Δt = 3hours # just what it is + Nt = 2920 # just what it is + start_time = 0 # Note: the forcing start at Jan 1 of the repeat year. + stop_time = Δt * (Nt - 1) + jra55_times = start_time:Δt:stop_time + + ondisk_fts = FieldTimeSeries{LX, LY, LZ}(jra55_fts.grid; backend, + path = jld2_filename, + name = shortname) + + set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) + end + =# return fts From a21ae076cdafacb12021969eac07431cc3ac805b Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 12:35:31 -0700 Subject: [PATCH 099/182] Add preprocessing ability to JRA55 time series --- src/DataWrangling/JRA55.jl | 323 ++++++++++++++++++++++--------------- 1 file changed, 196 insertions(+), 127 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 1e83e1e1..34602495 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -2,9 +2,9 @@ module JRA55 using Oceananigans using Oceananigans.Units - + using Oceananigans.BoundaryConditions: fill_halo_regions! -using Oceananigans.Grids: λnodes, φnodes +using Oceananigans.Grids: λnodes, φnodes, on_architecture using Oceananigans.Fields: interpolate! using ClimaOcean.OceanSeaIceModels: @@ -15,7 +15,7 @@ using NCDatasets using JLD2 # A list of all variables provided in the JRA55 dataset: -jra55_variable_names = (:freshwater_river_flux, +JRA55_variable_names = (:freshwater_river_flux, :rain_freshwater_flux, :snow_freshwater_flux, :freshwater_iceberg_flux, @@ -43,7 +43,7 @@ filenames = Dict( :northward_velocity => "RYF.vas.1990_1991.nc", # Northward near-surface wind ) -shortnames = Dict( +jra55_short_names = Dict( :freshwater_river_flux => "friver", # Freshwater fluxes from rivers :rain_freshwater_flux => "prra", # Freshwater flux from rainfall :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall @@ -58,6 +58,21 @@ shortnames = Dict( :northward_velocity => "vas", # Northward near-surface wind ) +field_time_series_short_names = Dict( + :freshwater_river_flux => :Fri, # Freshwater fluxes from rivers + :rain_freshwater_flux => :Fra, # Freshwater flux from rainfall + :snow_freshwater_flux => :Fsn, # Freshwater flux from snowfall + :freshwater_iceberg_flux => :Fic, # Freshwater flux from calving icebergs + :specific_humidity => :qa, # Surface specific humidity + :sea_level_pressure => :pa, # Sea level pressure + :relative_humidity => :rh, # Surface relative humidity + :downwelling_longwave_radiation => :Ql, # Downwelling longwave radiation + :downwelling_shortwave_radiation => :Qs, # Downwelling shortwave radiation + :temperature => :Ta, # Near-surface air temperature + :eastward_velocity => :ua, # Eastward near-surface wind + :northward_velocity => :va, # Northward near-surface wind +) + urls = Dict( :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", @@ -99,13 +114,66 @@ urls = Dict( "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", ) +function compute_bounding_indices(grid, LX, LY, λc, φc) + + Nx = length(λc) + Ny = length(φc) + + if isnothing(grid) + i₁, i₂ = (1, Nx) + j₁, j₂ = (1, Ny) + TX = Periodic + else # only load the data we need + # Nodes where we need to find data + λg = λnodes(grid, LX()) + φg = φnodes(grid, LY()) + + λ₁, λ₂ = extrema(λg) + φ₁, φ₂ = extrema(φg) + + # The following should work. If ᵒ are the extrema of nodes we want to + # interpolate to, and the following is a sketch of the JRA55 native grid, + # + # 1 2 3 4 5 + # | | | | | | + # | x ᵒ | x | x | x ᵒ | x | + # | | | | | | + # 1 2 3 4 5 6 + # + # then for example, we should find that (iᵢ, i₂) = (1, 5). + # So we want to reduce the first index by one, and limit them + # both by the available data. There could be some mismatch due + # to the use of different coordinate systems (ie whether λ ∈ (0, 360) + # which we may also need to handle separately. + + i₁ = searchsortedfirst(λc, λ₁) + j₁ = searchsortedfirst(φc, φ₁) + + i₂ = searchsortedfirst(λc, λ₂) + j₂ = searchsortedfirst(φc, φ₂) + + i₁ = max(1, i₁ - 1) + j₁ = max(1, j₁ - 1) + + i₂ = min(Nx, i₂) + j₂ = min(Ny, j₂) + + TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded + end + + return i₁, i₂, j₁, j₂, TX +end + + + """ - jra55_field_time_series(variable_name; + JRA55_field_time_series(variable_name; architecture = CPU(), - time_indices = :, + backend = InMemory(), + time_indices = nothing, url = urls[name], filename = filenames[variable_name], - shortname = shortnames[variable_name]) + shortname = jra55_short_names[variable_name]) Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, which describes one of the variables in the "repeat year forcing" dataset derived @@ -149,7 +217,7 @@ Keyword arguments Default: `ClimaOcean.JRA55.filenames[variable_name]`. - `shortname`: The "short name" of `variable_name` inside its NetCDF file. - Default: `ClimaOcean.JRA55.shortnames[variable_name]`. + Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. If it does not exist it will be generated. @@ -157,16 +225,19 @@ Keyword arguments - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is loaded (not recommended). """ -function jra55_field_time_series(variable_name, grid=nothing; +function JRA55_field_time_series(variable_name; #, grid=nothing; architecture = CPU(), location = nothing, url = nothing, filename = nothing, shortname = nothing, - time_indices = 1:1) + backend = InMemory() + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) - if isnothing(filename) && !(variable_name ∈ jra55_variable_names) - variable_strs = Tuple(" - :$name \n" for name in jra55_variable_names) + if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) + variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) variables_msg = prod(variable_strs) msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', @@ -176,7 +247,7 @@ function jra55_field_time_series(variable_name, grid=nothing; throw(ArgumentError(msg)) end - isnothing(shortname) && (shortname = shortnames[variable_name]) + isnothing(shortname) && (shortname = jra55_short_names[variable_name]) !isnothing(filename) && !isfile(filename) && isnothing(url) && throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ @@ -186,7 +257,7 @@ function jra55_field_time_series(variable_name, grid=nothing; isnothing(filename) && (filename = filenames[variable_name]) isnothing(url) && (url = urls[variable_name]) isfile(filename) || download(url, filename) - + # Get location if isnothing(location) LX = LY = Center @@ -194,6 +265,8 @@ function jra55_field_time_series(variable_name, grid=nothing; LX, LY = location end + totally_in_memory = backend isa InMemory{Nothing} + ds = Dataset(filename) # Note that each file should have the variables @@ -217,55 +290,22 @@ function jra55_field_time_series(variable_name, grid=nothing; push!(φn, 90) push!(λn, λn[1] + 360) - times = ds["time"][time_indices] - - Nx = length(λc) - Ny = length(φc) - - if isnothing(grid) - i₁, i₂ = (1, Nx) - j₁, j₂ = (1, Ny) - TX = Periodic - else # only load the data we need - # Nodes where we need to find data - λg = λnodes(grid, LX()) - φg = φnodes(grid, LY()) - - λ₁, λ₂ = extrema(λg) - φ₁, φ₂ = extrema(φg) - - # The following should work. If ᵒ are the extrema of nodes we want to - # interpolate to, and the following is a sketch of the JRA55 native grid, - # - # 1 2 3 4 5 - # | | | | | | - # | x ᵒ | x | x | x ᵒ | x | - # | | | | | | - # 1 2 3 4 5 6 - # - # then for example, we should find that (iᵢ, i₂) = (1, 5). - # So we want to reduce the first index by one, and limit them - # both by the available data. There could be some mismatch due - # to the use of different coordinate systems (ie whether λ ∈ (0, 360) - # which we may also need to handle separately. - - i₁ = searchsortedfirst(λc, λ₁) - j₁ = searchsortedfirst(φc, φ₁) - - i₂ = searchsortedfirst(λc, λ₂) - j₂ = searchsortedfirst(φc, φ₂) - - i₁ = max(1, i₁ - 1) - j₁ = max(1, j₁ - 1) - - i₂ = min(Nx, i₂) - j₂ = min(Ny, j₂) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(grid, LX, LY, λc, φc) - TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded + # Extract variable data + if totally_in_memory + # Set a sensible default + isnothing(time_indices) && (time_indices = 1:1) + time_indices_in_memory = time_indices + native_fts_architecture = architecture + else + isnothing(time_indices) && (time_indices = :) + time_indices_in_memory = 1:preprocess_chunk_size + native_fts_architecture = preprocess_architecture end - # Extract variable data - data = ds[shortname][i₁:i₂, j₁:j₂, time_indices] + times = ds["time"][time_indices_in_memory] + data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] φr = φn[j₁:j₂+1] Nrx, Nry, Nt = size(data) @@ -281,65 +321,94 @@ function jra55_field_time_series(variable_name, grid=nothing; stop_time = Δt * (Nt - 1) times = start_time:Δt:stop_time - jra55_native_grid = LatitudeLongitudeGrid(architecture; + JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture; halo = (1, 1), size = (Nrx, Nry), longitude = λr, latitude = φr, topology = (TX, Bounded, Flat)) - boundary_conditions = FieldBoundaryConditions(jra55_native_grid, (Center, Center, Nothing)) + boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) - native_fts = FieldTimeSeries{Center, Center, Nothing}(jra55_native_grid, times; boundary_conditions) + native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; boundary_conditions) # Fill the data in a GPU-friendly manner copyto!(interior(native_fts, :, :, 1, :), data[:, :, :]) - - # Fill halo regions so we can interpolate to finer grids fill_halo_regions!(native_fts) + #= if isnothing(grid) - return native_fts + fts = native_fts else # make a new FieldTimeSeries and interpolate native data onto it. boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; boundary_conditions) interpolate!(fts, native_fts) - return fts end + =# - #= - if backend isa OnDisk - longname = :downwelling_shortwave_radiation - time_indices = 1:3 - jra55_fts = ClimaOcean.JRA55.jra55_field_time_series(longname; architecture=arch, time_indices) - - jld2_filename = string("JRA55_repeat_year_", longname, ".jld2") - shortname = :Qs - backend = OnDisk() - LX, LY, LZ = location(jra55_fts) - - Δt = 3hours # just what it is - Nt = 2920 # just what it is - start_time = 0 # Note: the forcing start at Jan 1 of the repeat year. - stop_time = Δt * (Nt - 1) - jra55_times = start_time:Δt:stop_time - - ondisk_fts = FieldTimeSeries{LX, LY, LZ}(jra55_fts.grid; backend, + if backend isa InMemory{Nothing} + return native_fts + else # we're gonna save to disk! + @info "Processing JRA55 data and saving to disk..." + + fts_name = field_time_series_short_names[variable_name] + jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") + + ondisk_fts = FieldTimeSeries{LX, LY, LZ}(native_fts.grid; + backend = OnDisk(), path = jld2_filename, - name = shortname) - - set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) - end - =# + name = fts_name) + + # Re-open the dataset! + ds = Dataset(filename) + all_times = ds["time"][time_indices] + all_Nt = length(all_times) + chunk = last(preprocess_chunk_size) + + n = 1 # on disk + m = 1 # in memory + while n <= all_Nt + if n ∈ time_indices + m += 1 + else + # Update time_indices + time_indices_in_memory .+= preprocess_chunk_size + + # Clip time_indices if they extend past the end of the dataset + if last(time_indices_in_memory) > all_Nt + n₁ = first(time_indices_in_memory) + time_indices_in_memory = UnitRange(n₁, all_Nt) + end + + # Re-load .nc times and data + new_times = ds["time"][time_indices_in_memory] + native_fts.times .= new_times + + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + + m = 1 # reset + end + + set!(ondisk_fts, native_fts[m], n, native_fts.times[m]) + end + grid = on_architecture(architecture, JRA55_native_grid) - return fts -end + backend_fts = FieldTimeSeries{LX, LY, Nothing}(grid, all_times; + backend, + boundary_conditions, + path = jld2_filename, + name = fts_name) + return backend_fts + end +end #= """ - retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_conditions, data, jra55_native_grid; + retrieve_and_maybe_write_JRA55_data(chunks, grid, times, loc, boundary_conditions, data, JRA55_native_grid; interpolated_file = nothing, shortname = nothing) Retrieve JRA55 data and optionally write it to a file in an Oceananigans compatible format. @@ -351,7 +420,7 @@ Retrieve JRA55 data and optionally write it to a file in an Oceananigans compati - `loc`: Location of the JRA55 data. - `boundary_conditions`: Boundary conditions for the `FieldTimeSeries`. - `data`: JRA55 data to be retrieved. -- `jra55_native_grid`: Native grid of the JRA55 data. +- `JRA55_native_grid`: Native grid of the JRA55 data. - `interpolated_file`: Optional. Path to the file where the interpolated data will be written. - `shortname`: Optional. Shortname for the interpolated data. @@ -363,8 +432,8 @@ If `interpolated_file` is not a `Nothing`: (2) If the `interpolated_file` exists but is on a different grid, the file will be deleted and rewritten. (3) If the `shortname` is already present in the file, the data will not be written again. """ -function retrieve_and_maybe_write_jra55_data(::Nothing, grid, times, loc, boundary_conditions, data, jra55_native_grid; kwargs...) - native_fts = FieldTimeSeries{Center, Center, Nothing}(jra55_native_grid, times; boundary_conditions) +function retrieve_and_maybe_write_JRA55_data(::Nothing, grid, times, loc, boundary_conditions, data, JRA55_native_grid; kwargs...) + native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; boundary_conditions) # Fill the data in a GPU-friendly manner copyto!(interior(native_fts, :, :, 1, :), data[:, :, :]) @@ -385,14 +454,14 @@ function retrieve_and_maybe_write_jra55_data(::Nothing, grid, times, loc, bounda end # TODO: check also the time indices -function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_conditions, data, jra55_native_grid; +function retrieve_and_maybe_write_JRA55_data(chunks, grid, times, loc, boundary_conditions, data, JRA55_native_grid; interpolated_file = nothing, shortname = nothing) if !isfile(interpolated_file) # File does not exist, let's rewrite it - @info "rewriting the jra55 data into an Oceananigans compatible format" - interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + @info "rewriting the JRA55 data into an Oceananigans compatible format" + interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, JRA55_native_grid) end file = jldopen(interpolated_file) @@ -403,16 +472,16 @@ function retrieve_and_maybe_write_jra55_data(chunks, grid, times, loc, boundary_ @info "the saved boundary data is on another grid, deleting the old boundary file" rm(interpolated_file; force=true) - @info "rewriting the jra55 data into an Oceananigans compatible format" - interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + @info "rewriting the JRA55 data into an Oceananigans compatible format" + interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, JRA55_native_grid) else # File exists and the data is on the correct grid if !(shortname ∈ keys(file["timeseries"])) # `shortname` is not in the file close(file) - @info "rewriting the jra55 data into an Oceananigans compatible format" - interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, jra55_native_grid) + @info "rewriting the JRA55 data into an Oceananigans compatible format" + interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, JRA55_native_grid) end # File is there and `shortname` is in the file (probably the time indices are not correct) @@ -457,40 +526,40 @@ end =# # TODO: allow the user to pass dates -function jra55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # meters +function JRA55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # meters architecture = Oceananigans.architecture(grid) - u_jra55 = jra55_field_time_series(:eastward_velocity, grid; time_indices, architecture) - v_jra55 = jra55_field_time_series(:northward_velocity, grid; time_indices, architecture) - T_jra55 = jra55_field_time_series(:temperature, grid; time_indices, architecture) - q_jra55 = jra55_field_time_series(:specific_humidity, grid; time_indices, architecture) - p_jra55 = jra55_field_time_series(:sea_level_pressure, grid; time_indices, architecture) - Fr_jra55 = jra55_field_time_series(:rain_freshwater_flux, grid; time_indices, architecture) - Fs_jra55 = jra55_field_time_series(:snow_freshwater_flux, grid; time_indices, architecture) - Qlw_jra55 = jra55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) - Qsw_jra55 = jra55_field_time_series(:downwelling_shortwave_radiation, grid; time_indices, architecture) + u_JRA55 = JRA55_field_time_series(:eastward_velocity, grid; time_indices, architecture) + v_JRA55 = JRA55_field_time_series(:northward_velocity, grid; time_indices, architecture) + T_JRA55 = JRA55_field_time_series(:temperature, grid; time_indices, architecture) + q_JRA55 = JRA55_field_time_series(:specific_humidity, grid; time_indices, architecture) + p_JRA55 = JRA55_field_time_series(:sea_level_pressure, grid; time_indices, architecture) + Fr_JRA55 = JRA55_field_time_series(:rain_freshwater_flux, grid; time_indices, architecture) + Fs_JRA55 = JRA55_field_time_series(:snow_freshwater_flux, grid; time_indices, architecture) + Qlw_JRA55 = JRA55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) + Qsw_JRA55 = JRA55_field_time_series(:downwelling_shortwave_radiation, grid; time_indices, architecture) # NOTE: these have a different frequency than 3 hours so some changes are needed to - # jra55_field_time_series to support them. - # Fv_jra55 = jra55_field_time_series(:freshwater_river_flux, grid; time_indices, architecture) - # Fi_jra55 = jra55_field_time_series(:freshwater_iceberg_flux, grid; time_indices, architecture) + # JRA55_field_time_series to support them. + # Fv_JRA55 = JRA55_field_time_series(:freshwater_river_flux, grid; time_indices, architecture) + # Fi_JRA55 = JRA55_field_time_series(:freshwater_iceberg_flux, grid; time_indices, architecture) - times = u_jra55.times + times = u_JRA55.times - velocities = (u = u_jra55, - v = v_jra55) + velocities = (u = u_JRA55, + v = v_JRA55) - tracers = (T = T_jra55, - q = q_jra55) + tracers = (T = T_JRA55, + q = q_JRA55) - freshwater_flux = (rain = Fr_jra55, - snow = Fs_jra55) - # rivers = Fv_jra55, - # icebergs = Fi_jra55) + freshwater_flux = (rain = Fr_JRA55, + snow = Fs_JRA55) + # rivers = Fv_JRA55, + # icebergs = Fi_JRA55) - pressure = p_jra55 + pressure = p_JRA55 - downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_jra55, longwave=Qlw_jra55) + downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_JRA55, longwave=Qlw_JRA55) atmosphere = PrescribedAtmosphere(times, eltype(grid); velocities, From eb73cac06d6968fc6d9d30530fcf397f55e16b39 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 14:14:23 -0700 Subject: [PATCH 100/182] Implement a preprocessing feature in JRA55_field_time_series --- src/DataWrangling/JRA55.jl | 173 ++++++++++++++++++++++++------------- 1 file changed, 112 insertions(+), 61 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 34602495..cb954a14 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -59,18 +59,18 @@ jra55_short_names = Dict( ) field_time_series_short_names = Dict( - :freshwater_river_flux => :Fri, # Freshwater fluxes from rivers - :rain_freshwater_flux => :Fra, # Freshwater flux from rainfall - :snow_freshwater_flux => :Fsn, # Freshwater flux from snowfall - :freshwater_iceberg_flux => :Fic, # Freshwater flux from calving icebergs - :specific_humidity => :qa, # Surface specific humidity - :sea_level_pressure => :pa, # Sea level pressure - :relative_humidity => :rh, # Surface relative humidity - :downwelling_longwave_radiation => :Ql, # Downwelling longwave radiation - :downwelling_shortwave_radiation => :Qs, # Downwelling shortwave radiation - :temperature => :Ta, # Near-surface air temperature - :eastward_velocity => :ua, # Eastward near-surface wind - :northward_velocity => :va, # Northward near-surface wind + :freshwater_river_flux => "Fri", # Freshwater fluxes from rivers + :rain_freshwater_flux => "Fra", # Freshwater flux from rainfall + :snow_freshwater_flux => "Fsn", # Freshwater flux from snowfall + :freshwater_iceberg_flux => "Fic", # Freshwater flux from calving icebergs + :specific_humidity => "qa", # Surface specific humidity + :sea_level_pressure => "pa", # Sea level pressure + :relative_humidity => "rh", # Surface relative humidity + :downwelling_longwave_radiation => "Ql", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "Qs", # Downwelling shortwave radiation + :temperature => "Ta", # Near-surface air temperature + :eastward_velocity => "ua", # Eastward near-surface wind + :northward_velocity => "va", # Northward near-surface wind ) urls = Dict( @@ -231,7 +231,7 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; url = nothing, filename = nothing, shortname = nothing, - backend = InMemory() + backend = InMemory(), preprocess_chunk_size = 10, preprocess_architecture = CPU(), time_indices = nothing) @@ -256,7 +256,50 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; isnothing(filename) && (filename = filenames[variable_name]) isnothing(url) && (url = urls[variable_name]) - isfile(filename) || download(url, filename) + + # Decision tree: + # 1. jld2 file exists? + # - yes -> load and return FieldTimeSeries + # check time_indices and all that? + # - no -> download .nc data if not available + + jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") + fts_name = field_time_series_short_names[variable_name] + + totally_in_memory = backend isa InMemory{Nothing} + + if isfile(jld2_filename) + if totally_in_memory && !isnothing(time_indices) + # Correct interpretation of user input? + backend = InMemory(time_indices) + end + + fts = FieldTimeSeries(jld2_filename, fts_name; backend, architecture) + + # TODO: improve this. + Nt = length(fts.times) + if !isnothing(time_indices) && (Nt != length(time_indices)) + @warn string("The FieldTimeSeries found at $jld2_filename has $Nt time indices, but", '\n', + " length(time_indices) = ", length(time_indices), ". Delete or move", '\n', + " the existing file to regenerate the `FieldTimeSeries`.") + end + + return fts + else + isfile(filename) || download(url, filename) + end + + # Extract variable data + if totally_in_memory + # Set a sensible default + isnothing(time_indices) && (time_indices = 1:1) + time_indices_in_memory = time_indices + native_fts_architecture = architecture + else + isnothing(time_indices) && (time_indices = :) + time_indices_in_memory = 1:preprocess_chunk_size + native_fts_architecture = preprocess_architecture + end # Get location if isnothing(location) @@ -265,17 +308,15 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; LX, LY = location end - totally_in_memory = backend isa InMemory{Nothing} - ds = Dataset(filename) # Note that each file should have the variables - # ds["time"]: time coordinate - # ds["lon"]: longitude at the location of the variable - # ds["lat"]: latitude at the location of the variable - # ds["lon_bnds"]: bounding longitudes between which variables are averaged - # ds["lat_bnds"]: bounding latitudes between which variables are averaged - # ds[shortname]: the variable data + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data # Nodes at the variable location λc = ds["lon"][:] @@ -290,19 +331,14 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; push!(φn, 90) push!(λn, λn[1] + 360) - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(grid, LX, LY, λc, φc) - - # Extract variable data - if totally_in_memory - # Set a sensible default - isnothing(time_indices) && (time_indices = 1:1) - time_indices_in_memory = time_indices - native_fts_architecture = architecture - else - isnothing(time_indices) && (time_indices = :) - time_indices_in_memory = 1:preprocess_chunk_size - native_fts_architecture = preprocess_architecture - end + # TODO: support loading just part of the JRA55 data. + # Probably with arguments that take latitude, longitude bounds. + # i₁, i₂, j₁, j₂, TX = compute_bounding_indices(grid, LX, LY, λc, φc) + Nx = length(λc) + Ny = length(φc) + i₁, i₂ = (1, Nx) + j₁, j₂ = (1, Ny) + TX = Periodic times = ds["time"][time_indices_in_memory] data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] @@ -312,6 +348,15 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; close(ds) + JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture; + halo = (1, 1), + size = (Nrx, Nry), + longitude = λr, + latitude = φr, + topology = (TX, Bounded, Flat)) + + boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) + # Hack together the `times` for the JRA55 dataset we are currently using. # We might want to use the acutal dates instead though. # So the following code might need to change. @@ -321,14 +366,8 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; stop_time = Δt * (Nt - 1) times = start_time:Δt:stop_time - JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture; - halo = (1, 1), - size = (Nrx, Nry), - longitude = λr, - latitude = φr, - topology = (TX, Bounded, Flat)) - - boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) + # Make times into an array for later preprocessing + !totally_in_memory && (times = collect(times)) native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; boundary_conditions) @@ -346,33 +385,39 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; end =# - if backend isa InMemory{Nothing} + if totally_in_memory return native_fts else # we're gonna save to disk! - @info "Processing JRA55 data and saving to disk..." + @info "Pre-processing JRA55 data into a JLD2 file to be used with FieldTimeSeries..." - fts_name = field_time_series_short_names[variable_name] - jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") - - ondisk_fts = FieldTimeSeries{LX, LY, LZ}(native_fts.grid; - backend = OnDisk(), - path = jld2_filename, - name = fts_name) + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(native_fts.grid; + backend = OnDisk(), + path = jld2_filename, + name = fts_name) # Re-open the dataset! ds = Dataset(filename) - all_times = ds["time"][time_indices] - all_Nt = length(all_times) + all_datetimes = ds["time"][time_indices] + all_Nt = length(all_datetimes) chunk = last(preprocess_chunk_size) + Δt = 3hours # just what it is + start_time = 0 # Note: the forcing starts at Jan 1 of the repeat year. + stop_time = Δt * (all_Nt - 1) + all_times = start_time:Δt:stop_time + + # Save data to disk, one field at a time + start_clock = time_ns() n = 1 # on disk - m = 1 # in memory + m = 0 # in memory while n <= all_Nt - if n ∈ time_indices + print(" ... processing time index $n of $all_Nt \r") + + if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory m += 1 else # Update time_indices - time_indices_in_memory .+= preprocess_chunk_size + time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size # Clip time_indices if they extend past the end of the dataset if last(time_indices_in_memory) > all_Nt @@ -381,8 +426,8 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; end # Re-load .nc times and data - new_times = ds["time"][time_indices_in_memory] - native_fts.times .= new_times + # new_times = ds["time"][time_indices_in_memory] + # native_fts.times .= new_times new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) @@ -391,9 +436,16 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; m = 1 # reset end - set!(ondisk_fts, native_fts[m], n, native_fts.times[m]) + set!(on_disk_fts, native_fts[m], n, all_times[n]) + n += 1 end + elapsed = 1e-9 * (time_ns() - start_clock) + elapsed_str = prettytime(elapsed) + @info " ... done ($elapsed_str)" * repeat(" ", 20) + + close(ds) + grid = on_architecture(architecture, JRA55_native_grid) backend_fts = FieldTimeSeries{LX, LY, Nothing}(grid, all_times; @@ -571,7 +623,6 @@ function JRA55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # return atmosphere end - end # module From 04f1817eb2e8bce40449c9174ba09efb9132cf43 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 14:23:17 -0700 Subject: [PATCH 101/182] jra55 -> JRA55 --- experiments/prototype_omip_simulation/omip_simulation.jl | 2 -- .../prototype_omip_simulation/regional_omip_simulation.jl | 4 ++-- .../single_column_omip_simulation.jl | 4 ++-- experiments/prototype_omip_simulation/surface_fluxes.jl | 4 ++-- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl index 989560f6..2070f470 100644 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ b/experiments/prototype_omip_simulation/omip_simulation.jl @@ -10,8 +10,6 @@ using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, SurfaceRadiation -using ClimaOcean.JRA55: jra55_field_time_series - using ClimaSeaIce using ClimaSeaIce: IceWaterThermalEquilibrium diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index ca0410a0..19cf688f 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -6,7 +6,7 @@ using Oceananigans.Units: Time using ClimaOcean using ClimaOcean.OceanSeaIceModels: Radiation -using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere using ClimaOcean.DataWrangling.ECCO2: ecco2_field # using GLMakie @@ -94,7 +94,7 @@ start_time = time_ns() Ndays = 3 Nt = 8 * Ndays -atmosphere = jra55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) +atmosphere = JRA55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 4b290f14..4d12303a 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -5,7 +5,7 @@ using Oceananigans.Units: Time using ClimaOcean using ClimaOcean.OceanSeaIceModels: Radiation -using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere using ClimaOcean.DataWrangling.ECCO2: ecco2_field using GLMakie @@ -115,7 +115,7 @@ for location in keys(locations) Ndays = 365 Nt = 8 * Ndays - atmosphere = jra55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) + atmosphere = JRA55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl index 4d59c262..094a541e 100644 --- a/experiments/prototype_omip_simulation/surface_fluxes.jl +++ b/experiments/prototype_omip_simulation/surface_fluxes.jl @@ -5,7 +5,7 @@ using Oceananigans.Units: Time using ClimaOcean using ClimaOcean.OceanSeaIceModels: Radiation -using ClimaOcean.DataWrangling.JRA55: jra55_prescribed_atmosphere +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere using ClimaOcean.DataWrangling.ECCO2: ecco2_field using GLMakie @@ -81,7 +81,7 @@ elapsed = time_ns() - start_time @info "Ocean component built. " * prettytime(elapsed * 1e-9) start_time = time_ns() -atmosphere = jra55_prescribed_atmosphere(grid, 1:1) +atmosphere = JRA55_prescribed_atmosphere(grid, 1:1) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() From c79ad16f7a96b5df743022540cf0439325c23513 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 14:37:07 -0700 Subject: [PATCH 102/182] Better warning --- src/DataWrangling/JRA55.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index cb954a14..061a87ab 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -280,7 +280,7 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; Nt = length(fts.times) if !isnothing(time_indices) && (Nt != length(time_indices)) @warn string("The FieldTimeSeries found at $jld2_filename has $Nt time indices, but", '\n', - " length(time_indices) = ", length(time_indices), ". Delete or move", '\n', + " length(time_indices) = ", length(time_indices), ". Delete or move", " the existing file to regenerate the `FieldTimeSeries`.") end From 0f0b210835d49deac222e1cb5db2b2845a378d06 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 14:37:15 -0700 Subject: [PATCH 103/182] Update tests --- test/test_jra55.jl | 61 ++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index e77dffdb..4aa1fbb9 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -1,48 +1,22 @@ include("runtests_setup.jl") -using Oceananigans.Units - -arch = CPU() -longname = :downwelling_shortwave_radiation -time_indices = 1:3 -jra55_fts = ClimaOcean.JRA55.jra55_field_time_series(longname; architecture=arch, time_indices) - -jld2_filename = string("JRA55_repeat_year_", longname, ".jld2") -shortname = :Qs -backend = OnDisk() -LX, LY, LZ = location(jra55_fts) - -Δt = 3hours # just what it is -Nt = 2920 # just what it is -start_time = 0 # Note: the forcing start at Jan 1 of the repeat year. -stop_time = Δt * (Nt - 1) -jra55_times = start_time:Δt:stop_time - -ondisk_fts = FieldTimeSeries{LX, LY, LZ}(jra55_fts.grid; backend, - path = jld2_filename, - name = shortname) - -set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) - -#= @testset "JRA55 and data wrangling utilities" begin for arch in test_architectures A = typeof(arch) - @info "Testing jra55_field_time_series on $A..." + @info "Testing JRA55_field_time_series on $A..." test_name = :downwelling_shortwave_radiation test_filename = "RYF.rsds.1990_1991.nc" + test_jld2_filename = "JRA55_repeat_year_downwelling_shortwave_radiation.jld2" time_indices = 1:3 # This should download a file called "RYF.rsds.1990_1991.nc" - jra55_fts = ClimaOcean.JRA55.jra55_field_time_series(test_name; architecture=arch, time_indices) + jra55_fts = ClimaOcean.JRA55.JRA55_field_time_series(test_name; architecture=arch, time_indices) @test isfile(test_filename) - rm(test_filename) - @test jra55_fts isa FieldTimeSeries @test jra55_fts.grid isa LatitudeLongitudeGrid - + Nx, Ny, Nz, Nt = size(jra55_fts) @test Nx == 640 @test Ny == 320 @@ -54,6 +28,29 @@ set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) @test view(jra55_fts.data, 1, :, 1, :) == view(jra55_fts.data, Nx+1, :, 1, :) end + @info "Testing preprocessing JRA55 data on $A..." + rm(test_jld2_filename, force=true) + + on_disk_jra55_fts = ClimaOcean.JRA55.JRA55_field_time_series(test_name; + architecture = arch, + backend = OnDisk(), + time_indices) + + @test on_disk_jra55_fts isa FieldTimeSeries + @test parent(on_disk_jra55_fts[1]) == parent(jra55_fts[1]) + + @info "Testing loading preprocessed JRA55 data on $A..." + in_memory_jra55_fts = ClimaOcean.JRA55.JRA55_field_time_series(test_name; + architecture = arch, + backend = InMemory(2)) + + @test in_memory_jra55_fts isa FieldTimeSeries + @test parent(in_memory_jra55_fts[1]) == parent(jra55_fts[1]) + + # Clean up + rm(test_filename) + rm(on_disk_jra55_fts.path) + @info "Testing interpolate_field_time_series! on $A..." # Make target grid and field resolution = 1 # degree, eg 1/4 @@ -75,7 +72,6 @@ set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) times = jra55_fts.times boundary_conditions = jra55_fts.boundary_conditions target_fts = FieldTimeSeries{Center, Center, Nothing}(target_grid, times; boundary_conditions) - ClimaOcean.DataWrangling.interpolate_field_time_series!(target_fts, jra55_fts) # Random regression test @@ -84,6 +80,7 @@ set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) # Only include this if we are filling halo regions within # interpolate_field_time_series + @test jra55_fts[641, 1, 1, 1] == 222.24310434509874 @test target_fts[Nx + 1, 1, 1, 1] == 222.24310434509874 end @@ -104,4 +101,4 @@ set!(ondisk_fts, jra55_fts[1], 1, jra55_fts.times[1]) rm(filepath) end end -=# + From 68b495876d0966410e10825851ce5935064724d4 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 15:04:27 -0700 Subject: [PATCH 104/182] Fix up JRA55 tests --- test/test_jra55.jl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 4aa1fbb9..55c9cd30 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -23,6 +23,11 @@ include("runtests_setup.jl") @test Nz == 1 @test Nt == length(time_indices) + CUDA.@allowscalar begin + @test jra55_fts[1, 1, 1, 1] == 430.98105f0 + @test jra55_fts[641, 1, 1, 1] == 430.98105f0 + end + # Test that halo regions were filled to respect boundary conditions CUDA.@allowscalar begin @test view(jra55_fts.data, 1, :, 1, :) == view(jra55_fts.data, Nx+1, :, 1, :) @@ -76,12 +81,11 @@ include("runtests_setup.jl") # Random regression test CUDA.@allowscalar begin - @test target_fts[1, 1, 1, 1] == 222.24310434509874 + @test target_fts[1, 1, 1, 1] == 222.243136478611 # Only include this if we are filling halo regions within # interpolate_field_time_series - @test jra55_fts[641, 1, 1, 1] == 222.24310434509874 - @test target_fts[Nx + 1, 1, 1, 1] == 222.24310434509874 + @test target_fts[Nx + 1, 1, 1, 1] == 222.243136478611 end @test target_fts.times == jra55_fts.times From bc13f4a743193de91a8d2de3f5c86a733bfae700 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 15:05:05 -0700 Subject: [PATCH 105/182] Fix bug for InMemory{Colon} and specify Float32 JRA55 --- src/DataWrangling/JRA55.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 061a87ab..ec14c0be 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -266,7 +266,7 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") fts_name = field_time_series_short_names[variable_name] - totally_in_memory = backend isa InMemory{Nothing} + totally_in_memory = backend isa InMemory{Colon} if isfile(jld2_filename) if totally_in_memory && !isnothing(time_indices) @@ -345,10 +345,9 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; λr = λn[i₁:i₂+1] φr = φn[j₁:j₂+1] Nrx, Nry, Nt = size(data) - close(ds) - JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture; + JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; halo = (1, 1), size = (Nrx, Nry), longitude = λr, @@ -372,7 +371,7 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; boundary_conditions) # Fill the data in a GPU-friendly manner - copyto!(interior(native_fts, :, :, 1, :), data[:, :, :]) + copyto!(interior(native_fts, :, :, 1, :), data) fill_halo_regions!(native_fts) #= From b42dcb0a75d1e0a02658f2935d173ad7fbcada2c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 29 Jan 2024 15:05:38 -0700 Subject: [PATCH 106/182] Add correct Oceananigans version --- Manifest.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 4b2f72e1..81e56dbe 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -741,9 +741,11 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "ead1d8ec6911ff84ef52c387c827553bbc859c1b" +git-tree-sha1 = "85b0b81c4f6d542ab79b095d98de4e2773e03d65" +repo-rev = "ss-glw/time-bcs" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.6" +version = "0.90.7" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" From 40df5e52c23b4f5511ba60e857581098f2757b46 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 31 Jan 2024 20:54:38 +1100 Subject: [PATCH 107/182] add compat entry for Oceananigans --- experiments/prototype_omip_simulation/Project.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml index 3c31c917..38276dd2 100644 --- a/experiments/prototype_omip_simulation/Project.toml +++ b/experiments/prototype_omip_simulation/Project.toml @@ -8,3 +8,7 @@ NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" + +[compat] +Oceananigans = "0.90.6" +GLMakie = "0.9" From 9dc9789e3a040f402eec6f5caf33808bf597ffd7 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 31 Jan 2024 20:54:47 +1100 Subject: [PATCH 108/182] update deps --- Manifest.toml | 8 +- .../prototype_omip_simulation/Manifest.toml | 12 +- src/quarter_degree_global_simulation.jl | 213 ++++++++++++++++++ 3 files changed, 223 insertions(+), 10 deletions(-) create mode 100644 src/quarter_degree_global_simulation.jl diff --git a/Manifest.toml b/Manifest.toml index 81e56dbe..ec617c0a 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0-beta3" +julia_version = "1.10.0" manifest_format = "2.0" project_hash = "bcfc95e502c18276c6e7315f722ad6f48d7698c2" @@ -573,7 +573,7 @@ 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.0.1+1" +version = "8.4.0+0" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -1110,9 +1110,9 @@ deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.0+1" +version = "7.2.1+1" [[deps.SurfaceFluxes]] deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 6329b20b..e5516fcd 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0-beta3" +julia_version = "1.10.0" manifest_format = "2.0" project_hash = "a2a450f285334f2fe90a5a74f427515e12a6d318" @@ -1014,7 +1014,7 @@ 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.0.1+1" +version = "8.4.0+0" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -1304,9 +1304,9 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -path = "/home/greg/Projects/Oceananigans.jl" +git-tree-sha1 = "ead1d8ec6911ff84ef52c387c827553bbc859c1b" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.5" +version = "0.90.6" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -1951,9 +1951,9 @@ deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.0+1" +version = "7.2.1+1" [[deps.SurfaceFluxes]] deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] diff --git a/src/quarter_degree_global_simulation.jl b/src/quarter_degree_global_simulation.jl new file mode 100644 index 00000000..05caa21c --- /dev/null +++ b/src/quarter_degree_global_simulation.jl @@ -0,0 +1,213 @@ +using Oceananigans.TurbulenceClosures: HorizontalDivergenceFormulation +using Oceananigans.Advection: VelocityStencil + +""" + quarter_degree_near_global_simulation(architecture = GPU(); kwargs...) + +Return an `Oceananigans.Simulation` of Earth's ocean at 1/4 degree lateral resolution. +""" +function quarter_degree_near_global_simulation(architecture = GPU(); + size = (1440, 600, 48), + boundary_layer_turbulence_closure = RiBasedVerticalDiffusivity(), + background_vertical_diffusivity = 1e-5, + background_vertical_viscosity = 1e-4, + horizontal_viscosity = geometric_viscosity(HorizontalDivergenceFormulation(), 5days), + surface_temperature_relaxation_time_scale = 7days, + surface_salinity_relaxation_time_scale = 7days, + bottom_drag_coefficient = 3e-3, + reference_density = 1029.0, + reference_heat_capacity = 3991.0, + reference_salinity = 34.0, + time_step = 6minutes, + stop_iteration = Inf, + start_time = 345days, + stop_time = Inf, + equation_of_state = TEOS10EquationOfState(; reference_density), + tracers = [:T, :S], + initial_conditions = datadep"near_global_quarter_degree/initial_conditions.jld2", + bathymetry_path = datadep"near_global_quarter_degree/bathymetry-1440x600.jld2", + temp_surface_boundary_conditions_path = datadep"near_global_quarter_degree/temp-1440x600-latitude-75.jld2", + salt_surface_boundary_conditions_path = datadep"near_global_quarter_degree/salt-1440x600-latitude-75.jld2", + u_stress_surface_boundary_conditions_path = datadep"near_global_quarter_degree/tau_x-1440x600-latitude-75.jld2", + v_stress_surface_boundary_conditions_path = datadep"near_global_quarter_degree/tau_y-1440x600-latitude-75.jld2", +) + + bathymetry_file = jldopen(bathymetry_path) + bathymetry = bathymetry_file["bathymetry"] + close(bathymetry_file) + + @info "Reading initial conditions..."; start=time_ns() + initial_conditions_file = jldopen(initial_conditions) + T_init = initial_conditions_file["T"] + S_init = initial_conditions_file["S"] + close(initial_conditions_file) + @info "... read initial conditions (" * prettytime(1e-9 * (time_ns() - start)) * ")" + + # Files contain 12 arrays of monthly-averaged data from 1992 + @info "Reading boundary conditions..."; start=time_ns() + # Files contain 1 year (1992) of 12 monthly averages + τˣ = - jldopen(u_stress_surface_boundary_conditions_path)["field"] ./ reference_density + τʸ = - jldopen(v_stress_surface_boundary_conditions_path)["field"] ./ reference_density + T★ = jldopen(temp_surface_boundary_conditions_path)["field"] + S★ = jldopen(salt_surface_boundary_conditions_path)["field"] + F★ = zeros(Base.size(S★)...) + Q★ = zeros(Base.size(T★)...) + # close(u_stress_surface_boundary_conditions_path) + # close(v_stress_surface_boundary_conditions_path) + # close(temp_surface_boundary_conditions_path) + # close(salt_surface_boundary_conditions_path) + @info "... read boundary conditions (" * prettytime(1e-9 * (time_ns() - start)) * ")" + + # Convert boundary conditions arrays to GPU + τˣ = arch_array(architecture, τˣ) + τʸ = arch_array(architecture, τʸ) + target_sea_surface_temperature = T★ = arch_array(architecture, T★) + target_sea_surface_salinity = S★ = arch_array(architecture, S★) + surface_temperature_flux = Q★ = arch_array(architecture, Q★) + surface_salt_flux = F★ = arch_array(architecture, F★) + + # Stretched faces from ECCO Version 4 (49 levels in the vertical) + z_faces = VerticalGrids.z_49_levels_10_to_400_meter_spacing + + # A spherical domain + underlying_grid = LatitudeLongitudeGrid(architecture; size, + longitude = (-180, 180), + latitude = (-75, 75), + halo = (5, 5, 5), + z = z_faces) + + grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bathymetry)) + + @info "Created $grid" + + ##### + ##### Physics and model setup + ##### + + vitd = VerticallyImplicitTimeDiscretization() + + vertical_viscosity = VerticalScalarDiffusivity(vitd, ν=background_vertical_viscosity, κ=background_vertical_diffusivity) + + closures = Any[horizontal_viscosity, boundary_layer_turbulence_closure, vertical_viscosity] + + boundary_layer_turbulence_closure isa CATKEVerticalDiffusivity && + push!(tracers, :e) + + # TODO: do this internally in model constructor + closures = tuple(closures...) + + ##### + ##### Boundary conditions / time-dependent fluxes + ##### + + drag_u = FluxBoundaryCondition(u_immersed_bottom_drag, discrete_form=true, parameters = bottom_drag_coefficient) + drag_v = FluxBoundaryCondition(v_immersed_bottom_drag, discrete_form=true, parameters = bottom_drag_coefficient) + + no_slip_bc = ValueBoundaryCondition(0) + + u_immersed_bc = ImmersedBoundaryCondition(bottom = drag_u, + west = no_slip_bc, + east = no_slip_bc, + south = no_slip_bc, + north = no_slip_bc) + + v_immersed_bc = ImmersedBoundaryCondition(bottom = drag_v, + west = no_slip_bc, + east = no_slip_bc, + south = no_slip_bc, + north = no_slip_bc) + + u_bottom_drag_bc = FluxBoundaryCondition(u_bottom_drag, discrete_form = true, parameters = bottom_drag_coefficient) + v_bottom_drag_bc = FluxBoundaryCondition(v_bottom_drag, discrete_form = true, parameters = bottom_drag_coefficient) + + Nmonths = 12 # number of months in the forcing file + u_wind_stress_parameters = (; τ=τˣ, Nmonths) + v_wind_stress_parameters = (; τ=τʸ, Nmonths) + u_wind_stress_bc = FluxBoundaryCondition(surface_wind_stress, discrete_form=true, parameters=u_wind_stress_parameters) + v_wind_stress_bc = FluxBoundaryCondition(surface_wind_stress, discrete_form=true, parameters=v_wind_stress_parameters) + + Δz_top = @allowscalar Δzᵃᵃᶜ(1, 1, grid.Nz, grid.underlying_grid) + + T_relaxation_parameters = (; λ = Δz_top / surface_temperature_relaxation_time_scale, + Nmonths, + T★ = target_sea_surface_temperature, + Q★ = surface_temperature_flux) + + S_relaxation_parameters = (; λ = Δz_top / surface_salinity_relaxation_time_scale, + Nmonths, + S★ = target_sea_surface_salinity, + F★ = surface_salt_flux) + + T_surface_relaxation_bc = FluxBoundaryCondition(surface_temperature_relaxation, + discrete_form = true, + parameters = T_relaxation_parameters) + + S_surface_relaxation_bc = FluxBoundaryCondition(surface_salinity_relaxation, + discrete_form = true, + parameters = S_relaxation_parameters) + + u_bcs = FieldBoundaryConditions(top = u_wind_stress_bc, + bottom = u_bottom_drag_bc, + immersed = u_immersed_bc) + + v_bcs = FieldBoundaryConditions(top = v_wind_stress_bc, + bottom = v_bottom_drag_bc, + immersed = v_immersed_bc) + + T_bcs = FieldBoundaryConditions(top = T_surface_relaxation_bc) + S_bcs = FieldBoundaryConditions(top = S_surface_relaxation_bc) + + buoyancy = SeawaterBuoyancy(; equation_of_state) + coriolis = HydrostaticSphericalCoriolis(scheme = WetCellEnstrophyConservingScheme()) + free_surface = ImplicitFreeSurface() + + model = HydrostaticFreeSurfaceModel(; grid, free_surface, coriolis, buoyancy, tracers, + momentum_advection = WENO(vector_invariant = VelocityStencil()), + closure = closures, + boundary_conditions = (u=u_bcs, v=v_bcs, T=T_bcs, S=S_bcs), + tracer_advection = WENO(underlying_grid)) + + @info "... built $model." + @info "Model building time: " * prettytime(1e-9 * (time_ns() - start)) + + ##### + ##### Initial condition: + ##### + + set!(model, T=T_init, S=S_init) + + # Because MITgcm forcing starts at Jan 15 (?) + model.clock.time = start_time + + simulation = Simulation(model; Δt=time_step, stop_iteration, stop_time) + + start_time = [time_ns()] + + function progress(sim) + wall_time = (time_ns() - start_time[1]) * 1e-9 + + u = sim.model.velocities.u + w = sim.model.velocities.w + + intw = Array(interior(w)) + max_w = findmax(intw) + + mw = max_w[1] + iw = max_w[2] + + msg1 = @sprintf("Time: % 12s, iteration: %d, ", prettytime(sim), iteration(sim)) + msg2 = @sprintf("max(|u|): %.2e ms⁻¹, wmax: %.2e, loc: (%d, %d, %d), ", + maximum(abs, u), mw, iw[1], iw[2], iw[3]) + msg3 = @sprintf("wall time: %s", prettytime(wall_time)) + + @info msg1 * msg2 * msg3 + + start_time[1] = time_ns() + + return nothing + end + + simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + + return simulation +end From 0912e8a54412df704df194d1456fa6aded50c024 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 31 Jan 2024 21:07:45 +1100 Subject: [PATCH 109/182] use Oceananigans#ss-glw/time-bcs --- experiments/prototype_omip_simulation/Manifest.toml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index e5516fcd..795d3a07 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0" manifest_format = "2.0" -project_hash = "a2a450f285334f2fe90a5a74f427515e12a6d318" +project_hash = "672cbef2c7d6776d40e6432e74f2ade4088e87e6" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -1304,9 +1304,11 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "ead1d8ec6911ff84ef52c387c827553bbc859c1b" +git-tree-sha1 = "adb376d9962f0b29bac7e402c02ef9d5eda54b44" +repo-rev = "ss-glw/time-bcs" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.6" +version = "0.90.7" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" From e0431d81242275dddbb0e4ad6c286d758601f3ef Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 31 Jan 2024 21:18:34 +1100 Subject: [PATCH 110/182] fix --- src/DataWrangling/JRA55.jl | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index ec14c0be..fd9b5d92 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -169,11 +169,14 @@ end """ JRA55_field_time_series(variable_name; architecture = CPU(), + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, backend = InMemory(), - time_indices = nothing, - url = urls[name], - filename = filenames[variable_name], - shortname = jra55_short_names[variable_name]) + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, which describes one of the variables in the "repeat year forcing" dataset derived @@ -580,15 +583,15 @@ end function JRA55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # meters architecture = Oceananigans.architecture(grid) - u_JRA55 = JRA55_field_time_series(:eastward_velocity, grid; time_indices, architecture) - v_JRA55 = JRA55_field_time_series(:northward_velocity, grid; time_indices, architecture) - T_JRA55 = JRA55_field_time_series(:temperature, grid; time_indices, architecture) - q_JRA55 = JRA55_field_time_series(:specific_humidity, grid; time_indices, architecture) - p_JRA55 = JRA55_field_time_series(:sea_level_pressure, grid; time_indices, architecture) - Fr_JRA55 = JRA55_field_time_series(:rain_freshwater_flux, grid; time_indices, architecture) - Fs_JRA55 = JRA55_field_time_series(:snow_freshwater_flux, grid; time_indices, architecture) - Qlw_JRA55 = JRA55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) - Qsw_JRA55 = JRA55_field_time_series(:downwelling_shortwave_radiation, grid; time_indices, architecture) + u_JRA55 = JRA55_field_time_series(:eastward_velocity ; time_indices, architecture) + v_JRA55 = JRA55_field_time_series(:northward_velocity ; time_indices, architecture) + T_JRA55 = JRA55_field_time_series(:temperature ; time_indices, architecture) + q_JRA55 = JRA55_field_time_series(:specific_humidity ; time_indices, architecture) + p_JRA55 = JRA55_field_time_series(:sea_level_pressure ; time_indices, architecture) + Fr_JRA55 = JRA55_field_time_series(:rain_freshwater_flux ; time_indices, architecture) + Fs_JRA55 = JRA55_field_time_series(:snow_freshwater_flux ; time_indices, architecture) + Qlw_JRA55 = JRA55_field_time_series(:downwelling_longwave_radiation ; time_indices, architecture) + Qsw_JRA55 = JRA55_field_time_series(:downwelling_shortwave_radiation; time_indices, architecture) # NOTE: these have a different frequency than 3 hours so some changes are needed to # JRA55_field_time_series to support them. From f2e76638dfea91a1d14f5b497e2ff5f21d89f4ca Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 31 Jan 2024 21:22:06 +1100 Subject: [PATCH 111/182] use oceananigans 0.90.6 --- experiments/prototype_omip_simulation/Manifest.toml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 795d3a07..94c7db04 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1304,11 +1304,9 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "adb376d9962f0b29bac7e402c02ef9d5eda54b44" -repo-rev = "ss-glw/time-bcs" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +git-tree-sha1 = "ead1d8ec6911ff84ef52c387c827553bbc859c1b" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.7" +version = "0.90.6" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" From 73d34527bb6bfbef2c215caff6d15693f7b3fa79 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 31 Jan 2024 09:43:20 -0500 Subject: [PATCH 112/182] Update interface to JRA55_prescribed_atmosphere --- .../regional_omip_simulation.jl | 6 +- src/DataWrangling/JRA55.jl | 205 ++++-------------- 2 files changed, 49 insertions(+), 162 deletions(-) diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index 19cf688f..b1aa11eb 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -92,9 +92,9 @@ elapsed = time_ns() - start_time @info "Ocean component built. " * prettytime(elapsed * 1e-9) start_time = time_ns() -Ndays = 3 +Ndays = 30 Nt = 8 * Ndays -atmosphere = JRA55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) +atmosphere = JRA55_prescribed_atmosphere(arch, 1:Nt; backend=InMemory(8)) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() @@ -199,5 +199,3 @@ coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs =# run!(coupled_simulation) - - diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index ec14c0be..e8e25b44 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -265,30 +265,31 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") fts_name = field_time_series_short_names[variable_name] - totally_in_memory = backend isa InMemory{Colon} if isfile(jld2_filename) - if totally_in_memory && !isnothing(time_indices) - # Correct interpretation of user input? - backend = InMemory(time_indices) - end - - fts = FieldTimeSeries(jld2_filename, fts_name; backend, architecture) - - # TODO: improve this. - Nt = length(fts.times) - if !isnothing(time_indices) && (Nt != length(time_indices)) - @warn string("The FieldTimeSeries found at $jld2_filename has $Nt time indices, but", '\n', - " length(time_indices) = ", length(time_indices), ". Delete or move", - " the existing file to regenerate the `FieldTimeSeries`.") - end - - return fts - else - isfile(filename) || download(url, filename) + isnothing(time_indices) && (time_indices = Colon()) + + # Infer the `times` before loading data + temporary_fts = FieldTimeSeries(jld2_filename, fts_name; backend=OnDisk()) + + #try + times = temporary_fts.times[time_indices] + fts = FieldTimeSeries(jld2_filename, fts_name; backend, architecture, times) + return fts + #catch + # if !totally_in_memory # will need to overwrite + # msg = string("Cannot use backend=$backend with time_indices=$time_indices", '\n', + # " and the existing $jld2_filename, which does not", '\n', + # " have enough `times`. Delete $jld2_filename in order", '\n', + # " to re-generate it.") + # error(msg) + # end + #end end + isfile(filename) || download(url, filename) + # Extract variable data if totally_in_memory # Set a sensible default @@ -457,162 +458,50 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; end end -#= -""" - retrieve_and_maybe_write_JRA55_data(chunks, grid, times, loc, boundary_conditions, data, JRA55_native_grid; - interpolated_file = nothing, shortname = nothing) - -Retrieve JRA55 data and optionally write it to a file in an Oceananigans compatible format. - -## Arguments -- `chunks`: Chunk size for the in-memory backend of the `FieldTimeSeries`. -- `grid`: Grid for the `FieldTimeSeries`. -- `times`: Time values for the `FieldTimeSeries`. -- `loc`: Location of the JRA55 data. -- `boundary_conditions`: Boundary conditions for the `FieldTimeSeries`. -- `data`: JRA55 data to be retrieved. -- `JRA55_native_grid`: Native grid of the JRA55 data. -- `interpolated_file`: Optional. Path to the file where the interpolated data will be written. -- `shortname`: Optional. Shortname for the interpolated data. - -## Returns -- `fts`: `FieldTimeSeries` object containing the retrieved or interpolated data. - -If `interpolated_file` is not a `Nothing`: -(1) If the `interpolated_file` does not exist, the JRA55 data will be written to the file in an Oceananigans compatible format. -(2) If the `interpolated_file` exists but is on a different grid, the file will be deleted and rewritten. -(3) If the `shortname` is already present in the file, the data will not be written again. -""" -function retrieve_and_maybe_write_JRA55_data(::Nothing, grid, times, loc, boundary_conditions, data, JRA55_native_grid; kwargs...) - native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; boundary_conditions) - - # Fill the data in a GPU-friendly manner - copyto!(interior(native_fts, :, :, 1, :), data[:, :, :]) +const AA = Oceananigans.Architectures.AbstractArchitecture - # Fill halo regions so we can interpolate to finer grids - fill_halo_regions!(native_fts) - - if isnothing(grid) - return native_fts - else # make a new FieldTimeSeries and interpolate native data onto it. - boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) - fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; boundary_conditions) - - interpolate!(fts, native_fts) - - return fts - end -end - -# TODO: check also the time indices -function retrieve_and_maybe_write_JRA55_data(chunks, grid, times, loc, boundary_conditions, data, JRA55_native_grid; - interpolated_file = nothing, - shortname = nothing) - - if !isfile(interpolated_file) # File does not exist, let's rewrite it - - @info "rewriting the JRA55 data into an Oceananigans compatible format" - interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, JRA55_native_grid) - end - - file = jldopen(interpolated_file) - - if file["serialized/grid"] != grid # File exists but the data is on another grid, remove it and rewrite it - - close(file) - @info "the saved boundary data is on another grid, deleting the old boundary file" - rm(interpolated_file; force=true) - - @info "rewriting the JRA55 data into an Oceananigans compatible format" - interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, JRA55_native_grid) - - else # File exists and the data is on the correct grid - - if !(shortname ∈ keys(file["timeseries"])) # `shortname` is not in the file - close(file) - - @info "rewriting the JRA55 data into an Oceananigans compatible format" - interpolate_and_write_timeseries!(data, loc, grid, times, interpolated_file, shortname, boundary_conditions, JRA55_native_grid) - end - - # File is there and `shortname` is in the file (probably the time indices are not correct) - # TODO: check the time range includes the time range of the simulation - # check_time_indices!(args...) - end - - fts = FieldTimeSeries(interpolated_file, shortname; backend = InMemory(; chunk_size = chunks)) - - return fts -end - -""" - interpolate_and_write_timeseries!(data, loc, grid, times, path, name, bcs, native_grid) - -Interpolates and writes a time series of `data` at `times` onto disk in an Oceananigans compatible format. -""" -function interpolate_and_write_timeseries!(data, loc, grid, times, path, name, bcs, native_grid) - - dims = length(size(data)) - 1 - spatial_indices = Tuple(Colon() for i in 1:dims) - - native_field = Field{Center, Center, Nothing}(native_grid) - - f_tmp = Field{loc...}(grid) - fts_tmp = FieldTimeSeries(loc, grid, times; - backend = OnDisk(), - path, - name, - boundary_conditions = bcs) - - for t in eachindex(times) - set!(native_field, data[spatial_indices..., t]) - fill_halo_regions!(native_field) - interpolate!(f_tmp, native_field) - fill_halo_regions!(f_tmp) - set!(fts_tmp, f_tmp, t) - end - - return nothing -end -=# +JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = + JRA55_prescribed_atmosphere(CPU(), time_indices; kw...) # TODO: allow the user to pass dates -function JRA55_prescribed_atmosphere(grid, time_indices=:; reference_height=2) # meters - architecture = Oceananigans.architecture(grid) - - u_JRA55 = JRA55_field_time_series(:eastward_velocity, grid; time_indices, architecture) - v_JRA55 = JRA55_field_time_series(:northward_velocity, grid; time_indices, architecture) - T_JRA55 = JRA55_field_time_series(:temperature, grid; time_indices, architecture) - q_JRA55 = JRA55_field_time_series(:specific_humidity, grid; time_indices, architecture) - p_JRA55 = JRA55_field_time_series(:sea_level_pressure, grid; time_indices, architecture) - Fr_JRA55 = JRA55_field_time_series(:rain_freshwater_flux, grid; time_indices, architecture) - Fs_JRA55 = JRA55_field_time_series(:snow_freshwater_flux, grid; time_indices, architecture) - Qlw_JRA55 = JRA55_field_time_series(:downwelling_longwave_radiation, grid; time_indices, architecture) - Qsw_JRA55 = JRA55_field_time_series(:downwelling_shortwave_radiation, grid; time_indices, architecture) +function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); + backend = InMemory(24), # 3 days of data + reference_height = 2, # meters + other_kw...) + + ua = JRA55_field_time_series(:eastward_velocity; time_indices, backend, architecture, other_kw...) + va = JRA55_field_time_series(:northward_velocity; time_indices, backend, architecture, other_kw...) + Ta = JRA55_field_time_series(:temperature; time_indices, backend, architecture, other_kw...) + qa = JRA55_field_time_series(:specific_humidity; time_indices, backend, architecture, other_kw...) + pa = JRA55_field_time_series(:sea_level_pressure; time_indices, backend, architecture, other_kw...) + Fra = JRA55_field_time_series(:rain_freshwater_flux; time_indices, backend, architecture, other_kw...) + Fsn = JRA55_field_time_series(:snow_freshwater_flux; time_indices, backend, architecture, other_kw...) + Ql = JRA55_field_time_series(:downwelling_longwave_radiation; time_indices, backend, architecture, other_kw...) + Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; time_indices, backend, architecture, other_kw...) # NOTE: these have a different frequency than 3 hours so some changes are needed to # JRA55_field_time_series to support them. # Fv_JRA55 = JRA55_field_time_series(:freshwater_river_flux, grid; time_indices, architecture) # Fi_JRA55 = JRA55_field_time_series(:freshwater_iceberg_flux, grid; time_indices, architecture) - times = u_JRA55.times + times = ua.times - velocities = (u = u_JRA55, - v = v_JRA55) + velocities = (u = ua, + v = va) - tracers = (T = T_JRA55, - q = q_JRA55) + tracers = (T = Ta, + q = qa) - freshwater_flux = (rain = Fr_JRA55, - snow = Fs_JRA55) + freshwater_flux = (rain = Fra, + snow = Fsn) # rivers = Fv_JRA55, # icebergs = Fi_JRA55) - pressure = p_JRA55 + pressure = pa - downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qsw_JRA55, longwave=Qlw_JRA55) + downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qs, longwave=Ql) - atmosphere = PrescribedAtmosphere(times, eltype(grid); + atmosphere = PrescribedAtmosphere(times, eltype(ua); velocities, freshwater_flux, tracers, From 10ece457b3dbf2688e627890d0f128e2e1cf9231 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 31 Jan 2024 09:45:07 -0500 Subject: [PATCH 113/182] Remove artifact from JRA55.jl --- src/DataWrangling/JRA55.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 7b0a3ca7..a4a9560f 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -467,7 +467,6 @@ JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = JRA55_prescribed_atmosphere(CPU(), time_indices; kw...) # TODO: allow the user to pass dates -<<<<<<< HEAD function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = InMemory(24), # 3 days of data reference_height = 2, # meters From da6b835ae662e3c3aebe9fe7d740eb6e4a1c1d4a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 2 Feb 2024 16:16:05 -0700 Subject: [PATCH 114/182] Switch to assuming that we always interpolate atmos fields --- .../prototype_omip_simulation/Manifest.toml | 8 +- .../surface_fluxes.jl | 22 +++- src/DataWrangling/JRA55.jl | 23 +++- .../atmosphere_ocean_momentum_flux.jl | 18 --- .../ocean_sea_ice_surface_fluxes.jl | 116 ++++++++++-------- .../similarity_theory_turbulent_fluxes.jl | 16 +-- src/OceanSeaIceModels/OceanSeaIceModels.jl | 1 + .../PrescribedAtmospheres.jl | 40 +++--- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 1 - 9 files changed, 142 insertions(+), 103 deletions(-) delete mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_momentum_flux.jl diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 94c7db04..6e0d7744 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0" +julia_version = "1.10.0-rc1" manifest_format = "2.0" project_hash = "672cbef2c7d6776d40e6432e74f2ade4088e87e6" @@ -1304,9 +1304,9 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "ead1d8ec6911ff84ef52c387c827553bbc859c1b" +path = "/Users/gregorywagner/Projects/Oceananigans.jl" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.6" +version = "0.90.7" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -1951,7 +1951,7 @@ deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.1+1" diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl index 094a541e..bba9e260 100644 --- a/experiments/prototype_omip_simulation/surface_fluxes.jl +++ b/experiments/prototype_omip_simulation/surface_fluxes.jl @@ -81,11 +81,30 @@ elapsed = time_ns() - start_time @info "Ocean component built. " * prettytime(elapsed * 1e-9) start_time = time_ns() -atmosphere = JRA55_prescribed_atmosphere(grid, 1:1) +atmosphere = JRA55_prescribed_atmosphere(1:2, backend=InMemory()) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() +#= +fig = Figure() +axu = Axis(fig[1, 1]) +axv = Axis(fig[1, 2]) +axT = Axis(fig[1, 3]) +axq = Axis(fig[1, 4]) + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q + +heatmap!(axu, interior(ua, :, :, 1, 1)) +heatmap!(axv, interior(va, :, :, 1, 1)) +heatmap!(axT, interior(Ta, :, :, 1, 1)) +heatmap!(axq, interior(qa, :, :, 1, 1)) + +display(fig) + ocean.model.clock.time = start_seconds ocean.model.clock.iteration = 0 set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) @@ -95,6 +114,7 @@ va = atmosphere.velocities.v Ta = atmosphere.tracers.T qa = atmosphere.tracers.q times = ua.times +=# sea_ice = nothing radiation = Radiation() diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index a4a9560f..9c7cca63 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -6,6 +6,7 @@ using Oceananigans.Units using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Grids: λnodes, φnodes, on_architecture using Oceananigans.Fields: interpolate! +using Oceananigans.OutputReaders: Cyclical using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, @@ -235,6 +236,7 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; filename = nothing, shortname = nothing, backend = InMemory(), + time_extrapolation = Cyclical(), preprocess_chunk_size = 10, preprocess_architecture = CPU(), time_indices = nothing) @@ -270,6 +272,8 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; fts_name = field_time_series_short_names[variable_name] totally_in_memory = backend isa InMemory{Colon} + isfile(jld2_filename) && rm(jld2_filename) + #= if isfile(jld2_filename) isnothing(time_indices) && (time_indices = Colon()) @@ -290,6 +294,7 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; # end #end end + =# isfile(filename) || download(url, filename) @@ -352,7 +357,7 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; close(ds) JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; - halo = (1, 1), + halo = (3, 3), size = (Nrx, Nry), longitude = λr, latitude = φr, @@ -453,6 +458,7 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; backend_fts = FieldTimeSeries{LX, LY, Nothing}(grid, all_times; backend, + time_extrapolation, boundary_conditions, path = jld2_filename, name = fts_name) @@ -468,10 +474,23 @@ JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = # TODO: allow the user to pass dates function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); - backend = InMemory(24), # 3 days of data + backend = nothing, reference_height = 2, # meters other_kw...) + if isnothing(backend) # apply a default + Ni = try + length(time_indices) + catch + Inf + end + + # Manufacture a default for the number of fields to keep InMemory + Nf = min(24, Ni) + + backend = InMemory(Nf) + end + ua = JRA55_field_time_series(:eastward_velocity; time_indices, backend, architecture, other_kw...) va = JRA55_field_time_series(:northward_velocity; time_indices, backend, architecture, other_kw...) Ta = JRA55_field_time_series(:temperature; time_indices, backend, architecture, other_kw...) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_momentum_flux.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_momentum_flux.jl deleted file mode 100644 index d68b3a12..00000000 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_momentum_flux.jl +++ /dev/null @@ -1,18 +0,0 @@ -using Oceananigans.Operators: ℑxᶜᵃᵃ, ℑyᵃᶜᵃ - -##### -##### Relative velocities -##### - -@inline function x_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) - x_transfer_velocity_transfer_velocity = Δu_transfer_velocity(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) - return ρₐ / ρₒ * cᴰ * x_transfer_velocity_transfer_velocity -end - -@inline function y_atmosphere_ocean_momentum_flux(i, j, grid, clock, cᴰ, ρₒ, ρₐ, Uₒ, Uₐ) - time = Time(clock.time) - y_transfer_velocity_transfer_velocity = Δv_transfer_velocity(i, j, grid, time, Uₒ.u, Uₒ.v, Uₐ.u, Uₐ.v) - return ρₐ / ρₒ * cᴰ * y_transfer_velocity_transfer_velocity -end - - diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 6c10153a..f8f73233 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -4,16 +4,16 @@ using SurfaceFluxes using ..OceanSeaIceModels: reference_density, heat_capacity, - sea_ice_thickness, + sea_ice_concentration, downwelling_radiation, freshwater_flux using ClimaSeaIce: SlabSeaIceModel using Oceananigans: HydrostaticFreeSurfaceModel, architecture -using Oceananigans.Grids: inactive_node +using Oceananigans.Grids: inactive_node, node using Oceananigans.BoundaryConditions: fill_halo_regions! -using Oceananigans.Fields: ConstantField +using Oceananigans.Fields: ConstantField, interpolate using Oceananigans.Utils: launch!, Time using Oceananigans.Operators: ℑxᶜᵃᵃ, ℑyᵃᶜᵃ, ℑxᶠᵃᵃ, ℑyᵃᶠᵃ @@ -128,6 +128,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) ocean = coupled_model.ocean sea_ice = coupled_model.sea_ice atmosphere = coupled_model.atmosphere + atmosphere_grid = atmosphere.grid # Basic model properties grid = ocean.model.grid @@ -135,16 +136,9 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) clock = ocean.model.clock # Ocean, atmosphere, and sea ice state - ocean_velocities = surface_velocities(ocean) - ocean_tracers = surface_tracers(ocean) - - atmosphere_velocities = atmosphere.velocities - atmosphere_tracers = atmosphere.tracers - atmosphere_pressure = atmosphere.pressure - atmosphere_downwelling_radiation = atmosphere.downwelling_radiation - atmosphere_freshwater_flux = atmosphere.freshwater_flux - - ice_thickness = sea_ice_thickness(sea_ice) + ocean_velocities = surface_velocities(ocean) + ocean_tracers = surface_tracers(ocean) + ice_concentration = sea_ice_concentration(sea_ice) # Fluxes, and flux contributors centered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.uᶜᶜᶜ, @@ -159,25 +153,26 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) radiation_properties = coupled_model.fluxes.radiation ocean_state = merge(ocean_velocities, ocean_tracers) - atmosphere_state = merge(atmosphere_velocities, atmosphere_tracers, (; p=atmosphere_pressure)) + atmosphere_state = merge(atmosphere.velocities, atmosphere.tracers, (; p=atmosphere.pressure)) launch!(arch, grid, :xy, compute_atmosphere_ocean_turbulent_fluxes!, grid, clock, centered_velocity_fluxes, net_tracer_fluxes, turbulent_fluxes, - atmosphere_freshwater_flux, - atmosphere_downwelling_radiation, + atmosphere.freshwater_flux, + atmosphere.downwelling_radiation, radiation_properties, ocean_state, atmosphere_state, + atmosphere_grid, atmosphere.reference_height, # height at which the state is known atmosphere.thermodynamics_parameters, coupled_model.fluxes.ocean_reference_density, coupled_model.fluxes.ocean_heat_capacity, coupled_model.fluxes.freshwater_density, coupled_model.fluxes.ocean_temperature_units, - ice_thickness) + ice_concentration) # Note: I think this can be avoided if we modify the preceding kernel # to compute from 0:Nx+1, ie in halo regions @@ -189,6 +184,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) return nothing end +const c = Center() + @kernel function compute_atmosphere_ocean_turbulent_fluxes!(grid, clock, centered_velocity_fluxes, @@ -199,13 +196,14 @@ end radiation_properties, ocean_state, atmos_state, + atmos_grid, atmosphere_reference_height, atmosphere_thermodynamics_parameters, ocean_reference_density, ocean_heat_capacity, freshwater_density, ocean_temperature_units, - ice_thickness) + ice_concentration) i, j = @index(Global, NTuple) @@ -216,40 +214,50 @@ end # Ocean state uₒ = ℑxᶜᵃᵃ(i, j, 1, grid, ocean_state.u) vₒ = ℑyᵃᶜᵃ(i, j, 1, grid, ocean_state.v) - Uₒ = SVector(uₒ, vₒ) Tₒ = ocean_state.T[i, j, 1] Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) Sₒ = ocean_state.S[i, j, 1] # Atmos state - uₐ = atmos_state.u[i, j, 1, time] - vₐ = atmos_state.v[i, j, 1, time] - Uₐ = SVector(uₐ, vₐ) + X = node(i, j, 1, grid, c, c, c) + + uₐ = interpolate_field_time_series(atmos_state.u, X, time, atmos_grid) + vₐ = interpolate_field_time_series(atmos_state.v, X, time, atmos_grid) + + Tₐ = interpolate_field_time_series(atmos_state.T, X, time, atmos_grid) + pₐ = interpolate_field_time_series(atmos_state.p, X, time, atmos_grid) + qₐ = interpolate_field_time_series(atmos_state.q, X, time, atmos_grid) - Tₐ = atmos_state.T[i, j, 1, time] - pₐ = atmos_state.p[i, j, 1, time] - qₐ = atmos_state.q[i, j, 1, time] # total specific humidity + Qs = interpolate_field_time_series(downwelling_radiation.shortwave, X, time, atmos_grid) + Qℓ = interpolate_field_time_series(downwelling_radiation.longwave, X, time, atmos_grid) + + # Accumulate freshwater mass fluxes. Rain, snow, runoff -- all freshwater. + M = interpolate_field_time_series(prescribed_freshwater_flux, X, time, atmos_grid) end # Build thermodynamic and dynamic states in the atmosphere and surface. # Notation: # ⋅ ϕ ≡ thermodynamic state vector # ⋅ Φ ≡ "dynamic" state vector (thermodynamics + reference height + velocity) - ℂ = atmosphere_thermodynamics_parameters + ℂₐ = atmosphere_thermodynamics_parameters + ϕₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) + hₐ = atmosphere_reference_height # elevation of atmos variables relative to surface - ϕₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₐ, qₐ) + Uₐ = SVector(uₐ, vₐ) Φₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, ϕₐ) # Build surface state with saturated specific humidity surface_type = AtmosphericThermodynamics.Liquid() - q★ = seawater_saturation_specific_humidity(ℂ, Tₒ, Sₒ, ϕₐ, + qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, ϕₐ, turbulent_fluxes.water_mole_fraction, turbulent_fluxes.water_vapor_saturation, surface_type) # Thermodynamic and dynamic surface state + ϕ₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₒ, qₒ) + h₀ = zero(grid) # surface height - ϕ₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂ, pₐ, Tₒ, q★) + Uₒ = SVector(uₒ, vₒ) Φ₀ = dynamic_surface_state = SurfaceFluxes.StateValues(h₀, Uₒ, ϕ₀) # Initial guess for the roughness length. @@ -271,17 +279,13 @@ end conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) # Compute heat fluxes, bulk flux first - Qd = net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation_properties) + Qd = net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation_properties) Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state, ocean_temperature_units) Qc = conditions.shf # sensible or "conductive" heat flux Qe = conditions.lhf # latent or "evaporative" heat flux ΣQ = Qd + Qu + Qc + Qe - # Accumulate freshwater fluxes. Rain, snow, runoff -- all freshwater. - # Note these are mass fluxes, hence the "M". - M = cross_realm_flux(i, j, grid, time, prescribed_freshwater_flux) - - # Convert from a mass flux to a volume flux / velocity? + # Convert from a mass flux to a volume flux (aka velocity). # Also switch the sign, for some reason we are given freshwater flux as positive down. ρᶠ = freshwater_density ΣF = - M / ρᶠ @@ -328,12 +332,10 @@ end end end -@inline function net_downwelling_radiation(i, j, grid, time, downwelling_radiation, radiation) - Qˢʷ = downwelling_radiation.shortwave - Qˡʷ = downwelling_radiation.longwave +@inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) α = stateindex(radiation.reflection.ocean, i, j, 1, time) - return @inbounds - (1 - α) * Qˢʷ[i, j, 1, time] - Qˡʷ[i, j, 1, time] + return @inbounds - (1 - α) * Qs - Qℓ end @inline function net_upwelling_radiation(i, j, grid, time, radiation, ocean_state, ocean_temperature_units) @@ -348,22 +350,28 @@ end return ϵ * σ * Tₒ^4 end -@inline cross_realm_flux(i, j, grid, time, ::Nothing, args...) = zero(grid) -@inline cross_realm_flux(i, j, grid, time, a::AbstractArray, args...) = stateindex(a, i, j, 1, time) -@inline cross_realm_flux(i, j, grid, time, nt::NamedTuple, args...) = cross_realm_flux(i, j, grid, time, values(nt), args...) +@inline interpolate_field_time_series(J, x, t, grid) = + interpolate(x, t, J, (c, c, c), grid) + +@inline interpolate_field_time_series(ΣJ::NamedTuple, args...) = + interpolate_field_time_series(values(ΣJ), args...) + +@inline interpolate_field_time_series(ΣJ::Tuple{<:Any}, args...) = + interpolate_field_time_series(ΣJ[1], args...) + + interpolate_field_time_series(ΣJ[2], args...) -@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any}, args...) = - cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) +@inline interpolate_field_time_series(ΣJ::Tuple{<:Any, <:Any}, args...) = + interpolate_field_time_series(ΣJ[1], args...) + + interpolate_field_time_series(ΣJ[2], args...) -@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any, <:Any}, args...) = - cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[3], args...) +@inline interpolate_field_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any}, args...) = + interpolate_field_time_series(ΣJ[1], args...) + + interpolate_field_time_series(ΣJ[2], args...) + + interpolate_field_time_series(ΣJ[3], args...) -@inline cross_realm_flux(i, j, grid, time, flux_tuple::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = - cross_realm_flux(i, j, grid, time, flux_tuple[1], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[2], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[3], args...) + - cross_realm_flux(i, j, grid, time, flux_tuple[4], args...) +@inline interpolate_field_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = + interpolate_field_time_series(ΣJ[1], args...) + + interpolate_field_time_series(ΣJ[2], args...) + + interpolate_field_time_series(ΣJ[3], args...) + + interpolate_field_time_series(ΣJ[4], args...) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 52756a5c..ec331d84 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -142,18 +142,20 @@ default_universal_function_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = co ζ_a = convert(FT, 2.5), γ = convert(FT, 4.42)) -function seawater_saturation_specific_humidity(atmosphere_thermodynamics_parameters, - surface_temperature, - surface_salinity, - atmos_state, - water_mole_fraction, - water_vapor_saturation, - ::Liquid) +@inline function seawater_saturation_specific_humidity(atmosphere_thermodynamics_parameters, + surface_temperature, + surface_salinity, + atmos_state, + water_mole_fraction, + water_vapor_saturation, + ::Liquid) ℂₐ = atmosphere_thermodynamics_parameters + FT = eltype(ℂₐ) Tₛ = surface_temperature Sₛ = surface_salinity ρₛ = atmos_state.ρ # surface density -- should we extrapolate to obtain this? + ρₛ = convert(FT, ρₛ) q★_H₂O = water_saturation_specific_humidity(water_vapor_saturation, ℂₐ, ρₛ, Tₛ) x_H₂O = compute_water_mole_fraction(water_mole_fraction, Sₛ) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 12f72314..d4620bbd 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -29,6 +29,7 @@ function reference_density end function heat_capacity end sea_ice_thickness(::Nothing) = nothing +sea_ice_concentration(::Nothing) = nothing ##### ##### Some implementation diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 0821c75e..6a927597 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -86,9 +86,9 @@ function ConstitutiveParameters(FT = Float64; dry_air_molar_mass = 0.02897, water_molar_mass = 0.018015) - return ConstitutiveParameters(convert(FT, gas_constant), - convert(FT, dry_air_molar_mass), - convert(FT, water_molar_mass)) + return ConstitutiveParameters{FT}(convert(FT, gas_constant), + convert(FT, dry_air_molar_mass), + convert(FT, water_molar_mass)) end const CP = ConstitutiveParameters @@ -132,10 +132,10 @@ function HeatCapacityParameters(FT = Float64; liquid_water_heat_capacity = 4181, water_ice_heat_capacity = 2100) - return HeatCapacityParameters(convert(FT, dry_air_adiabatic_exponent), - convert(FT, water_vapor_heat_capacity), - convert(FT, liquid_water_heat_capacity), - convert(FT, water_ice_heat_capacity)) + return HeatCapacityParameters{FT}(convert(FT, dry_air_adiabatic_exponent), + convert(FT, water_vapor_heat_capacity), + convert(FT, liquid_water_heat_capacity), + convert(FT, water_ice_heat_capacity)) end const HCP = HeatCapacityParameters @@ -178,13 +178,13 @@ function PhaseTransitionParameters(FT = Float64; water_freezing_temperature = 273.15, total_ice_nucleation_temperature = 233) - return PhaseTransitionParameters(convert(FT, reference_vaporization_enthalpy), - convert(FT, reference_sublimation_enthalpy), - convert(FT, reference_temperature), - convert(FT, triple_point_temperature), - convert(FT, triple_point_pressure), - convert(FT, water_freezing_temperature), - convert(FT, total_ice_nucleation_temperature)) + return PhaseTransitionParameters{FT}(convert(FT, reference_vaporization_enthalpy), + convert(FT, reference_sublimation_enthalpy), + convert(FT, reference_temperature), + convert(FT, triple_point_temperature), + convert(FT, triple_point_pressure), + convert(FT, water_freezing_temperature), + convert(FT, total_ice_nucleation_temperature)) end const PTP = PhaseTransitionParameters @@ -279,7 +279,8 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters ##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic) ##### -struct PrescribedAtmosphere{U, P, C, F, R, TP, TI, FT} +struct PrescribedAtmosphere{G, U, P, C, F, R, TP, TI, FT} + grid :: G velocities :: U pressure :: P tracers :: C @@ -312,9 +313,16 @@ function PrescribedAtmosphere(times, FT=Float64; freshwater_flux = nothing, downwelling_radiation = nothing, thermodynamics_parameters = PrescribedAtmosphereThermodynamicsParameters(FT), + grid = nothing, tracers = nothing) - return PrescribedAtmosphere(velocities, + if isnothing(grid) # try to find it + u = first(velocities) + grid = u.grid + end + + return PrescribedAtmosphere(grid, + velocities, pressure, tracers, freshwater_flux, diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index e8cfc26d..8a0cb264 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -87,4 +87,3 @@ function default_nan_checker(model::OceanSeaIceModel) return nan_checker end - From ce22dbf0ac03b919f55df20a44a139c6ddb30552 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 2 Feb 2024 16:35:52 -0700 Subject: [PATCH 115/182] Update surface fluxes script --- experiments/prototype_omip_simulation/surface_fluxes.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl index bba9e260..c26254d6 100644 --- a/experiments/prototype_omip_simulation/surface_fluxes.jl +++ b/experiments/prototype_omip_simulation/surface_fluxes.jl @@ -129,12 +129,12 @@ Jᵛ = coupled_model.fluxes.total.ocean.momentum.v Jᵀ = coupled_model.fluxes.total.ocean.tracers.T Jˢ = coupled_model.fluxes.total.ocean.tracers.S -E = coupled_model.fluxes.turbulent.fields.evaporation +E = coupled_model.fluxes.turbulent.fields.freshwater Fʳ = atmosphere.freshwater_flux.rain Fˢ = atmosphere.freshwater_flux.snow -Qᶜ = coupled_model.fluxes.turbulent.fields.sensible_heat_flux -Qᵉ = coupled_model.fluxes.turbulent.fields.latent_heat_flux +Qᶜ = coupled_model.fluxes.turbulent.fields.sensible_heat +Qᵉ = coupled_model.fluxes.turbulent.fields.latent_heat Qˡ = atmosphere.downwelling_radiation.longwave Qˢ = atmosphere.downwelling_radiation.shortwave From 93c17c76ec8bf1e1a450251c189e3e6cab02678a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 2 Feb 2024 21:03:17 -0500 Subject: [PATCH 116/182] Start working on similarity theory fluxes --- .../prototype_omip_simulation/Manifest.toml | 10 ++- .../surface_fluxes.jl | 4 +- .../ocean_sea_ice_surface_fluxes.jl | 57 +++++++------- .../similarity_theory_turbulent_fluxes.jl | 76 ++++++++++++++++++- 4 files changed, 114 insertions(+), 33 deletions(-) diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 6e0d7744..3c62abd9 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0-rc1" +julia_version = "1.10.0-beta3" manifest_format = "2.0" project_hash = "672cbef2c7d6776d40e6432e74f2ade4088e87e6" @@ -1014,7 +1014,7 @@ 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" +version = "8.0.1+1" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -1304,7 +1304,9 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -path = "/Users/gregorywagner/Projects/Oceananigans.jl" +git-tree-sha1 = "487b4a79cda089c898fdc9c0c21061712f0fc062" +repo-rev = "ss-glw/time-bcs" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.7" @@ -1953,7 +1955,7 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" +version = "7.2.0+1" [[deps.SurfaceFluxes]] deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl index c26254d6..63a132d1 100644 --- a/experiments/prototype_omip_simulation/surface_fluxes.jl +++ b/experiments/prototype_omip_simulation/surface_fluxes.jl @@ -36,7 +36,7 @@ start_time = time_ns() ##### Construct the grid ##### -arch = CPU() +arch = GPU() latitude = (-75, +65) longitude = (0, 360) @@ -81,7 +81,7 @@ elapsed = time_ns() - start_time @info "Ocean component built. " * prettytime(elapsed * 1e-9) start_time = time_ns() -atmosphere = JRA55_prescribed_atmosphere(1:2, backend=InMemory()) +atmosphere = JRA55_prescribed_atmosphere(1:2, backend=InMemory(), architecture=arch) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index f8f73233..56b019b5 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -221,18 +221,18 @@ const c = Center() # Atmos state X = node(i, j, 1, grid, c, c, c) - uₐ = interpolate_field_time_series(atmos_state.u, X, time, atmos_grid) - vₐ = interpolate_field_time_series(atmos_state.v, X, time, atmos_grid) + uₐ = interpolate_atmos_field_time_series(atmos_state.u, X, time, atmos_grid) + vₐ = interpolate_atmos_field_time_series(atmos_state.v, X, time, atmos_grid) - Tₐ = interpolate_field_time_series(atmos_state.T, X, time, atmos_grid) - pₐ = interpolate_field_time_series(atmos_state.p, X, time, atmos_grid) - qₐ = interpolate_field_time_series(atmos_state.q, X, time, atmos_grid) + Tₐ = interpolate_atmos_field_time_series(atmos_state.T, X, time, atmos_grid) + pₐ = interpolate_atmos_field_time_series(atmos_state.p, X, time, atmos_grid) + qₐ = interpolate_atmos_field_time_series(atmos_state.q, X, time, atmos_grid) - Qs = interpolate_field_time_series(downwelling_radiation.shortwave, X, time, atmos_grid) - Qℓ = interpolate_field_time_series(downwelling_radiation.longwave, X, time, atmos_grid) + Qs = interpolate_atmos_field_time_series(downwelling_radiation.shortwave, X, time, atmos_grid) + Qℓ = interpolate_atmos_field_time_series(downwelling_radiation.longwave, X, time, atmos_grid) # Accumulate freshwater mass fluxes. Rain, snow, runoff -- all freshwater. - M = interpolate_field_time_series(prescribed_freshwater_flux, X, time, atmos_grid) + M = interpolate_atmos_field_time_series(prescribed_freshwater_flux, X, time, atmos_grid) end # Build thermodynamic and dynamic states in the atmosphere and surface. @@ -350,28 +350,33 @@ end return ϵ * σ * Tₒ^4 end -@inline interpolate_field_time_series(J, x, t, grid) = +##### +##### Utility for interpolating tuples of fields +##### + +# Note: assumes loc = (c, c, c) +@inline interpolate_atmos_field_time_series(J, x, t, grid) = interpolate(x, t, J, (c, c, c), grid) -@inline interpolate_field_time_series(ΣJ::NamedTuple, args...) = - interpolate_field_time_series(values(ΣJ), args...) +@inline interpolate_atmos_field_time_series(ΣJ::NamedTuple, args...) = + interpolate_atmos_field_time_series(values(ΣJ), args...) -@inline interpolate_field_time_series(ΣJ::Tuple{<:Any}, args...) = - interpolate_field_time_series(ΣJ[1], args...) + - interpolate_field_time_series(ΣJ[2], args...) +@inline interpolate_atmos_field_time_series(ΣJ::Tuple{<:Any}, args...) = + interpolate_atmos_field_time_series(ΣJ[1], args...) + + interpolate_atmos_field_time_series(ΣJ[2], args...) -@inline interpolate_field_time_series(ΣJ::Tuple{<:Any, <:Any}, args...) = - interpolate_field_time_series(ΣJ[1], args...) + - interpolate_field_time_series(ΣJ[2], args...) +@inline interpolate_atmos_field_time_series(ΣJ::Tuple{<:Any, <:Any}, args...) = + interpolate_atmos_field_time_series(ΣJ[1], args...) + + interpolate_atmos_field_time_series(ΣJ[2], args...) -@inline interpolate_field_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any}, args...) = - interpolate_field_time_series(ΣJ[1], args...) + - interpolate_field_time_series(ΣJ[2], args...) + - interpolate_field_time_series(ΣJ[3], args...) +@inline interpolate_atmos_field_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any}, args...) = + interpolate_atmos_field_time_series(ΣJ[1], args...) + + interpolate_atmos_field_time_series(ΣJ[2], args...) + + interpolate_atmos_field_time_series(ΣJ[3], args...) -@inline interpolate_field_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = - interpolate_field_time_series(ΣJ[1], args...) + - interpolate_field_time_series(ΣJ[2], args...) + - interpolate_field_time_series(ΣJ[3], args...) + - interpolate_field_time_series(ΣJ[4], args...) +@inline interpolate_atmos_field_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = + interpolate_atmos_field_time_series(ΣJ[1], args...) + + interpolate_atmos_field_time_series(ΣJ[2], args...) + + interpolate_atmos_field_time_series(ΣJ[3], args...) + + interpolate_atmos_field_time_series(ΣJ[4], args...) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index ec331d84..6d91b816 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -21,7 +21,7 @@ import SurfaceFluxes.Parameters: ##### Bulk turbulent fluxes based on similarity theory ##### -struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, F} <: AbstractSurfaceFluxesParameters +struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, R, F} <: AbstractSurfaceFluxesParameters gravitational_acceleration :: FT von_karman_constant :: FT bulk_velocity_scale :: ΔU @@ -29,6 +29,7 @@ struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, F} <: AbstractSurf thermodynamics_parameters :: TP water_vapor_saturation :: S water_mole_fraction :: W + roughness_lengths :: R fields :: F end @@ -101,6 +102,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; thermodynamics_parameters, water_vapor_saturation, water_mole_fraction, + nothing, fields) end @@ -214,3 +216,75 @@ end return (1 - s) / (1 - s + α * s) end +#= +struct GravityWaveRoughnessLengths{FT} + gravity_wave_parameter :: FT + laminar_parameter :: FT + air_kinematic_viscosity :: FT +end + +function GravityWaveRoughnessLengths(FT=Float64; + gravity_wave_parameter = 0.011, + laminar_parameter = 0.11, + air_kinematic_viscosity=1.5e-5) + + return GravityWaveRoughnessLengths(convert(FT, gravity_wave_parameter), + convert(FT, laminar_parameter), + convert(FT, air_kinematic_viscosity)) +end + +@inline function compute_turbulent_surface_fluxes(roughness_lengths::SimplifiedRoughnessLengths, + atmos_state, + ocean_state) + + # Solve for the surface fluxes with initial roughness length guess + Uᵍ = zero(grid) # gustiness + β = one(grid) # surface "resistance" + values = SurfaceFluxes.ValuesOnly(atmos_state, ocean_State, + roughness_lengths.momentum, + roughness_lengths.heat + Uᵍ, β) + conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + + fluxes = (; + latent_heat_flux = conditions.lhf, + sensible_heat_flux = conditions.shf, + freshwater_flux = conditions.evaporation, + zonal_momentum_flux = conditions.ρτxz, + meridional_momentum_flux = conditions.ρτyz, + ) + + return fluxes +end + + +@inline function compute_turbulent_surface_fluxes(roughness_lengths::GravityWaveRoughnessLengths, + atmos_state, + ocean_state) + + # Solve for the surface fluxes with initial roughness length guess + Uᵍ = zero(grid) # gustiness + β = one(grid) # surface "resistance" + values = SurfaceFluxes.ValuesOnly(atmos_state, ocean_State, + roughness_lengths.momentum, + roughness_lengths.heat + Uᵍ, β) + + conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + + fluxes = (; + latent_heat_flux = conditions.lhf, + sensible_heat_flux = conditions.shf, + freshwater_flux = conditions.evaporation, + zonal_momentum_flux = conditions.ρτxz, + meridional_momentum_flux = conditions.ρτyz, + ) + + return fluxes +end + + +=# + + +=# From 1f7551ad6b705b5ff6fe9439fbf4c1d3294f44d9 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 2 Feb 2024 21:25:37 -0500 Subject: [PATCH 117/182] Updates --- .../similarity_theory_turbulent_fluxes.jl | 122 +++++++++++++++--- 1 file changed, 106 insertions(+), 16 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 6d91b816..e3b6b43a 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -25,7 +25,7 @@ struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, R, F} <: AbstractS gravitational_acceleration :: FT von_karman_constant :: FT bulk_velocity_scale :: ΔU - universal_function :: UF + similarity_function :: UF thermodynamics_parameters :: TP water_vapor_saturation :: S water_mole_fraction :: W @@ -35,7 +35,7 @@ end const STTF = SimilarityTheoryTurbulentFluxes @inline thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters -@inline uf_params(fluxes::STTF) = fluxes.universal_function +@inline uf_params(fluxes::STTF) = fluxes.similarity_function @inline von_karman_const(fluxes::STTF) = fluxes.von_karman_constant @inline grav(fluxes::STTF) = fluxes.gravitational_acceleration @@ -44,10 +44,11 @@ const STTF = SimilarityTheoryTurbulentFluxes Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), adapt(to, fluxes.von_karman_constant), adapt(to, fluxes.bulk_velocity_scale), - adapt(to, fluxes.universal_function), + adapt(to, fluxes.similarity_function), adapt(to, fluxes.thermodynamics_parameters), adapt(to, fluxes.water_vapor_saturation), adapt(to, fluxes.water_mole_fraction), + adapt(to, fluxes.roughness_lengths), adapt(to, fluxes.fields)) Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" @@ -77,7 +78,7 @@ function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) "├── gravitational_acceleration: ", prettysummary(fluxes.gravitational_acceleration), '\n', "├── von_karman_constant: ", prettysummary(fluxes.von_karman_constant), '\n', "├── bulk_velocity_scale: ", summary(fluxes.bulk_velocity_scale), '\n', - "├── universal_function: ", summary(fluxes.universal_function), '\n', + "├── similarity_function: ", summary(fluxes.similarity_function), '\n', "├── water_mole_fraction: ", summary(fluxes.water_mole_fraction), '\n', "├── water_vapor_saturation: ", summary(fluxes.water_vapor_saturation), '\n', "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) @@ -89,7 +90,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; gravitational_acceleration = convert(FT, 9.80665), bulk_velocity_scale = nothing, von_karman_constant = convert(FT, 0.4), - universal_function = default_universal_function_parameters(FT), + similarity_function = default_similarity_function_parameters(FT), thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), @@ -98,7 +99,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; return SimilarityTheoryTurbulentFluxes(gravitational_acceleration, von_karman_constant, bulk_velocity_scale, - universal_function, + similarity_function, thermodynamics_parameters, water_vapor_saturation, water_mole_fraction, @@ -138,11 +139,11 @@ end end # See SurfaceFluxes.jl for other parameter set options. -default_universal_function_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), - a_m = convert(FT, 4.7), - a_h = convert(FT, 4.7), - ζ_a = convert(FT, 2.5), - γ = convert(FT, 4.42)) +default_businger_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), + a_m = convert(FT, 4.7), + a_h = convert(FT, 4.7), + ζ_a = convert(FT, 2.5), + γ = convert(FT, 4.42)) @inline function seawater_saturation_specific_humidity(atmosphere_thermodynamics_parameters, surface_temperature, @@ -217,12 +218,85 @@ end end #= -struct GravityWaveRoughnessLengths{FT} +struct SimilarityFunction{FT} + a :: FT + b :: FT + c :: FT +end + +struct GravityWaveRoughnessLength{FT} gravity_wave_parameter :: FT laminar_parameter :: FT air_kinematic_viscosity :: FT end +struct AtmosphericState{Q, T, U, V} + q :: Q + θ :: T + u :: U + v :: V +end + +AtmosphericState(q, θ, u) = AtmosphericState(q, θ, u, nothing) + +@inline function (ψ::SimilarityFunction)(Ri) + a = ψ.a + b = ψ.b + c = ψ.c + + ϕ⁻¹ = (1 - b * Ri)^c + ψ_unstable = log((1 + ϕ⁻¹)^2 * (1 + ϕ⁻¹^2) / 8) - 2 * atan(ϕ⁻¹) + π/2 + ψ_stable = - a * Ri + return ifelse(Ri < 0, ψ_unstable, ψ_stable) +end + +@inline similarity_scale(ψ, h, ℓ, Ri) = 1 / (log(h/ℓ) - ψ(Ri) + ψ(ℓ * Ri / h)) + +function buoyancy_scale(θ★, q★, surface_state, parameters) + θ★ = fluxes.θ + q★ = fluxes.q + 𝒯₀ = virtual_temperature(parameters, surface_state) + q₀ = surface_state.q + θ₀ = surface_state.θ + r = parameters.molar_mass_ratio + g = parameters.gravitational_acceleration + δ = r - 1 + b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * θ₀ * q★) + return b★ +end + +function fixed_point_fluxes(u★, θ★, q★, + surface_state, + inner_length_scales, + universal_function, + parameters) + + Δu = differences.u + Δv = differences.v + Δθ = differences.θ + Δq = differences.q + + ϰ = parameters.von_karman_constant + f = universal_function + + b★ = buoyancy_scale(θ★, q★, surface_state, parameters) + Riₕ = - ϰ * h * b★ / u★^2 + + ℓu = inner_length_scales.u(u★) + ℓθ = inner_length_scales.θ(u★) + ℓq = inner_length_scales.q(u★) + + χu = momentum_flux_scale(f, h, ℓu, Riₕ) + χθ = tracer_flux_scale(f, h, ℓθ, Riₕ) + χq = tracer_flux_scale(f, h, ℓq, Riₕ) + + u★ = ϰ * χu * sqrt(Δu^2 + Δv^2) + θ★ = ϰ * χθ * Δθ + q★ = ϰ * χq * Δq + + return u★, θ★, q★ +end + function GravityWaveRoughnessLengths(FT=Float64; gravity_wave_parameter = 0.011, laminar_parameter = 0.11, @@ -233,7 +307,26 @@ function GravityWaveRoughnessLengths(FT=Float64; convert(FT, air_kinematic_viscosity)) end -@inline function compute_turbulent_surface_fluxes(roughness_lengths::SimplifiedRoughnessLengths, +@inline function compute_turbulent_surface_fluxes(similarity_function::BusingerParams, + roughness_lengths, + atmos_state, + ocean_state) + + ℓu = roughness_lengths.momentum + ℓθ = roughness_lengths.heat + ℓq = roughness_lengths.moisture + + + fluxes = (; + latent_heat_flux = conditions.lhf, + sensible_heat_flux = conditions.shf, + freshwater_flux = conditions.evaporation, + zonal_momentum_flux = conditions.ρτxz, + meridional_momentum_flux = conditions.ρτyz, + ) + +@inline function compute_turbulent_surface_fluxes(similarity_function::BusingerParams, + roughness_lengths::SimplifiedRoughnessLengths, atmos_state, ocean_state) @@ -283,8 +376,5 @@ end return fluxes end - =# - -=# From d44cd1929e497b5f9f7049fd50c7f035e3132dbc Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sun, 4 Feb 2024 22:26:21 -0500 Subject: [PATCH 118/182] Shuffle omip components --- ..._ocean_component.jl => omip_components.jl} | 44 +++++++++++++++++++ .../omip_sea_ice_component.jl | 36 --------------- .../regional_omip_simulation.jl | 2 +- 3 files changed, 45 insertions(+), 37 deletions(-) rename experiments/prototype_omip_simulation/{omip_ocean_component.jl => omip_components.jl} (54%) diff --git a/experiments/prototype_omip_simulation/omip_ocean_component.jl b/experiments/prototype_omip_simulation/omip_components.jl similarity index 54% rename from experiments/prototype_omip_simulation/omip_ocean_component.jl rename to experiments/prototype_omip_simulation/omip_components.jl index ebd6b56c..c062d283 100644 --- a/experiments/prototype_omip_simulation/omip_ocean_component.jl +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -48,3 +48,47 @@ function omip_ocean_component(grid) return ocean end + + +function omip_sea_ice_component(grid) + Nx, Ny, Nz = size(grid) + sea_ice_grid = LatitudeLongitudeGrid(arch, + size = (Nx, Ny), + longitude = (0, 360), + halo = (7, 7), + latitude = (southern_limit, northern_limit), + topology = (Periodic, Bounded, Flat)) + + sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBottom(bottom_height)) + + sea_ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) + + Nz = size(grid, 3) + So = ocean_model.tracers.S + ocean_surface_salinity = view(So, :, :, Nz) + bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) + + u, v, w = ocean_model.velocities + ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), + v = view(v, :, :, Nz), #interior(v, :, :, Nz), + w = ZeroField()) + + sea_ice_model = SlabSeaIceModel(sea_ice_grid; + velocities = ocean_surface_velocities, + advection = nothing, + ice_consolidation_thickness = 0.05, + ice_salinity = 4, + internal_heat_flux = ConductiveFlux(conductivity=2), + top_heat_flux = ConstantField(0), # W m⁻² + top_heat_boundary_condition = PrescribedTemperature(0), + bottom_heat_boundary_condition = bottom_bc, + bottom_heat_flux = sea_ice_ocean_heat_flux) + + s# et!(sea_ice_model, h=ℋᵢ) + + sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) + + return sea_ice +end + + diff --git a/experiments/prototype_omip_simulation/omip_sea_ice_component.jl b/experiments/prototype_omip_simulation/omip_sea_ice_component.jl index fbd2cd83..e69de29b 100644 --- a/experiments/prototype_omip_simulation/omip_sea_ice_component.jl +++ b/experiments/prototype_omip_simulation/omip_sea_ice_component.jl @@ -1,36 +0,0 @@ -sea_ice_grid = LatitudeLongitudeGrid(arch, - size = (Nx, Ny), - longitude = (0, 360), - halo = (7, 7), - latitude = (southern_limit, northern_limit), - topology = (Periodic, Bounded, Flat)) - -sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBottom(bottom_height)) - -sea_ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) - -Nz = size(grid, 3) -So = ocean_model.tracers.S -ocean_surface_salinity = view(So, :, :, Nz) -bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) - -u, v, w = ocean_model.velocities -ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), - v = view(v, :, :, Nz), #interior(v, :, :, Nz), - w = ZeroField()) - -sea_ice_model = SlabSeaIceModel(sea_ice_grid; - velocities = ocean_surface_velocities, - advection = nothing, - ice_consolidation_thickness = 0.05, - ice_salinity = 4, - internal_heat_flux = ConductiveFlux(conductivity=2), - top_heat_flux = ConstantField(0), # W m⁻² - top_heat_boundary_condition = PrescribedTemperature(0), - bottom_heat_boundary_condition = bottom_bc, - bottom_heat_flux = sea_ice_ocean_heat_flux) - -set!(sea_ice_model, h=ℋᵢ) - -sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) - diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index b1aa11eb..cdbe3dfb 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -15,7 +15,7 @@ using Dates start_time = time_ns() -include("omip_ocean_component.jl") +include("omip_components.jl") epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) From e77e2f28a196c5fb9d26e2ba06df68865abe2404 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 5 Feb 2024 08:48:16 -0500 Subject: [PATCH 119/182] Updates for freely decaying sea ice simulation --- .../regional_omip_simulation.jl | 6 ++++-- .../prototype_omip_simulation/surface_fluxes.jl | 2 +- .../CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl | 12 ++++++++---- .../similarity_theory_turbulent_fluxes.jl | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index cdbe3dfb..98ebc03b 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -92,12 +92,14 @@ elapsed = time_ns() - start_time @info "Ocean component built. " * prettytime(elapsed * 1e-9) start_time = time_ns() +#= Ndays = 30 Nt = 8 * Ndays atmosphere = JRA55_prescribed_atmosphere(arch, 1:Nt; backend=InMemory(8)) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() +=# ocean.model.clock.time = start_seconds ocean.model.clock.iteration = 0 @@ -113,7 +115,7 @@ sea_ice = nothing radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 60days) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_iteration=200) elapsed = time_ns() - start_time @info "Coupled simulation built. " * prettytime(elapsed * 1e-9) @@ -153,7 +155,7 @@ function progress(sim) @info msg end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) # Build flux outputs Jᵘ = coupled_model.fluxes.total.ocean.momentum.u diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl index 63a132d1..0dc447be 100644 --- a/experiments/prototype_omip_simulation/surface_fluxes.jl +++ b/experiments/prototype_omip_simulation/surface_fluxes.jl @@ -14,7 +14,7 @@ using Dates start_time = time_ns() -include("omip_ocean_component.jl") +include("omip_components.jl") epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 56b019b5..d63b0af6 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -64,10 +64,14 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; ocean_heat_capacity = convert(FT, ocean_heat_capacity) freshwater_density = convert(FT, freshwater_density) - # It's the "thermodynamics gravitational acceleration" - # (as opposed to the one used for the free surface) - gravitational_acceleration = ocean.model.buoyancy.model.gravitational_acceleration - turbulent_fluxes = SimilarityTheoryTurbulentFluxes(grid; gravitational_acceleration) + if isnothing(atmosphere) + # It's the "thermodynamics gravitational acceleration" + # (as opposed to the one used for the free surface) + gravitational_acceleration = ocean.model.buoyancy.model.gravitational_acceleration + turbulent_fluxes = SimilarityTheoryTurbulentFluxes(grid; gravitational_acceleration) + else + turbulent_fluxes = nothing + end prescribed_fluxes = nothing diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index e3b6b43a..81bc6a40 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -90,7 +90,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; gravitational_acceleration = convert(FT, 9.80665), bulk_velocity_scale = nothing, von_karman_constant = convert(FT, 0.4), - similarity_function = default_similarity_function_parameters(FT), + similarity_function = default_businger_parameters(FT), thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), From cb0759161a8f93578dbdde4ad047a5432a73e685 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 5 Feb 2024 09:58:22 -0700 Subject: [PATCH 120/182] Get freely decaying ice simulation working --- .../omip_components.jl | 41 +++++++++------ .../regional_omip_simulation.jl | 50 ++++++++++--------- .../time_step_ocean_sea_ice_model.jl | 2 +- 3 files changed, 54 insertions(+), 39 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl index c062d283..99374dac 100644 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -3,6 +3,12 @@ using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: MixingLength, TurbulentKineticEnergyEquation +using Oceananigans.Grids: halo_size, topology, φnodes, λnodes +using Oceananigans.Fields: ConstantField, ZeroField + +using ClimaSeaIce +using ClimaSeaIce.HeatBoundaryConditions: IceWaterThermalEquilibrium + using SeawaterPolynomials.TEOS10: TEOS10EquationOfState function omip_ocean_component(grid) @@ -49,21 +55,31 @@ function omip_ocean_component(grid) return ocean end +function omip_sea_ice_component(ocean_model) + ocean_grid = ocean_model.grid + Nx, Ny, Nz = size(ocean_grid) + Hx, Hy, Hz = halo_size(ocean_grid) + TX, TY, TZ = topology(ocean_grid) -function omip_sea_ice_component(grid) - Nx, Ny, Nz = size(grid) - sea_ice_grid = LatitudeLongitudeGrid(arch, + λ = λnodes(ocean_grid, Face()) + φ = φnodes(ocean_grid, Face()) + longitude = (λ[1], λ[end]) + latitude = (φ[1], φ[end]) + + sea_ice_grid = LatitudeLongitudeGrid(arch; longitude, latitude, size = (Nx, Ny), - longitude = (0, 360), - halo = (7, 7), - latitude = (southern_limit, northern_limit), - topology = (Periodic, Bounded, Flat)) - - sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBottom(bottom_height)) + halo = (Hx, Hy), + topology = (TX, TY, Flat)) - sea_ice_ocean_heat_flux = Field{Center, Center, Nothing}(grid) + if ocean_grid isa ImmersedBoundaryGrid + h = ocean_grid.immersed_boundary.bottom_height + land = h .>= 0 + sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBoundary(land)) + end + + sea_ice_ocean_heat_flux = Field{Center, Center, Nothing}(ocean_grid) - Nz = size(grid, 3) + Nz = size(ocean_grid, 3) So = ocean_model.tracers.S ocean_surface_salinity = view(So, :, :, Nz) bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) @@ -84,11 +100,8 @@ function omip_sea_ice_component(grid) bottom_heat_boundary_condition = bottom_bc, bottom_heat_flux = sea_ice_ocean_heat_flux) - s# et!(sea_ice_model, h=ℋᵢ) - sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) return sea_ice end - diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index 98ebc03b..086996da 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -1,3 +1,4 @@ +#= using Oceananigans using Oceananigans.Architectures: arch_array using Oceananigans.Units @@ -17,6 +18,7 @@ start_time = time_ns() include("omip_components.jl") +arch = CPU() epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) start_seconds = Second(date - epoch).value @@ -24,6 +26,7 @@ start_seconds = Second(date - epoch).value # vᵢ = ecco2_field(:v_velocity, date) Te = ecco2_field(:temperature, date) Se = ecco2_field(:salinity, date) +ℋe = ecco2_field(:sea_ice_thickness, date) land = interior(Te) .< -10 interior(Te)[land] .= NaN @@ -37,10 +40,9 @@ start_time = time_ns() ##### Construct the grid ##### -arch = GPU() - -latitude = (-60, +60) -longitude = (0, 360) +latitude = (-75, -45) +#longitude = (0, 360) +longitude = (0, 90) i₁ = 4 * first(longitude) + 1 i₂ = 1440 - 4 * (360 - last(longitude)) @@ -56,6 +58,7 @@ zf = znodes(Te.grid, Face()) Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) Sᵢ = interior(Se, i₁:i₂, j₁:j₂, :) +ℋᵢ = interior(ℋe, i₁:i₂, j₁:j₂, :) # Construct bottom_height depth by analyzing T Nx, Ny, Nz = size(Tᵢ) @@ -73,7 +76,11 @@ end Tᵢ = arch_array(arch, Tᵢ) Sᵢ = arch_array(arch, Sᵢ) -@show Nx Ny Nz zf +if longitude[2] - longitude[1] == 360 + TX = Periodic +else + TX = Bounded +end grid = LatitudeLongitudeGrid(arch; latitude, longitude, size = (Nx, Ny, Nz), @@ -101,21 +108,20 @@ elapsed = time_ns() - start_time start_time = time_ns() =# +atmosphere = nothing + ocean.model.clock.time = start_seconds ocean.model.clock.iteration = 0 set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -times = ua.times +sea_ice = omip_sea_ice_component(ocean.model) #nothing +set!(sea_ice.model, h=ℋᵢ) +=# -sea_ice = nothing -radiation = Radiation() +radiation = nothing # Radiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_iteration=200) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_iteration=3) elapsed = time_ns() - start_time @info "Coupled simulation built. " * prettytime(elapsed * 1e-9) @@ -155,7 +161,7 @@ function progress(sim) @info msg end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) # Build flux outputs Jᵘ = coupled_model.fluxes.total.ocean.momentum.u @@ -185,19 +191,15 @@ outputs = merge(fields, fluxes) filename = "regional_omip_simulation" -coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, fluxes; filename * "_fluxes", - schedule = TimeInterval(1day), +coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, fluxes; + filename = filename * "_fluxes", + schedule = TimeInterval(Oceananigans.Units.day), overwrite_existing = true) -coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; filename * "_fields", +coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; + filename = filename * "_fields", indices = (:, :, Nz), - schedule = TimeInterval(1day), + schedule = TimeInterval(Oceananigans.Units.day), overwrite_existing = true) -#= -coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, - schedule = AveragedTimeInterval(1days), - overwrite_existing = true) -=# - run!(coupled_simulation) diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index 643400c5..3e306bf1 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -15,7 +15,7 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_ # Initialization if coupled_model.clock.iteration == 0 @info "Initializing coupled model ice thickness..." - h⁻ = coupled_model.previous_ice_thickness + h⁻ = coupled_model.fluxes.previous_ice_thickness hⁿ = coupled_model.sea_ice.model.ice_thickness parent(h⁻) .= parent(hⁿ) end From 6f21488fe2abd1b431b16aef86501d8221be2366 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 5 Feb 2024 12:27:07 -0500 Subject: [PATCH 121/182] Get sea ice decaying simulation running --- .../omip_components.jl | 2 +- .../regional_omip_simulation.jl | 44 ++++++++----------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl index 99374dac..980d26aa 100644 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -73,7 +73,7 @@ function omip_sea_ice_component(ocean_model) if ocean_grid isa ImmersedBoundaryGrid h = ocean_grid.immersed_boundary.bottom_height - land = h .>= 0 + land = interior(h) .>= 0 sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBoundary(land)) end diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index 086996da..59db2c89 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -1,4 +1,3 @@ -#= using Oceananigans using Oceananigans.Architectures: arch_array using Oceananigans.Units @@ -18,7 +17,7 @@ start_time = time_ns() include("omip_components.jl") -arch = CPU() +arch = GPU() epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) start_seconds = Second(date - epoch).value @@ -40,9 +39,8 @@ start_time = time_ns() ##### Construct the grid ##### -latitude = (-75, -45) -#longitude = (0, 360) -longitude = (0, 90) +latitude = (-75, -30) +longitude = (0, 360) i₁ = 4 * first(longitude) + 1 i₂ = 1440 - 4 * (360 - last(longitude)) @@ -75,6 +73,7 @@ end Tᵢ = arch_array(arch, Tᵢ) Sᵢ = arch_array(arch, Sᵢ) +ℋᵢ = arch_array(arch, ℋᵢ) if longitude[2] - longitude[1] == 360 TX = Periodic @@ -116,12 +115,12 @@ set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) sea_ice = omip_sea_ice_component(ocean.model) #nothing set!(sea_ice.model, h=ℋᵢ) -=# radiation = nothing # Radiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_iteration=3) +stop_time = start_seconds + 90days +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=stop_time) elapsed = time_ns() - start_time @info "Coupled simulation built. " * prettytime(elapsed * 1e-9) @@ -129,11 +128,6 @@ start_time = time_ns() wall_clock = Ref(time_ns()) -Nz = size(grid, 3) -Ts = view(ocean.model.tracers.T, :, :, Nz) -Ss = view(ocean.model.tracers.S, :, :, Nz) -es = view(ocean.model.tracers.e, :, :, Nz) - function progress(sim) msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) @@ -144,24 +138,18 @@ function progress(sim) u, v, w = sim.model.ocean.model.velocities msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - #= T = sim.model.ocean.model.tracers.T S = sim.model.ocean.model.tracers.S e = sim.model.ocean.model.tracers.e - Nz = size(T, 3) - msg *= @sprintf(", u★: %.2f m s⁻¹", u★) - msg *= @sprintf(", Q: %.2f W m⁻²", Q) - msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) - msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) - msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) - =# + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", maximum(T), minimum(T)) + msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) + msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) @info msg end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) # Build flux outputs Jᵘ = coupled_model.fluxes.total.ocean.momentum.u @@ -186,20 +174,26 @@ auxiliary_fields = (; N², κᶜ) fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) # Slice fields at the surface -#outputs = merge(fields, fluxes) outputs = merge(fields, fluxes) filename = "regional_omip_simulation" +#= coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, fluxes; filename = filename * "_fluxes", - schedule = TimeInterval(Oceananigans.Units.day), + schedule = TimeInterval(1days), overwrite_existing = true) +=# coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; filename = filename * "_fields", indices = (:, :, Nz), - schedule = TimeInterval(Oceananigans.Units.day), + schedule = TimeInterval(1days), + overwrite_existing = true) + +coupled_simulation.output_writers[:seaice] = JLD2OutputWriter(sea_ice.model, (; h = sea_ice.model.ice_thickness); + filename = filename * "_sea_ice_thickness", + schedule = TimeInterval(1days), overwrite_existing = true) run!(coupled_simulation) From 989593bae65f210e2d675ed6006acf5118fba18d Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 5 Feb 2024 14:17:12 -0700 Subject: [PATCH 122/182] Working on fixed point iteration --- .../single_column_omip_simulation.jl | 14 +- .../surface_fluxes.jl | 5 +- .../CrossRealmFluxes/CrossRealmFluxes.jl | 1 + .../compute_turbulent_fluxes.jl | 276 ++++++++++++++++++ .../ocean_sea_ice_surface_fluxes.jl | 52 ++-- .../similarity_theory_turbulent_fluxes.jl | 57 ++-- src/OceanSeaIceModels/OceanSeaIceModels.jl | 3 + 7 files changed, 333 insertions(+), 75 deletions(-) create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 4d12303a..1a2b83db 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -12,6 +12,8 @@ using GLMakie using Printf using Dates +include("omip_components.jl") + locations = ( #eastern_mediterranean = (λ = 30, φ = 32), ocean_station_papa = (λ = 215, φ = 50), @@ -21,13 +23,11 @@ locations = ( tasman_southern_ocean = (λ = 145, φ = -55), ) -for location in keys(locations) +#for location in keys(locations) +location = :ocean_station_papa -#location = :ocean_station_papa start_time = time_ns() - include("omip_ocean_component.jl") - epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) start_seconds = Second(date - epoch).value @@ -115,7 +115,7 @@ for location in keys(locations) Ndays = 365 Nt = 8 * Ndays - atmosphere = JRA55_prescribed_atmosphere(grid, 1:Nt) #, 1:21) + atmosphere = JRA55_prescribed_atmosphere(1:2, backend=InMemory()) #, 1:21) elapsed = time_ns() - start_time @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() @@ -148,6 +148,7 @@ for location in keys(locations) radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + #= coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 60days) elapsed = time_ns() - start_time @@ -400,5 +401,6 @@ for location in keys(locations) record(fig, "$(location)_single_column_simulation.mp4", 1:Nt, framerate=24) do nn @info "Drawing frame $nn of $Nt..." n[] = nn - end +# end end +=# diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl index 0dc447be..c198c102 100644 --- a/experiments/prototype_omip_simulation/surface_fluxes.jl +++ b/experiments/prototype_omip_simulation/surface_fluxes.jl @@ -16,6 +16,7 @@ start_time = time_ns() include("omip_components.jl") +arch = CPU() epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) start_seconds = Second(date - epoch).value @@ -36,8 +37,6 @@ start_time = time_ns() ##### Construct the grid ##### -arch = GPU() - latitude = (-75, +65) longitude = (0, 360) @@ -129,7 +128,7 @@ Jᵛ = coupled_model.fluxes.total.ocean.momentum.v Jᵀ = coupled_model.fluxes.total.ocean.tracers.T Jˢ = coupled_model.fluxes.total.ocean.tracers.S -E = coupled_model.fluxes.turbulent.fields.freshwater +E = coupled_model.fluxes.turbulent.fields.water_vapor Fʳ = atmosphere.freshwater_flux.rain Fˢ = atmosphere.freshwater_flux.snow diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index f14c8b56..9dd9ebfa 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -60,6 +60,7 @@ function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) end include("radiation.jl") +include("compute_turbulent_fluxes.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") # include("atmosphere_sea_ice_fluxes.jl") diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl new file mode 100644 index 00000000..3d20bad9 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl @@ -0,0 +1,276 @@ +using Printf + +import Thermodynamics as AtmosphericThermodynamics + +using Thermodynamics: PhasePartition + +@inline update_turbulent_flux_fields!(::Nothing, args...) = nothing + +@inline function update_turbulent_flux_fields!(fields, i, j, grid, fluxes) + Qv = fields.latent_heat + Qc = fields.sensible_heat + Fv = fields.water_vapor + τx = fields.x_momentum + τy = fields.y_momentum + kᴺ = size(grid, 3) # index of the top ocean cell + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) + @inbounds begin + # +0: cooling, -0: heating + Qv[i, j, 1] = ifelse(inactive, 0, fluxes.latent_heat) + Qc[i, j, 1] = ifelse(inactive, 0, fluxes.sensible_heat) + Fv[i, j, 1] = ifelse(inactive, 0, fluxes.water_vapor) + τx[i, j, 1] = ifelse(inactive, 0, fluxes.x_momentum) + τy[i, j, 1] = ifelse(inactive, 0, fluxes.y_momentum) + end + return nothing +end + +@inline compute_turbulent_fluxes(turbulent_fluxes, atmos_state, ocean_state) = + compute_turbulent_fluxes(turbulent_fluxes.roughness_lengths, turbulent_fluxes, atmos_state, ocean_state) + +##### +##### Struct that represents a 3-tuple of momentum, heat, and water vapor +##### + +struct SimilarityScales{U, T, Q} + momentum :: U + temperature :: T + water_vapor :: Q +end + +# Convenience default with water_vapor component = nothing +SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature, nothing) + +##### +##### Interface into SurfaceFluxes.jl +##### + +# This is the case that SurfaceFluxes.jl can do +const NothingVaporRoughnessLength = SimilarityScales{<:Number, <:Number, Nothing} + +@inline function compute_turbulent_fluxes(roughness_lengths::NothingVaporRoughnessLength, + turbulent_fluxes, + atmos_state, + ocean_state) + + # Constant roughness lengths + ℓu = roughness_lengths.momentum + ℓθ = roughness_lengths.temperature + + # Solve for the surface fluxes with initial roughness length guess + Uᵍ = zero(zm) # gustiness + β = one(zm) # surface "resistance" + values = SurfaceFluxes.ValuesOnly(atmos_state, ocean_state, ℓu, ℓθ, Uᵍ, β) + conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + + fluxes = (; + sensible_heat = conditions.shf, + latent_heat = conditions.lhf, + water_vapor = conditions.evaporation, + x_momentum = conditions.ρτxz, + y_momentum = conditions.ρτyz, + ) + + return fluxes +end + +##### +##### Fixed-point iteration for roughness length +##### + +const ConstantRoughnessLength = SimilarityScales{<:Number, <:Number, <:Number} + +struct SimilarityFunction{FT, C} + a :: FT + b :: FT + c :: C +end + +@inline function (ψ::SimilarityFunction)(Ri) + a = ψ.a + b = ψ.b + c = ψ.c + + ϕ⁻¹ = (1 - b * Ri)^c + ψ_unstable = log((1 + ϕ⁻¹)^2 * (1 + ϕ⁻¹^2) / 8) - (4 * atan(ϕ⁻¹) + π) / 2 + ψ_stable = - a * Ri + + return ifelse(Ri < 0, ψ_unstable, ψ_stable) +end + +struct OneQuarter end +struct OneHalf end + +import Base: ^ +@inline ^(x, ::OneQuarter) = sqrt(sqrt(x)) +@inline ^(x, ::OneHalf) = sqrt(x) + +function businger_similarity_functions(FT=Float64) + au = convert(FT, 4.7) + bu = convert(FT, 15) + cu = OneQuarter() + ψu = SimilarityFunction(au, bu, cu) + + ah = convert(FT, 6.35) + bh = convert(FT, 9) + ch = OneHalf() + ψh = SimilarityFunction(ah, bh, ch) + + ψq = ψh + + return SimilarityScales(ψu, ψh, ψq) +end + +@inline function bulk_factor(ψ, h, ℓ, Ri) + L★ = h / Ri + χ⁻¹ = log(h / ℓ) - ψ(Ri) + ψ(ℓ / L★) + return 1 / χ⁻¹ +end + +@inline function buoyancy_scale(θ★, q★, 𝒬, parameters) + ℂ = parameters.thermodynamics_parameters + + 𝒯₀ = AtmosphericThermodynamics.virtual_temperature(ℂ, 𝒬) + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) + q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬) + + ε = AtmosphericThermodynamics.Parameters.molmass_ratio(parameters) + δ = ε - 1 + g = SurfaceFluxes.Parameters.grav(parameters) + + b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * θ₀ * q★) + + return b★ +end + + +@inline function state_differences(ℂ, 𝒰₁, 𝒰₀) + z₁ = 𝒰₁.z + z₀ = 𝒰₀.z + Δh = z₁ - z₀ + + U₁ = 𝒰₁.u + U₀ = 𝒰₀.u + + @inbounds begin + Δu = U₁[1] - U₀[1] + Δv = U₁[2] - U₀[2] + end + + # Thermodynamic state + 𝒬₁ = 𝒰₁.ts + 𝒬₀ = 𝒰₀.ts + + θ₁ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₁) + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₀) + Δθ = θ₁ - θ₀ + + q₁ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₁) + q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₀) + Δq = q₁ - q₀ + + return Δh, Δu, Δv, Δθ, Δq +end + +@inline function compute_turbulent_fluxes(roughness_lengths::ConstantRoughnessLength, + turbulent_fluxes, + atmos_state, + ocean_state) + + # Prescribed difference between two states + ℂₐ = thermodynamics_params(turbulent_fluxes) + Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, ocean_state) + #differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) + differences = (; u=Δu, v=Δv, θ=zero(Δθ), q=zero(Δq), h=Δh) + + # Solve for the characteristic scales u★, θ★, q★, and thus for fluxes. + Γ₀ = Γ★ = SimilarityScales(1e-6, 1e-6, 1e-6) + + for iter = 1:10 + Γ★ = refine_characteristic_scales(Γ★, + roughness_lengths, + turbulent_fluxes.similarity_functions, + differences, + ocean_state, + turbulent_fluxes) + + msg = @sprintf("Iter: %d, u★: %.4e, θ★: %.4e, q★: %.4e", iter, u★ , θ★, q★) + @info msg + end + + u★ = Γ★.momentum + θ★ = Γ★.temperature + q★ = Γ★.water_vapor + + # u★² ≡ sqrt(τx² + τy²) + τx = u★^2 * Δu / sqrt(Δu^2 + Δv^2) + τy = u★^2 * Δv / sqrt(Δu^2 + Δv^2) + + 𝒬ₐ = atmos_state.ts + ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) + cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity + ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) + + fluxes = (; + water_vapor = ρₐ * u★ * q★, + sensible_heat = ρₐ * cₚ * u★ * θ★, + latent_heat = ρₐ * u★ * q★ * ℰv, + x_momentum = ρₐ * τx, + y_momentum = ρₐ * τy, + ) + + return fluxes +end + +function refine_characteristic_scales(estimated_characteristic_scales, + roughness_lengths, + similarity_functions, + differences, + ocean_state, + similarity_parameters) + + # "initial" scales because we will recompute them + u★ = estimated_characteristic_scales.momentum + θ★ = estimated_characteristic_scales.temperature + q★ = estimated_characteristic_scales.water_vapor + + # Extract roughness lengths + ℓu = roughness_lengths.momentum + ℓθ = roughness_lengths.temperature + ℓq = roughness_lengths.water_vapor + + # Compute flux Richardson number + h = differences.h + ϰ = similarity_parameters.von_karman_constant + + 𝒬ₒ = ocean_state.ts # thermodyanmic state + b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, similarity_parameters) + Riₕ = - ϰ * h * b★ / u★^2 + + # Compute similarity functions + fu = similarity_functions.momentum + fθ = similarity_functions.temperature + fq = similarity_functions.water_vapor + + χu = bulk_factor(fu, h, ℓu, Riₕ) + χθ = bulk_factor(fθ, h, ℓθ, Riₕ) + χq = bulk_factor(fq, h, ℓq, Riₕ) + + Δu = differences.u + Δv = differences.v + Δθ = differences.θ + Δq = differences.q + + u★ = ϰ * χu * sqrt(Δu^2 + Δv^2) + θ★ = ϰ * χθ * Δθ + q★ = ϰ * χq * Δq + + return SimilarityScales(u★, θ★, q★) +end + +struct GravityWaveRoughnessLength{FT} + gravitational_acceleration :: FT + gravity_wave_parameter :: FT + laminar_parameter :: FT +end + diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index d63b0af6..04ff3286 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -64,7 +64,7 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; ocean_heat_capacity = convert(FT, ocean_heat_capacity) freshwater_density = convert(FT, freshwater_density) - if isnothing(atmosphere) + if !isnothing(atmosphere) # It's the "thermodynamics gravitational acceleration" # (as opposed to the one used for the free surface) gravitational_acceleration = ocean.model.buoyancy.model.gravitational_acceleration @@ -241,52 +241,39 @@ const c = Center() # Build thermodynamic and dynamic states in the atmosphere and surface. # Notation: - # ⋅ ϕ ≡ thermodynamic state vector - # ⋅ Φ ≡ "dynamic" state vector (thermodynamics + reference height + velocity) + # ⋅ 𝒬 ≡ thermodynamic state vector + # ⋅ 𝒰 ≡ "dynamic" state vector (thermodynamics + reference height + velocity) ℂₐ = atmosphere_thermodynamics_parameters - ϕₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) + 𝒬ₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) hₐ = atmosphere_reference_height # elevation of atmos variables relative to surface Uₐ = SVector(uₐ, vₐ) - Φₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, ϕₐ) + 𝒰ₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, 𝒬ₐ) # Build surface state with saturated specific humidity surface_type = AtmosphericThermodynamics.Liquid() - qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, ϕₐ, + qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, 𝒬ₐ, turbulent_fluxes.water_mole_fraction, turbulent_fluxes.water_vapor_saturation, surface_type) # Thermodynamic and dynamic surface state - ϕ₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₒ, qₒ) + 𝒬₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₒ, qₒ) h₀ = zero(grid) # surface height Uₒ = SVector(uₒ, vₒ) - Φ₀ = dynamic_surface_state = SurfaceFluxes.StateValues(h₀, Uₒ, ϕ₀) + 𝒰₀ = dynamic_ocean_state = SurfaceFluxes.StateValues(h₀, Uₒ, 𝒬₀) - # Initial guess for the roughness length. - FT = eltype(grid) - zᵐ = zʰ = convert(FT, 5e-4) # τ = 0.3 => u★ = sqrt(τ / ρₐ) ~ z₀ ~ 5e-4 - - # Solve for the surface fluxes with initial roughness length guess - Uᵍ = zero(grid) # gustiness - β = one(grid) # surface "resistance" - values = SurfaceFluxes.ValuesOnly(Φₐ, Φ₀, zᵐ, zʰ, Uᵍ, β) - conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) - - # It's like a fixed point iteration - g = turbulent_fluxes.gravitational_acceleration - α = convert(FT, 0.011) # Charnock parameter - u★ = conditions.ustar - zᵐ = zʰ = α * u★^2 / g - values = SurfaceFluxes.ValuesOnly(Φₐ, Φ₀, zᵐ, zʰ, Uᵍ, β) - conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) - + fluxes = compute_turbulent_fluxes(turbulent_fluxes.roughness_lengths, + turbulent_fluxes, + dynamic_atmos_state, + dynamic_ocean_state) + # Compute heat fluxes, bulk flux first + Qc = fluxes.sensible_heat # sensible or "conductive" heat flux + Qe = fluxes.latent_heat # latent or "evaporative" heat flux Qd = net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation_properties) Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state, ocean_temperature_units) - Qc = conditions.shf # sensible or "conductive" heat flux - Qe = conditions.lhf # latent or "evaporative" heat flux ΣQ = Qd + Qu + Qc + Qe # Convert from a mass flux to a volume flux (aka velocity). @@ -294,12 +281,11 @@ const c = Center() ρᶠ = freshwater_density ΣF = - M / ρᶠ - # Apparently, conditions.evaporation is a mass flux of water. # So, we divide by the density of freshwater. - E = conditions.evaporation / ρᶠ + E = fluxes.water_vapor / ρᶠ ΣF += E - update_turbulent_flux_fields!(turbulent_fluxes.fields, i, j, grid, conditions, ρᶠ) + update_turbulent_flux_fields!(turbulent_fluxes.fields, i, j, grid, fluxes) # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes Jᵘ = centered_velocity_fluxes.u @@ -310,8 +296,8 @@ const c = Center() ρₒ = ocean_reference_density cₒ = ocean_heat_capacity - atmos_ocean_Jᵘ = conditions.ρτxz / ρₒ - atmos_ocean_Jᵛ = conditions.ρτyz / ρₒ + atmos_ocean_Jᵘ = fluxes.x_momentum / ρₒ + atmos_ocean_Jᵛ = fluxes.y_momentum / ρₒ atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) atmos_ocean_Jˢ = - Sₒ * ΣF diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 81bc6a40..2bb3edc2 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -9,6 +9,7 @@ using SurfaceFluxes.UniversalFunctions: BusingerParams, BusingerType using ..PrescribedAtmospheres: PrescribedAtmosphereThermodynamicsParameters import Thermodynamics as AtmosphericThermodynamics +import Thermodynamics.Parameters: molmass_ratio import SurfaceFluxes.Parameters: thermodynamics_params, @@ -25,7 +26,7 @@ struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, R, F} <: AbstractS gravitational_acceleration :: FT von_karman_constant :: FT bulk_velocity_scale :: ΔU - similarity_function :: UF + similarity_functions :: UF thermodynamics_parameters :: TP water_vapor_saturation :: S water_mole_fraction :: W @@ -35,9 +36,10 @@ end const STTF = SimilarityTheoryTurbulentFluxes @inline thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters -@inline uf_params(fluxes::STTF) = fluxes.similarity_function +@inline uf_params(fluxes::STTF) = fluxes.similarity_functions @inline von_karman_const(fluxes::STTF) = fluxes.von_karman_constant @inline grav(fluxes::STTF) = fluxes.gravitational_acceleration +@inline molmass_ratio(fluxes::STTF) = molmass_ratio(fluxes.thermodynamics_parameters) @inline universal_func_type(fluxes::STTF{<:Any, <:Any, <:BusingerParams}) = BusingerType() @@ -84,60 +86,49 @@ function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) end +function default_roughness_lengths(FT=Float64) + momentum = convert(FT, 1e-4) + heat = convert(FT, 1e-4) + return SimilarityScales(momentum, heat) +end + const PATP = PrescribedAtmosphereThermodynamicsParameters function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; - gravitational_acceleration = convert(FT, 9.80665), + gravitational_acceleration = default_gravitational_acceleration, bulk_velocity_scale = nothing, von_karman_constant = convert(FT, 0.4), - similarity_function = default_businger_parameters(FT), + similarity_functions = businger_similarity_functions(FT), thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), + # roughness_lengths = default_roughness_lengths(FT), + roughness_lengths = SimilarityScales(1e-3, 1e-3, 1e-3), fields = nothing) - return SimilarityTheoryTurbulentFluxes(gravitational_acceleration, - von_karman_constant, + return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), + convert(FT, von_karman_constant), bulk_velocity_scale, - similarity_function, + similarity_functions, thermodynamics_parameters, water_vapor_saturation, water_mole_fraction, - nothing, + roughness_lengths, fields) end function SimilarityTheoryTurbulentFluxes(grid::AbstractGrid; kw...) - freshwater = Field{Center, Center, Nothing}(grid) - latent_heat = Field{Center, Center, Nothing}(grid) + water_vapor = Field{Center, Center, Nothing}(grid) + latent_heat = Field{Center, Center, Nothing}(grid) sensible_heat = Field{Center, Center, Nothing}(grid) + x_momentum = Field{Center, Center, Nothing}(grid) + y_momentum = Field{Center, Center, Nothing}(grid) - fields = (; latent_heat, sensible_heat, freshwater) + fields = (; latent_heat, sensible_heat, water_vapor, x_momentum, y_momentum) return SimilarityTheoryTurbulentFluxes(eltype(grid); kw..., fields) end -@inline update_turbulent_flux_fields!(::Nothing, args...) = nothing - -@inline function update_turbulent_flux_fields!(fields, i, j, grid, conditions, ρᶠ) - Qv = fields.latent_heat - Qc = fields.sensible_heat - Fv = fields.freshwater - kᴺ = size(grid, 3) # index of the top ocean cell - inactive = inactive_node(i, j, kᴺ, grid, c, c, c) - @inbounds begin - # +0: cooling, -0: heating - Qv[i, j, 1] = ifelse(inactive, 0, conditions.lhf) - Qc[i, j, 1] = ifelse(inactive, 0, conditions.shf) - - # "Salt flux" has the opposite sign of "freshwater flux". - # E > 0 implies that freshwater is fluxing upwards. - Fvᵢ = conditions.evaporation / ρᶠ # convert to volume flux - Fv[i, j, 1] = ifelse(inactive, Fvᵢ, 0) - end - return nothing -end - # See SurfaceFluxes.jl for other parameter set options. default_businger_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), a_m = convert(FT, 4.7), @@ -314,7 +305,7 @@ end ℓu = roughness_lengths.momentum ℓθ = roughness_lengths.heat - ℓq = roughness_lengths.moisture + ℓq = roughness_lengths.water_vapor fluxes = (; diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index d4620bbd..c4f31f15 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -31,6 +31,9 @@ function heat_capacity end sea_ice_thickness(::Nothing) = nothing sea_ice_concentration(::Nothing) = nothing +const default_gravitational_acceleration = 9.80665 +const default_freshwater_density = 1000 + ##### ##### Some implementation ##### From ba990217f6ca3f732742465ead0732b2f2031a20 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 6 Feb 2024 10:09:51 -0700 Subject: [PATCH 123/182] Updates for single column simulation --- .../prototype_omip_simulation/Manifest.toml | 10 +- .../single_column_omip_simulation.jl | 6 +- src/DataWrangling/JRA55.jl | 34 ++++-- .../compute_turbulent_fluxes.jl | 34 ++++-- .../ocean_sea_ice_surface_fluxes.jl | 115 +++++++++--------- 5 files changed, 110 insertions(+), 89 deletions(-) diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 3c62abd9..6e0d7744 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0-beta3" +julia_version = "1.10.0-rc1" manifest_format = "2.0" project_hash = "672cbef2c7d6776d40e6432e74f2ade4088e87e6" @@ -1014,7 +1014,7 @@ 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.0.1+1" +version = "8.4.0+0" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -1304,9 +1304,7 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "487b4a79cda089c898fdc9c0c21061712f0fc062" -repo-rev = "ss-glw/time-bcs" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +path = "/Users/gregorywagner/Projects/Oceananigans.jl" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.7" @@ -1955,7 +1953,7 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.0+1" +version = "7.2.1+1" [[deps.SurfaceFluxes]] deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 1a2b83db..0ddc255f 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -120,7 +120,7 @@ location = :ocean_station_papa @info "Atmosphere built. " * prettytime(elapsed * 1e-9) start_time = time_ns() - ocean.model.clock.time = start_seconds + # ocean.model.clock.time = start_seconds ocean.model.clock.iteration = 0 set!(ocean.model, T=Tc, S=Sc, e=1e-6) @@ -148,7 +148,6 @@ location = :ocean_station_papa radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) - #= coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 60days) elapsed = time_ns() - start_time @@ -195,7 +194,7 @@ location = :ocean_station_papa Jᵛ = coupled_model.fluxes.total.ocean.momentum.v Jᵀ = coupled_model.fluxes.total.ocean.tracers.T Jˢ = coupled_model.fluxes.total.ocean.tracers.S - E = coupled_model.fluxes.turbulent.fields.freshwater + E = coupled_model.fluxes.turbulent.fields.water_vapor Qse = coupled_model.fluxes.turbulent.fields.sensible_heat Qla = coupled_model.fluxes.turbulent.fields.latent_heat ρₒ = coupled_model.fluxes.ocean_reference_density @@ -240,6 +239,7 @@ location = :ocean_station_papa run!(coupled_simulation) + #= filename *= ".jld2" ut = FieldTimeSeries(filename, "u") diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 9c7cca63..d730ea3e 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -273,7 +273,9 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; totally_in_memory = backend isa InMemory{Colon} isfile(jld2_filename) && rm(jld2_filename) + #= + # TODO: figure out how to use existing jld2 files if isfile(jld2_filename) isnothing(time_indices) && (time_indices = Colon()) @@ -377,7 +379,9 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; # Make times into an array for later preprocessing !totally_in_memory && (times = collect(times)) - native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; boundary_conditions) + native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + time_extrapolation, + boundary_conditions) # Fill the data in a GPU-friendly manner copyto!(interior(native_fts, :, :, 1, :), data) @@ -475,6 +479,7 @@ JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = # TODO: allow the user to pass dates function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, + time_extrapolation = Cyclical(), reference_height = 2, # meters other_kw...) @@ -491,15 +496,20 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = InMemory(Nf) end - ua = JRA55_field_time_series(:eastward_velocity; time_indices, backend, architecture, other_kw...) - va = JRA55_field_time_series(:northward_velocity; time_indices, backend, architecture, other_kw...) - Ta = JRA55_field_time_series(:temperature; time_indices, backend, architecture, other_kw...) - qa = JRA55_field_time_series(:specific_humidity; time_indices, backend, architecture, other_kw...) - pa = JRA55_field_time_series(:sea_level_pressure; time_indices, backend, architecture, other_kw...) - Fra = JRA55_field_time_series(:rain_freshwater_flux; time_indices, backend, architecture, other_kw...) - Fsn = JRA55_field_time_series(:snow_freshwater_flux; time_indices, backend, architecture, other_kw...) - Ql = JRA55_field_time_series(:downwelling_longwave_radiation; time_indices, backend, architecture, other_kw...) - Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; time_indices, backend, architecture, other_kw...) + kw = (; time_indices, time_extrapolation, backend, architecture) + kw = merge(kw, other_kw) + + @show kw + + ua = JRA55_field_time_series(:eastward_velocity; kw...) + va = JRA55_field_time_series(:northward_velocity; kw...) + Ta = JRA55_field_time_series(:temperature; kw...) + qa = JRA55_field_time_series(:specific_humidity; kw...) + pa = JRA55_field_time_series(:sea_level_pressure; kw...) + Fra = JRA55_field_time_series(:rain_freshwater_flux; kw...) + Fsn = JRA55_field_time_series(:snow_freshwater_flux; kw...) + Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) + Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) # NOTE: these have a different frequency than 3 hours so some changes are needed to # JRA55_field_time_series to support them. @@ -514,8 +524,8 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); tracers = (T = Ta, q = qa) - freshwater_flux = (rain = Fra, - snow = Fsn) + freshwater_flux = (rain = Fra, + snow = Fsn) # rivers = Fv_JRA55, # icebergs = Fi_JRA55) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl index 3d20bad9..b8481822 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl @@ -3,6 +3,7 @@ using Printf import Thermodynamics as AtmosphericThermodynamics using Thermodynamics: PhasePartition +using KernelAbstractions.Extras.LoopInfo: @unroll @inline update_turbulent_flux_fields!(::Nothing, args...) = nothing @@ -91,8 +92,10 @@ end b = ψ.b c = ψ.c - ϕ⁻¹ = (1 - b * Ri)^c + Ri⁻ = min(zero(Ri), Ri) + ϕ⁻¹ = (1 - b * Ri⁻)^c ψ_unstable = log((1 + ϕ⁻¹)^2 * (1 + ϕ⁻¹^2) / 8) - (4 * atan(ϕ⁻¹) + π) / 2 + ψ_stable = - a * Ri return ifelse(Ri < 0, ψ_unstable, ψ_stable) @@ -180,13 +183,12 @@ end # Prescribed difference between two states ℂₐ = thermodynamics_params(turbulent_fluxes) Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, ocean_state) - #differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) - differences = (; u=Δu, v=Δv, θ=zero(Δθ), q=zero(Δq), h=Δh) + differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) # Solve for the characteristic scales u★, θ★, q★, and thus for fluxes. - Γ₀ = Γ★ = SimilarityScales(1e-6, 1e-6, 1e-6) + Γ₀ = Γ★ = SimilarityScales(1e-3, 1e-3, 1e-3) - for iter = 1:10 + @unroll for iter = 1:10 Γ★ = refine_characteristic_scales(Γ★, roughness_lengths, turbulent_fluxes.similarity_functions, @@ -194,8 +196,14 @@ end ocean_state, turbulent_fluxes) - msg = @sprintf("Iter: %d, u★: %.4e, θ★: %.4e, q★: %.4e", iter, u★ , θ★, q★) - @info msg + @debug begin + u★ = Γ★.momentum + θ★ = Γ★.temperature + q★ = Γ★.water_vapor + # u★² = Cᴰ * (Δu² + Δv²) + Cᴰ = u★^2 / (Δu^2 + Δv^2) + @sprintf("Iter: %d, Cᴰ: %.4e, u★: %.4e, θ★: %.4e, q★: %.4e", iter, Cᴰ, u★ , θ★, q★) + end end u★ = Γ★.momentum @@ -222,12 +230,12 @@ end return fluxes end -function refine_characteristic_scales(estimated_characteristic_scales, - roughness_lengths, - similarity_functions, - differences, - ocean_state, - similarity_parameters) +@inline function refine_characteristic_scales(estimated_characteristic_scales, + roughness_lengths, + similarity_functions, + differences, + ocean_state, + similarity_parameters) # "initial" scales because we will recompute them u★ = estimated_characteristic_scales.momentum diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 04ff3286..5661e5ad 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -68,9 +68,9 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; # It's the "thermodynamics gravitational acceleration" # (as opposed to the one used for the free surface) gravitational_acceleration = ocean.model.buoyancy.model.gravitational_acceleration - turbulent_fluxes = SimilarityTheoryTurbulentFluxes(grid; gravitational_acceleration) + similarity_theory = SimilarityTheoryTurbulentFluxes(grid; gravitational_acceleration) else - turbulent_fluxes = nothing + similarity_theory = nothing end prescribed_fluxes = nothing @@ -109,7 +109,7 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; total_fluxes = (; ocean=total_ocean_fluxes) - return OceanSeaIceSurfaceFluxes(turbulent_fluxes, + return OceanSeaIceSurfaceFluxes(similarity_theory, prescribed_fluxes, total_fluxes, radiation, @@ -152,7 +152,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) v = coupled_model.fluxes.total.ocean.momentum.v) net_tracer_fluxes = coupled_model.fluxes.total.ocean.tracers - turbulent_fluxes = coupled_model.fluxes.turbulent + similarity_theory = coupled_model.fluxes.turbulent prescribed_fluxes = coupled_model.fluxes.prescribed radiation_properties = coupled_model.fluxes.radiation @@ -163,7 +163,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) grid, clock, centered_velocity_fluxes, net_tracer_fluxes, - turbulent_fluxes, + similarity_theory, atmosphere.freshwater_flux, atmosphere.downwelling_radiation, radiation_properties, @@ -189,12 +189,13 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) end const c = Center() +const f = Face() @kernel function compute_atmosphere_ocean_turbulent_fluxes!(grid, clock, centered_velocity_fluxes, net_tracer_fluxes, - turbulent_fluxes, + similarity_theory, prescribed_freshwater_flux, downwelling_radiation, radiation_properties, @@ -210,6 +211,7 @@ const c = Center() ice_concentration) i, j = @index(Global, NTuple) + kᴺ = size(grid, 3) time = Time(clock.time) @@ -222,21 +224,24 @@ const c = Center() Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) Sₒ = ocean_state.S[i, j, 1] - # Atmos state - X = node(i, j, 1, grid, c, c, c) + # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) + # The third index "k" should not matter but we put the correct index to get + # a surface node anyways. + X = node(i, j, kᴺ + 1, grid, c, c, f) - uₐ = interpolate_atmos_field_time_series(atmos_state.u, X, time, atmos_grid) - vₐ = interpolate_atmos_field_time_series(atmos_state.v, X, time, atmos_grid) + uₐ = interp_atmos_time_series(atmos_state.u, X, time, atmos_grid) + vₐ = interp_atmos_time_series(atmos_state.v, X, time, atmos_grid) - Tₐ = interpolate_atmos_field_time_series(atmos_state.T, X, time, atmos_grid) - pₐ = interpolate_atmos_field_time_series(atmos_state.p, X, time, atmos_grid) - qₐ = interpolate_atmos_field_time_series(atmos_state.q, X, time, atmos_grid) + Tₐ = interp_atmos_time_series(atmos_state.T, X, time, atmos_grid) + pₐ = interp_atmos_time_series(atmos_state.p, X, time, atmos_grid) + qₐ = interp_atmos_time_series(atmos_state.q, X, time, atmos_grid) - Qs = interpolate_atmos_field_time_series(downwelling_radiation.shortwave, X, time, atmos_grid) - Qℓ = interpolate_atmos_field_time_series(downwelling_radiation.longwave, X, time, atmos_grid) + Qs = interp_atmos_time_series(downwelling_radiation.shortwave, X, time, atmos_grid) + Qℓ = interp_atmos_time_series(downwelling_radiation.longwave, X, time, atmos_grid) - # Accumulate freshwater mass fluxes. Rain, snow, runoff -- all freshwater. - M = interpolate_atmos_field_time_series(prescribed_freshwater_flux, X, time, atmos_grid) + # Accumulate mass fluxes of freshwater due to rain, snow, rivers, + # icebergs, and whatever else. + M = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_grid) end # Build thermodynamic and dynamic states in the atmosphere and surface. @@ -253,8 +258,8 @@ const c = Center() # Build surface state with saturated specific humidity surface_type = AtmosphericThermodynamics.Liquid() qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, 𝒬ₐ, - turbulent_fluxes.water_mole_fraction, - turbulent_fluxes.water_vapor_saturation, + similarity_theory.water_mole_fraction, + similarity_theory.water_vapor_saturation, surface_type) # Thermodynamic and dynamic surface state @@ -264,28 +269,29 @@ const c = Center() Uₒ = SVector(uₒ, vₒ) 𝒰₀ = dynamic_ocean_state = SurfaceFluxes.StateValues(h₀, Uₒ, 𝒬₀) - fluxes = compute_turbulent_fluxes(turbulent_fluxes.roughness_lengths, - turbulent_fluxes, - dynamic_atmos_state, - dynamic_ocean_state) + turbulent_fluxes = compute_turbulent_fluxes(similarity_theory.roughness_lengths, + similarity_theory, + dynamic_atmos_state, + dynamic_ocean_state) # Compute heat fluxes, bulk flux first - Qc = fluxes.sensible_heat # sensible or "conductive" heat flux - Qe = fluxes.latent_heat # latent or "evaporative" heat flux + Qc = turbulent_fluxes.sensible_heat # sensible or "conductive" heat flux + Qv = turbulent_fluxes.latent_heat # latent heat flux associated with vapor tranpsort Qd = net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation_properties) Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state, ocean_temperature_units) - ΣQ = Qd + Qu + Qc + Qe + ΣQ = Qd + Qu + Qc + Qv - # Convert from a mass flux to a volume flux (aka velocity). + # Convert from a mass flux to a volume flux (aka velocity) + # by dividing by the density of freshwater. # Also switch the sign, for some reason we are given freshwater flux as positive down. ρᶠ = freshwater_density ΣF = - M / ρᶠ - # So, we divide by the density of freshwater. - E = fluxes.water_vapor / ρᶠ - ΣF += E + # Add the contribution from the turbulent water vapor flux + Fv = turbulent_fluxes.water_vapor / ρᶠ + ΣF += Fv - update_turbulent_flux_fields!(turbulent_fluxes.fields, i, j, grid, fluxes) + update_turbulent_flux_fields!(similarity_theory.fields, i, j, grid, turbulent_fluxes) # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes Jᵘ = centered_velocity_fluxes.u @@ -296,13 +302,12 @@ const c = Center() ρₒ = ocean_reference_density cₒ = ocean_heat_capacity - atmos_ocean_Jᵘ = fluxes.x_momentum / ρₒ - atmos_ocean_Jᵛ = fluxes.y_momentum / ρₒ + atmos_ocean_Jᵘ = turbulent_fluxes.x_momentum / ρₒ + atmos_ocean_Jᵛ = turbulent_fluxes.y_momentum / ρₒ atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) atmos_ocean_Jˢ = - Sₒ * ΣF # Mask fluxes over land for convenience - kᴺ = size(grid, 3) # index of the top ocean cell inactive = inactive_node(i, j, kᴺ, grid, c, c, c) @inbounds begin @@ -324,7 +329,6 @@ end @inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) α = stateindex(radiation.reflection.ocean, i, j, 1, time) - return @inbounds - (1 - α) * Qs - Qℓ end @@ -344,29 +348,30 @@ end ##### Utility for interpolating tuples of fields ##### -# Note: assumes loc = (c, c, c) -@inline interpolate_atmos_field_time_series(J, x, t, grid) = - interpolate(x, t, J, (c, c, c), grid) +# Note: assumes loc = (c, c, c) (and the third location should +# not matter.) +@inline interp_atmos_time_series(J, X, time, grid) = + interpolate(X, time, J, (c, c, c), grid) -@inline interpolate_atmos_field_time_series(ΣJ::NamedTuple, args...) = - interpolate_atmos_field_time_series(values(ΣJ), args...) +@inline interp_atmos_time_series(ΣJ::NamedTuple, args...) = + interp_atmos_time_series(values(ΣJ), args...) -@inline interpolate_atmos_field_time_series(ΣJ::Tuple{<:Any}, args...) = - interpolate_atmos_field_time_series(ΣJ[1], args...) + - interpolate_atmos_field_time_series(ΣJ[2], args...) +@inline interp_atmos_time_series(ΣJ::Tuple{<:Any}, args...) = + interp_atmos_time_series(ΣJ[1], args...) + + interp_atmos_time_series(ΣJ[2], args...) -@inline interpolate_atmos_field_time_series(ΣJ::Tuple{<:Any, <:Any}, args...) = - interpolate_atmos_field_time_series(ΣJ[1], args...) + - interpolate_atmos_field_time_series(ΣJ[2], args...) +@inline interp_atmos_time_series(ΣJ::Tuple{<:Any, <:Any}, args...) = + interp_atmos_time_series(ΣJ[1], args...) + + interp_atmos_time_series(ΣJ[2], args...) -@inline interpolate_atmos_field_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any}, args...) = - interpolate_atmos_field_time_series(ΣJ[1], args...) + - interpolate_atmos_field_time_series(ΣJ[2], args...) + - interpolate_atmos_field_time_series(ΣJ[3], args...) +@inline interp_atmos_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any}, args...) = + interp_atmos_time_series(ΣJ[1], args...) + + interp_atmos_time_series(ΣJ[2], args...) + + interp_atmos_time_series(ΣJ[3], args...) -@inline interpolate_atmos_field_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = - interpolate_atmos_field_time_series(ΣJ[1], args...) + - interpolate_atmos_field_time_series(ΣJ[2], args...) + - interpolate_atmos_field_time_series(ΣJ[3], args...) + - interpolate_atmos_field_time_series(ΣJ[4], args...) +@inline interp_atmos_time_series(ΣJ::Tuple{<:Any, <:Any, <:Any, <:Any}, args...) = + interp_atmos_time_series(ΣJ[1], args...) + + interp_atmos_time_series(ΣJ[2], args...) + + interp_atmos_time_series(ΣJ[3], args...) + + interp_atmos_time_series(ΣJ[4], args...) From be569b5db1c077708a24caa03e57e50fbf45158a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 7 Feb 2024 10:29:44 -0700 Subject: [PATCH 124/182] Single column test --- .../prototype_omip_simulation/Manifest.toml | 2 +- .../prototype_omip_simulation/Project.toml | 3 +- .../test_field_time_series.jl | 37 ++++ .../test_single_column_omip_simulation.jl | 192 ++++++++++++++++++ src/DataWrangling/JRA55.jl | 138 +++++++------ .../ocean_sea_ice_surface_fluxes.jl | 15 ++ .../PrescribedAtmospheres.jl | 19 ++ .../time_step_ocean_sea_ice_model.jl | 3 +- 8 files changed, 345 insertions(+), 64 deletions(-) create mode 100644 experiments/prototype_omip_simulation/test_field_time_series.jl create mode 100644 experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 6e0d7744..7ba86ee0 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0-rc1" manifest_format = "2.0" -project_hash = "672cbef2c7d6776d40e6432e74f2ade4088e87e6" +project_hash = "0892c27a537f93187841c13e787e804f45c1eef4" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml index 38276dd2..4f05c844 100644 --- a/experiments/prototype_omip_simulation/Project.toml +++ b/experiments/prototype_omip_simulation/Project.toml @@ -4,11 +4,12 @@ ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" [compat] -Oceananigans = "0.90.6" GLMakie = "0.9" +Oceananigans = "0.90.6" diff --git a/experiments/prototype_omip_simulation/test_field_time_series.jl b/experiments/prototype_omip_simulation/test_field_time_series.jl new file mode 100644 index 00000000..68d42fca --- /dev/null +++ b/experiments/prototype_omip_simulation/test_field_time_series.jl @@ -0,0 +1,37 @@ +using Oceananigans +using Oceananigans.OutputReaders: Cyclical, update_field_time_series! +using Oceananigans.Utils: Time +using GLMakie + +grid = RectilinearGrid(size=(1, 1, 1), extent=(1, 1, 1)) +times = 0:6 +path = "test_field_time_series.jld2" +rm(path, force=true) +name = "c" +c = CenterField(grid) +odct = FieldTimeSeries{Center, Center, Center}(grid; backend=OnDisk(), path, name) +for n in times + set!(c, n) + set!(odct, c, n, n) +end + +timct = FieldTimeSeries(path, name; backend=InMemory(), time_indexing=Cyclical()) +pimct = FieldTimeSeries(path, name; backend=InMemory(3), time_indexing=Cyclical()) + +ts = -2.1:0.1:17.1 +Nt = length(ts) +pci = zeros(Nt) + +for (n, t) in enumerate(ts) + update_field_time_series!(pimct, Time(t)) + pci[n] = pimct[1, 1, 1, Time(t)] +end + +tci = [timct[1, 1, 1, Time(t)] for t in ts] + +fig = Figure() +ax = Axis(fig[1, 1]) +scatterlines!(ax, ts, tci, marker='s', color=:blue) +scatterlines!(ax, ts, pci, marker=:square, color=:pink) +scatter!(ax, timct.times, timct[1, 1, 1, :], marker='o', markersize=20) +display(fig) diff --git a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl new file mode 100644 index 00000000..fc3a4d96 --- /dev/null +++ b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl @@ -0,0 +1,192 @@ +using Oceananigans +using Oceananigans.Units +using Oceananigans.Grids: node +using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time + +using ClimaOcean +using ClimaOcean.OceanSeaIceModels: Radiation +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: interp_atmos_time_series +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +using GLMakie +using Printf +using Dates + +include("omip_components.jl") + +locations = ( + #eastern_mediterranean = (λ = 30, φ = 32), + ocean_station_papa = (λ = 215, φ = 50), + north_atlantic = (λ = 325, φ = 50), + drake_passage = (λ = 300, φ = -60), + weddell_sea = (λ = 325, φ = -70), + tasman_southern_ocean = (λ = 145, φ = -55), +) + +location = :ocean_station_papa + +start_time = time_ns() + +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 1) +start_seconds = Second(date - epoch).value +uᵢ = ecco2_field(:u_velocity, date) +vᵢ = ecco2_field(:v_velocity, date) +Tᵢ = ecco2_field(:temperature, date) +Sᵢ = ecco2_field(:salinity, date) + +land = interior(Tᵢ) .< -10 +interior(Tᵢ)[land] .= NaN +interior(Sᵢ)[land] .= NaN + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +arch = CPU() + +Δ = 1/4 # resolution in degrees +φ₁ = -90 + Δ/2 +φ₂ = +90 - Δ/2 +λ₁ = 0 + Δ/2 +λ₂ = 360 - Δ/2 +φe = φ₁:Δ:φ₂ +λe = λ₁:Δ:λ₂ + +λ★, φ★ = locations[location] + +i★ = searchsortedfirst(λe, λ★) +j★ = searchsortedfirst(φe, φ★) + +longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) +latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) + +# Column +uc = interior(uᵢ, i★:i★, j★:j★, :) +vc = interior(vᵢ, i★:i★, j★:j★, :) +Tc = interior(Tᵢ, i★:i★, j★:j★, :) +Sc = interior(Sᵢ, i★:i★, j★:j★, :) + +# Find bottom +zm = -400 +zf = znodes(Tᵢ.grid, Face()) +kb = findlast(T -> T < -20, Tc[1, 1, :]) +km = findlast(z -> z < zm, zf) +k★ = isnothing(kb) ? km : max(kb + 1, km) + +Nz = size(Tc, 3) +kf = k★:Nz+1 +kc = k★:Nz +zf = zf[kf] +uc = uc[:, :, kc] +vc = vc[:, :, kc] +Tc = Tc[:, :, kc] +Sc = Sc[:, :, kc] +Nz′ = length(kc) + +grid = LatitudeLongitudeGrid(arch; longitude, latitude, + size = (1, 1, Nz′), + z = zf, + topology = (Periodic, Periodic, Bounded)) + +elapsed = time_ns() - start_time +@info "Grid constructed. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +ocean = omip_ocean_component(grid) +elapsed = time_ns() - start_time +@info "Ocean component built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +Ndays = 7 +Nt = 8 * Ndays +atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(8)) #, 1:21) +elapsed = time_ns() - start_time +@info "Atmosphere built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +# ocean.model.clock.time = start_seconds +ocean.model.clock.iteration = 0 +set!(ocean.model, T=Tc, S=Sc, e=1e-6) + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +times = ua.times + +sea_ice = nothing +radiation = Radiation() +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +coupled_model.clock.iteration = 0 +coupled_model.clock.time = 0 +set!(coupled_model.ocean.model, u=0, v=0, T=Tc, S=Sc, e=1e-6) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=14days) + +elapsed = time_ns() - start_time +@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +wall_clock = Ref(time_ns()) + +atmos_grid = atmosphere.grid +const c = Center() + +function progress(sim) + msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) + + #= + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + =# + + t = time(sim) + X = node(1, 1, 1, sim.model.ocean.model.grid, c, c, c) + uai = interp_atmos_time_series(ua, X, Time(t), atmos_grid) + vai = interp_atmos_time_series(va, X, Time(t), atmos_grid) + Tai = interp_atmos_time_series(Ta, X, Time(t), atmos_grid) + qai = interp_atmos_time_series(qa, X, Time(t), atmos_grid) + + msg *= @sprintf(", ua: %.2e, va: %.2e, Ta: %.2f, qa: %.2e", uai, vai, Tai, qai) + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + e = sim.model.ocean.model.tracers.e + + τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) + τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) + u★ = (τˣ^2 + τʸ^2)^(1/4) + + Q = first(sim.model.fluxes.total.ocean.heat) + + t = time(sim) + + Nz = size(T, 3) + msg *= @sprintf(", u★: %.2f m s⁻¹", u★) + msg *= @sprintf(", Q: %.2f W m⁻²", Q) + + #= + msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) + msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) + msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) + =# + + @info msg +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) + +run!(coupled_simulation) + diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index d730ea3e..d90e3c78 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -6,7 +6,7 @@ using Oceananigans.Units using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Grids: λnodes, φnodes, on_architecture using Oceananigans.Fields: interpolate! -using Oceananigans.OutputReaders: Cyclical +using Oceananigans.OutputReaders: Cyclical, TotallyInMemory using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, @@ -165,7 +165,12 @@ function compute_bounding_indices(grid, LX, LY, λc, φc) return i₁, i₂, j₁, j₂, TX end - +function jra55_times(Nt, start_time=0) + Δt = 3hours # just what it is + stop_time = start_time + Δt * (Nt - 1) + times = start_time:Δt:stop_time + return times +end """ JRA55_field_time_series(variable_name; @@ -229,14 +234,15 @@ Keyword arguments - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is loaded (not recommended). """ -function JRA55_field_time_series(variable_name; #, grid=nothing; +function JRA55_field_time_series(variable_name; architecture = CPU(), + grid = nothing, location = nothing, url = nothing, filename = nothing, shortname = nothing, backend = InMemory(), - time_extrapolation = Cyclical(), + time_indexing = Cyclical(), preprocess_chunk_size = 10, preprocess_architecture = CPU(), time_indices = nothing) @@ -252,30 +258,34 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; throw(ArgumentError(msg)) end - isnothing(shortname) && (shortname = jra55_short_names[variable_name]) - - !isnothing(filename) && !isfile(filename) && isnothing(url) && + if !isnothing(filename) && !isfile(filename) && isnothing(url) throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ If intended, please provide both the filename and url that should be used \n \ to download the new file.")) + end - isnothing(filename) && (filename = filenames[variable_name]) - isnothing(url) && (url = urls[variable_name]) + isnothing(shortname) && (shortname = jra55_short_names[variable_name]) + isnothing(filename) && (filename = filenames[variable_name]) + isnothing(url) && (url = urls[variable_name]) - # Decision tree: - # 1. jld2 file exists? - # - yes -> load and return FieldTimeSeries - # check time_indices and all that? - # - no -> download .nc data if not available + # Record some important user decisions + totally_in_memory = backend isa TotallyInMemory + on_native_grid = isnothing(grid) jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") fts_name = field_time_series_short_names[variable_name] - totally_in_memory = backend isa InMemory{Colon} + # TODO: figure out how to use existing jld2 files + # Eg we have to check correctness, etc + isfile(filename) || download(url, filename) isfile(jld2_filename) && rm(jld2_filename) #= - # TODO: figure out how to use existing jld2 files + # Decision tree: + # 1. jld2 file exists? + # - yes -> load and return FieldTimeSeries + # check time_indices and all that? + # - no -> download .nc data if not available if isfile(jld2_filename) isnothing(time_indices) && (time_indices = Colon()) @@ -298,21 +308,30 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; end =# - isfile(filename) || download(url, filename) - - # Extract variable data if totally_in_memory - # Set a sensible default + # In this case, the whole time series is in memory. + # Either the time series is short, or we are doing a limited-area + # simulation, like in a single column. In this case we conservatively + # set a default time_indices = 1:1. isnothing(time_indices) && (time_indices = 1:1) time_indices_in_memory = time_indices native_fts_architecture = architecture else + # In this case, part or all of the time series will be stored in a file. + # If we've gotten this far, it means that a suitable existing .jld2 file + # was not found and we need to preprocess data from the native .nc files. + # Now, time_indices refers to the time_indices that we will preprocess; + # by default we choose all of them. The architecture is only the + # architecture used for preprocessing, which typically will be CPU() + # even if we would like the final FieldTimeSeries on the GPU. + # Finally, `time_indices_in_memory` only refers to preprocessing, + # and we determine it using the kwarg `preprocess_chunk_size`. isnothing(time_indices) && (time_indices = :) time_indices_in_memory = 1:preprocess_chunk_size native_fts_architecture = preprocess_architecture end - # Get location + # Set a default location. if isnothing(location) LX = LY = Center else @@ -344,12 +363,15 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; # TODO: support loading just part of the JRA55 data. # Probably with arguments that take latitude, longitude bounds. - # i₁, i₂, j₁, j₂, TX = compute_bounding_indices(grid, LX, LY, λc, φc) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(grid, LX, LY, λc, φc) + + #= Nx = length(λc) Ny = length(φc) i₁, i₂ = (1, Nx) j₁, j₂ = (1, Ny) TX = Periodic + =# times = ds["time"][time_indices_in_memory] data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] @@ -367,42 +389,42 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) + # TODO: fix this and use dates? # Hack together the `times` for the JRA55 dataset we are currently using. # We might want to use the acutal dates instead though. # So the following code might need to change. - Δt = 3hours # just what it is - Nt = length(times) - start_time = 0 # Note: the forcing start at Jan 1 of the repeat year. - stop_time = Δt * (Nt - 1) - times = start_time:Δt:stop_time + times = jra55_times(length(times)) # Make times into an array for later preprocessing - !totally_in_memory && (times = collect(times)) + if !totally_in_memory + times = collect(times) + end native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - time_extrapolation, + time_indexing, boundary_conditions) # Fill the data in a GPU-friendly manner copyto!(interior(native_fts, :, :, 1, :), data) fill_halo_regions!(native_fts) - #= - if isnothing(grid) + if on_native_grid fts = native_fts else # make a new FieldTimeSeries and interpolate native data onto it. boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) - fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; boundary_conditions) + fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) interpolate!(fts, native_fts) end - =# if totally_in_memory - return native_fts + return fts else # we're gonna save to disk! - @info "Pre-processing JRA55 data into a JLD2 file to be used with FieldTimeSeries..." + # TODO: something's wrong here + @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(native_fts.grid; + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(fts.grid; + # time_indexing, + boundary_conditions, backend = OnDisk(), path = jld2_filename, name = fts_name) @@ -412,11 +434,7 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; all_datetimes = ds["time"][time_indices] all_Nt = length(all_datetimes) chunk = last(preprocess_chunk_size) - - Δt = 3hours # just what it is - start_time = 0 # Note: the forcing starts at Jan 1 of the repeat year. - stop_time = Δt * (all_Nt - 1) - all_times = start_time:Δt:stop_time + all_times = jra55_times(all_Nt) # Save data to disk, one field at a time start_clock = time_ns() @@ -427,28 +445,36 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory m += 1 - else + else # load new data # Update time_indices time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size + n₁ = first(time_indices_in_memory) # Clip time_indices if they extend past the end of the dataset if last(time_indices_in_memory) > all_Nt - n₁ = first(time_indices_in_memory) time_indices_in_memory = UnitRange(n₁, all_Nt) end - # Re-load .nc times and data - # new_times = ds["time"][time_indices_in_memory] - # native_fts.times .= new_times + # Re-compute times + Nt = length(time_indices_in_memory) + new_times = jra55_times(Nt, all_times[n₁]) + native_fts.times = new_times + # Re-compute data new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) fill_halo_regions!(native_fts) + if !on_native_grid + fts.times = new_times + interpolate!(fts, native_fts) + end + m = 1 # reset end - set!(on_disk_fts, native_fts[m], n, all_times[n]) + set!(on_disk_fts, fts[m], n, all_times[n]) + n += 1 end @@ -458,16 +484,8 @@ function JRA55_field_time_series(variable_name; #, grid=nothing; close(ds) - grid = on_architecture(architecture, JRA55_native_grid) - - backend_fts = FieldTimeSeries{LX, LY, Nothing}(grid, all_times; - backend, - time_extrapolation, - boundary_conditions, - path = jld2_filename, - name = fts_name) - - return backend_fts + user_fts = FieldTimeSeries(jld2_filename, fts_name; architecture, backend, time_indexing) + return user_fts end end @@ -479,7 +497,7 @@ JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = # TODO: allow the user to pass dates function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, - time_extrapolation = Cyclical(), + time_indexing = Cyclical(), reference_height = 2, # meters other_kw...) @@ -496,11 +514,9 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = InMemory(Nf) end - kw = (; time_indices, time_extrapolation, backend, architecture) + kw = (; time_indices, time_indexing, backend, architecture) kw = merge(kw, other_kw) - @show kw - ua = JRA55_field_time_series(:eastward_velocity; kw...) va = JRA55_field_time_series(:northward_velocity; kw...) Ta = JRA55_field_time_series(:temperature; kw...) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 5661e5ad..7f29e4c4 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -16,6 +16,8 @@ using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Fields: ConstantField, interpolate using Oceananigans.Utils: launch!, Time +# using Oceananigans.OutputReaders: extract_field_time_series, update_field_time_series! + using Oceananigans.Operators: ℑxᶜᵃᵃ, ℑyᵃᶜᵃ, ℑxᶠᵃᵃ, ℑyᵃᶠᵃ using KernelAbstractions: @kernel, @index @@ -159,6 +161,19 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) ocean_state = merge(ocean_velocities, ocean_tracers) atmosphere_state = merge(atmosphere.velocities, atmosphere.tracers, (; p=atmosphere.pressure)) + #= + time = Time(clock.time) + possible_ftses = tuple(atmosphere_state..., prescribed_fluxes...) + @show possible_ftses + + ftses = extract_field_time_series(atmosphere_state..., prescribed_fluxes...) + @show ftses + + for fts in ftses + update_field_time_series!(fts, time) + end + =# + launch!(arch, grid, :xy, compute_atmosphere_ocean_turbulent_fluxes!, grid, clock, centered_velocity_fluxes, diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 6a927597..537da18b 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -1,10 +1,14 @@ module PrescribedAtmospheres using Oceananigans.Utils: prettysummary +using Oceananigans.OutputReaders: update_field_time_series!, extract_field_time_series, time_indices_in_memory +using Oceananigans.OutputReaders: FieldTimeSeries, interpolating_time_indices using Adapt using Thermodynamics.Parameters: AbstractThermodynamicsParameters +import Oceananigans.Models: update_model_field_time_series! + import Thermodynamics.Parameters: gas_constant, # molmass_dryair, # Molar mass of dry air (without moisture) @@ -332,6 +336,21 @@ function PrescribedAtmosphere(times, FT=Float64; convert(FT, reference_height)) end +function update_model_field_time_series!(atmos::PrescribedAtmosphere, time) + ftses = extract_field_time_series(atmos) + for fts in ftses + update_field_time_series!(fts, time) + if fts isa FieldTimeSeries + times = fts.times + idx = time_indices_in_memory(fts) + ñ, n₁, n₂ = interpolating_time_indices(fts, time.time) + @show time, idx, Tuple(times[n] for n in idx), ñ, n₁, n₂ + end + end + + return nothing +end + struct TwoStreamDownwellingRadiation{SW, LW} shortwave :: SW longwave :: LW diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index 3e306bf1..1bb5020b 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -41,7 +41,8 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_ end function update_state!(coupled_model::OceanSeaIceModel, callbacks=[]; compute_tendencies=false) - # update_model_field_time_series!(coupled_model.atmosphere) + time = Time(coupled_model.clock.time) + update_model_field_time_series!(coupled_model.atmosphere, time) compute_atmosphere_ocean_fluxes!(coupled_model) # compute_atmosphere_sea_ice_fluxes!(coupled_model) # compute_sea_ice_ocean_fluxes!(coupled_model) From 73d4e93db7aab5d379cdcaf05ccef8d552aa2eab Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 7 Feb 2024 12:45:06 -0700 Subject: [PATCH 125/182] Always use the same clock... --- .../omip_components.jl | 12 ++++ .../test_single_column_omip_simulation.jl | 61 ++++++------------- .../ocean_sea_ice_surface_fluxes.jl | 15 +---- .../PrescribedAtmospheres.jl | 13 ++-- 4 files changed, 40 insertions(+), 61 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl index 980d26aa..0a0cf5a6 100644 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -13,6 +13,8 @@ using SeawaterPolynomials.TEOS10: TEOS10EquationOfState function omip_ocean_component(grid) + start_time = time_ns() + top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) @@ -52,10 +54,16 @@ function omip_ocean_component(grid) ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) + elapsed = time_ns() - start_time + msg = string("Finished building ocean component. (" * prettytime(elapsed * 1e-9), ")") + @info msg + return ocean end function omip_sea_ice_component(ocean_model) + start_time = time_ns() + ocean_grid = ocean_model.grid Nx, Ny, Nz = size(ocean_grid) Hx, Hy, Hz = halo_size(ocean_grid) @@ -102,6 +110,10 @@ function omip_sea_ice_component(ocean_model) sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) + elapsed = time_ns() - start_time + msg = string("Finished building sea ice component. (" * prettytime(elapsed * 1e-9), ")") + @info msg + return sea_ice end diff --git a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl index fc3a4d96..19c26685 100644 --- a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl @@ -32,8 +32,6 @@ start_time = time_ns() epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) start_seconds = Second(date - epoch).value -uᵢ = ecco2_field(:u_velocity, date) -vᵢ = ecco2_field(:v_velocity, date) Tᵢ = ecco2_field(:temperature, date) Sᵢ = ecco2_field(:salinity, date) @@ -68,8 +66,6 @@ longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) # Column -uc = interior(uᵢ, i★:i★, j★:j★, :) -vc = interior(vᵢ, i★:i★, j★:j★, :) Tc = interior(Tᵢ, i★:i★, j★:j★, :) Sc = interior(Sᵢ, i★:i★, j★:j★, :) @@ -84,8 +80,6 @@ Nz = size(Tc, 3) kf = k★:Nz+1 kc = k★:Nz zf = zf[kf] -uc = uc[:, :, kc] -vc = vc[:, :, kc] Tc = Tc[:, :, kc] Sc = Sc[:, :, kc] Nz′ = length(kc) @@ -95,48 +89,33 @@ grid = LatitudeLongitudeGrid(arch; longitude, latitude, z = zf, topology = (Periodic, Periodic, Bounded)) -elapsed = time_ns() - start_time -@info "Grid constructed. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - ocean = omip_ocean_component(grid) -elapsed = time_ns() - start_time -@info "Ocean component built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() +set!(ocean.model, T=Tc, S=Sc, e=1e-6) -Ndays = 7 +start_time = time_ns() +Ndays = 2 Nt = 8 * Ndays atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(8)) #, 1:21) -elapsed = time_ns() - start_time -@info "Atmosphere built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -# ocean.model.clock.time = start_seconds -ocean.model.clock.iteration = 0 -set!(ocean.model, T=Tc, S=Sc, e=1e-6) - -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -times = ua.times +#atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory()) #, 1:21) +@info "Atmosphere built. " * prettytime((time_ns() - start_time) * 1e-9) +# Build coupled simulation +start_time = time_ns() sea_ice = nothing radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) - -coupled_model.clock.iteration = 0 -coupled_model.clock.time = 0 -set!(coupled_model.ocean.model, u=0, v=0, T=Tc, S=Sc, e=1e-6) coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=14days) - -elapsed = time_ns() - start_time -@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() +@info "Coupled simulation built. " * prettytime((time_ns() - start_time) * 1e-9) wall_clock = Ref(time_ns()) atmos_grid = atmosphere.grid +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +times = ua.times + const c = Center() function progress(sim) @@ -167,16 +146,16 @@ function progress(sim) τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) u★ = (τˣ^2 + τʸ^2)^(1/4) + msg *= @sprintf(", τˣ: %.2f m² s⁻²", τˣ) + msg *= @sprintf(", τʸ: %.2f m² s⁻²", τʸ) + msg *= @sprintf(", u★: %.2f m s⁻¹", u★) Q = first(sim.model.fluxes.total.ocean.heat) - - t = time(sim) - - Nz = size(T, 3) - msg *= @sprintf(", u★: %.2f m s⁻¹", u★) msg *= @sprintf(", Q: %.2f W m⁻²", Q) + #= + Nz = size(T, 3) msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) @@ -186,7 +165,7 @@ function progress(sim) @info msg end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) run!(coupled_simulation) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 7f29e4c4..2317b05a 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -139,7 +139,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) # Basic model properties grid = ocean.model.grid arch = architecture(grid) - clock = ocean.model.clock + clock = coupled_model.clock # Ocean, atmosphere, and sea ice state ocean_velocities = surface_velocities(ocean) @@ -161,19 +161,6 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) ocean_state = merge(ocean_velocities, ocean_tracers) atmosphere_state = merge(atmosphere.velocities, atmosphere.tracers, (; p=atmosphere.pressure)) - #= - time = Time(clock.time) - possible_ftses = tuple(atmosphere_state..., prescribed_fluxes...) - @show possible_ftses - - ftses = extract_field_time_series(atmosphere_state..., prescribed_fluxes...) - @show ftses - - for fts in ftses - update_field_time_series!(fts, time) - end - =# - launch!(arch, grid, :xy, compute_atmosphere_ocean_turbulent_fluxes!, grid, clock, centered_velocity_fluxes, diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 537da18b..9fcd6c8c 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -340,12 +340,13 @@ function update_model_field_time_series!(atmos::PrescribedAtmosphere, time) ftses = extract_field_time_series(atmos) for fts in ftses update_field_time_series!(fts, time) - if fts isa FieldTimeSeries - times = fts.times - idx = time_indices_in_memory(fts) - ñ, n₁, n₂ = interpolating_time_indices(fts, time.time) - @show time, idx, Tuple(times[n] for n in idx), ñ, n₁, n₂ - end + + # if fts isa FieldTimeSeries + # times = fts.times + # idx = time_indices_in_memory(fts) + # ñ, n₁, n₂ = interpolating_time_indices(fts, time.time) + # @show time, idx, Tuple(times[n] for n in idx), ñ, n₁, n₂ + # end end return nothing From 3679b3431c8c41e45742e0fc56f7eae8998f982c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 7 Feb 2024 16:29:17 -0500 Subject: [PATCH 126/182] Bugfixes --- experiments/prototype_omip_simulation/Manifest.toml | 12 ++++++------ .../test_single_column_omip_simulation.jl | 8 +++----- .../CrossRealmFluxes/compute_turbulent_fluxes.jl | 2 ++ .../similarity_theory_turbulent_fluxes.jl | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 7ba86ee0..ad26c010 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0-rc1" +julia_version = "1.10.0-beta3" manifest_format = "2.0" project_hash = "0892c27a537f93187841c13e787e804f45c1eef4" @@ -1014,7 +1014,7 @@ 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" +version = "8.0.1+1" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -1304,15 +1304,15 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -path = "/Users/gregorywagner/Projects/Oceananigans.jl" +path = "/home/greg/Projects/Oceananigans.jl" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.7" [deps.Oceananigans.extensions] - OceananigansEnzymeCoreExt = "EnzymeCore" + OceananigansEnzymeExt = "Enzyme" [deps.Oceananigans.weakdeps] - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" [[deps.OffsetArrays]] git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" @@ -1953,7 +1953,7 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" +version = "7.2.0+1" [[deps.SurfaceFluxes]] deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] diff --git a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl index 19c26685..f828ab6e 100644 --- a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl @@ -10,7 +10,6 @@ using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: interp_atmos_time_series using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere using ClimaOcean.DataWrangling.ECCO2: ecco2_field -using GLMakie using Printf using Dates @@ -25,6 +24,7 @@ locations = ( tasman_southern_ocean = (λ = 145, φ = -55), ) +arch = GPU() location = :ocean_station_papa start_time = time_ns() @@ -47,8 +47,6 @@ start_time = time_ns() ##### Construct the grid ##### -arch = CPU() - Δ = 1/4 # resolution in degrees φ₁ = -90 + Δ/2 φ₂ = +90 - Δ/2 @@ -95,8 +93,8 @@ set!(ocean.model, T=Tc, S=Sc, e=1e-6) start_time = time_ns() Ndays = 2 Nt = 8 * Ndays -atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(8)) #, 1:21) -#atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory()) #, 1:21) +# atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(8), architecture=GPU()) #, 1:21) +atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(), architecture=arch) @info "Atmosphere built. " * prettytime((time_ns() - start_time) * 1e-9) # Build coupled simulation diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl index b8481822..07e5e62d 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl @@ -196,6 +196,7 @@ end ocean_state, turbulent_fluxes) + #= @debug begin u★ = Γ★.momentum θ★ = Γ★.temperature @@ -204,6 +205,7 @@ end Cᴰ = u★^2 / (Δu^2 + Δv^2) @sprintf("Iter: %d, Cᴰ: %.4e, u★: %.4e, θ★: %.4e, q★: %.4e", iter, Cᴰ, u★ , θ★, q★) end + =# end u★ = Γ★.momentum diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 2bb3edc2..9ba559e8 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -46,7 +46,7 @@ const STTF = SimilarityTheoryTurbulentFluxes Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), adapt(to, fluxes.von_karman_constant), adapt(to, fluxes.bulk_velocity_scale), - adapt(to, fluxes.similarity_function), + adapt(to, fluxes.similarity_functions), adapt(to, fluxes.thermodynamics_parameters), adapt(to, fluxes.water_vapor_saturation), adapt(to, fluxes.water_mole_fraction), From f3b927a0e18f15b7728351826b805c9de71ff647 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 7 Feb 2024 14:33:04 -0700 Subject: [PATCH 127/182] Remove unneeded imports --- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 9fcd6c8c..0091a75e 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -1,8 +1,7 @@ module PrescribedAtmospheres using Oceananigans.Utils: prettysummary -using Oceananigans.OutputReaders: update_field_time_series!, extract_field_time_series, time_indices_in_memory -using Oceananigans.OutputReaders: FieldTimeSeries, interpolating_time_indices +using Oceananigans.OutputReaders: update_field_time_series!, extract_field_time_series using Adapt using Thermodynamics.Parameters: AbstractThermodynamicsParameters @@ -340,13 +339,6 @@ function update_model_field_time_series!(atmos::PrescribedAtmosphere, time) ftses = extract_field_time_series(atmos) for fts in ftses update_field_time_series!(fts, time) - - # if fts isa FieldTimeSeries - # times = fts.times - # idx = time_indices_in_memory(fts) - # ñ, n₁, n₂ = interpolating_time_indices(fts, time.time) - # @show time, idx, Tuple(times[n] for n in idx), ñ, n₁, n₂ - # end end return nothing From 80d7142fd9b8cfdd9223eaa78af005d1e8455980 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 7 Feb 2024 15:36:55 -0700 Subject: [PATCH 128/182] Convert FieldTimeSeries to OffsetArray before computing fluxes --- .../ocean_sea_ice_surface_fluxes.jl | 50 +++++++++++++------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 2317b05a..dff24a8d 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -159,19 +159,37 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) radiation_properties = coupled_model.fluxes.radiation ocean_state = merge(ocean_velocities, ocean_tracers) - atmosphere_state = merge(atmosphere.velocities, atmosphere.tracers, (; p=atmosphere.pressure)) + + atmosphere_velocities = map(u -> u.data, atmosphere.velocities) + atmosphere_tracers = map(c -> c.data, atmosphere.tracers) + atmosphere_pressure = atmosphere.pressure.data + + atmosphere_state = merge(atmosphere_velocities, atmosphere_tracers, (; p=atmosphere_pressure)) + freshwater_flux = map(ϕ -> ϕ.data, atmosphere.freshwater_flux) + + u = atmosphere.velocities.u # for example + atmosphere_times = u.times + atmosphere_backend = u.backend + atmosphere_time_indexing = u.time_indexing + + Qs = atmosphere.downwelling_radiation.shortwave + Ql = atmosphere.downwelling_radiation.longwave + downwelling_radiation = (shortwave=Qs.data, longwave=Ql.data) launch!(arch, grid, :xy, compute_atmosphere_ocean_turbulent_fluxes!, grid, clock, centered_velocity_fluxes, net_tracer_fluxes, similarity_theory, - atmosphere.freshwater_flux, - atmosphere.downwelling_radiation, + freshwater_flux, + downwelling_radiation, radiation_properties, ocean_state, atmosphere_state, atmosphere_grid, + atmosphere_times, + atmosphere_backend, + atmosphere_time_indexing, atmosphere.reference_height, # height at which the state is known atmosphere.thermodynamics_parameters, coupled_model.fluxes.ocean_reference_density, @@ -204,6 +222,9 @@ const f = Face() ocean_state, atmos_state, atmos_grid, + atmos_times, + atmos_backend, + atmos_time_indexing, atmosphere_reference_height, atmosphere_thermodynamics_parameters, ocean_reference_density, @@ -231,19 +252,20 @@ const f = Face() # a surface node anyways. X = node(i, j, kᴺ + 1, grid, c, c, f) - uₐ = interp_atmos_time_series(atmos_state.u, X, time, atmos_grid) - vₐ = interp_atmos_time_series(atmos_state.v, X, time, atmos_grid) + atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) + uₐ = interp_atmos_time_series(atmos_state.u, X, time, atmos_args...) + vₐ = interp_atmos_time_series(atmos_state.v, X, time, atmos_args...) - Tₐ = interp_atmos_time_series(atmos_state.T, X, time, atmos_grid) - pₐ = interp_atmos_time_series(atmos_state.p, X, time, atmos_grid) - qₐ = interp_atmos_time_series(atmos_state.q, X, time, atmos_grid) + Tₐ = interp_atmos_time_series(atmos_state.T, X, time, atmos_args...) + pₐ = interp_atmos_time_series(atmos_state.p, X, time, atmos_args...) + qₐ = interp_atmos_time_series(atmos_state.q, X, time, atmos_args...) - Qs = interp_atmos_time_series(downwelling_radiation.shortwave, X, time, atmos_grid) - Qℓ = interp_atmos_time_series(downwelling_radiation.longwave, X, time, atmos_grid) + Qs = interp_atmos_time_series(downwelling_radiation.shortwave, X, time, atmos_args...) + Qℓ = interp_atmos_time_series(downwelling_radiation.longwave, X, time, atmos_args...) # Accumulate mass fluxes of freshwater due to rain, snow, rivers, # icebergs, and whatever else. - M = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_grid) + M = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_args...) end # Build thermodynamic and dynamic states in the atmosphere and surface. @@ -350,10 +372,10 @@ end ##### Utility for interpolating tuples of fields ##### -# Note: assumes loc = (c, c, c) (and the third location should +# Note: assumes loc = (c, c, nothing) (and the third location should # not matter.) -@inline interp_atmos_time_series(J, X, time, grid) = - interpolate(X, time, J, (c, c, c), grid) +@inline interp_atmos_time_series(J, X, time, grid, args...) = + interpolate(X, time, J, (c, c, nothing), grid, args...) @inline interp_atmos_time_series(ΣJ::NamedTuple, args...) = interp_atmos_time_series(values(ΣJ), args...) From e6847629808f7094a3cc8c6859f82d4a2ba4f16f Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 8 Feb 2024 16:31:25 -0500 Subject: [PATCH 129/182] Working on turublnet fluxes --- .../test_single_column_omip_simulation.jl | 15 ++--- .../ocean_sea_ice_surface_fluxes.jl | 61 ++++++++++--------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl index f828ab6e..49dcd41f 100644 --- a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl @@ -102,7 +102,7 @@ start_time = time_ns() sea_ice = nothing radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=14days) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_iteration=10)#stop_time=14days) @info "Coupled simulation built. " * prettytime((time_ns() - start_time) * 1e-9) wall_clock = Ref(time_ns()) @@ -119,12 +119,14 @@ const c = Center() function progress(sim) msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) - #= elapsed = 1e-9 * (time_ns() - wall_clock[]) msg *= string(", wall time: ", prettytime(elapsed)) wall_clock[] = time_ns() - =# + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + #= t = time(sim) X = node(1, 1, 1, sim.model.ocean.model.grid, c, c, c) uai = interp_atmos_time_series(ua, X, Time(t), atmos_grid) @@ -134,9 +136,6 @@ function progress(sim) msg *= @sprintf(", ua: %.2e, va: %.2e, Ta: %.2f, qa: %.2e", uai, vai, Tai, qai) - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - T = sim.model.ocean.model.tracers.T S = sim.model.ocean.model.tracers.S e = sim.model.ocean.model.tracers.e @@ -151,8 +150,6 @@ function progress(sim) Q = first(sim.model.fluxes.total.ocean.heat) msg *= @sprintf(", Q: %.2f W m⁻²", Q) - - #= Nz = size(T, 3) msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) @@ -163,7 +160,7 @@ function progress(sim) @info msg end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) run!(coupled_simulation) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index dff24a8d..d1aa8074 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -177,26 +177,27 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) downwelling_radiation = (shortwave=Qs.data, longwave=Ql.data) launch!(arch, grid, :xy, compute_atmosphere_ocean_turbulent_fluxes!, - grid, clock, - centered_velocity_fluxes, - net_tracer_fluxes, - similarity_theory, - freshwater_flux, - downwelling_radiation, - radiation_properties, + grid, + clock, ocean_state, + coupled_model.fluxes.ocean_temperature_units, atmosphere_state, + downwelling_radiation, + freshwater_flux, atmosphere_grid, atmosphere_times, atmosphere_backend, atmosphere_time_indexing, atmosphere.reference_height, # height at which the state is known - atmosphere.thermodynamics_parameters, - coupled_model.fluxes.ocean_reference_density, - coupled_model.fluxes.ocean_heat_capacity, - coupled_model.fluxes.freshwater_density, - coupled_model.fluxes.ocean_temperature_units, - ice_concentration) + atmosphere.thermodynamics_parameters) + #similarity_theory) + # centered_velocity_fluxes, + # net_tracer_fluxes, + # radiation_properties, + # coupled_model.fluxes.ocean_reference_density, + # coupled_model.fluxes.ocean_heat_capacity, + # coupled_model.fluxes.freshwater_density, + # ice_concentration) # Note: I think this can be avoided if we modify the preceding kernel # to compute from 0:Nx+1, ie in halo regions @@ -213,25 +214,25 @@ const f = Face() @kernel function compute_atmosphere_ocean_turbulent_fluxes!(grid, clock, - centered_velocity_fluxes, - net_tracer_fluxes, - similarity_theory, - prescribed_freshwater_flux, - downwelling_radiation, - radiation_properties, ocean_state, + ocean_temperature_units, atmos_state, + downwelling_radiation, + prescribed_freshwater_flux, atmos_grid, atmos_times, atmos_backend, atmos_time_indexing, atmosphere_reference_height, - atmosphere_thermodynamics_parameters, - ocean_reference_density, - ocean_heat_capacity, - freshwater_density, - ocean_temperature_units, - ice_concentration) + atmos_thermodynamics_parameters) + #similarity_theory) + # centered_velocity_fluxes, + # net_tracer_fluxes, + # radiation_properties, + # ocean_reference_density, + # ocean_heat_capacity, + # freshwater_density, + # ice_concentration) i, j = @index(Global, NTuple) kᴺ = size(grid, 3) @@ -246,7 +247,9 @@ const f = Face() Tₒ = ocean_state.T[i, j, 1] Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) Sₒ = ocean_state.S[i, j, 1] + end + @inbounds begin # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) # The third index "k" should not matter but we put the correct index to get # a surface node anyways. @@ -272,7 +275,7 @@ const f = Face() # Notation: # ⋅ 𝒬 ≡ thermodynamic state vector # ⋅ 𝒰 ≡ "dynamic" state vector (thermodynamics + reference height + velocity) - ℂₐ = atmosphere_thermodynamics_parameters + ℂₐ = atmos_thermodynamics_parameters 𝒬ₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) hₐ = atmosphere_reference_height # elevation of atmos variables relative to surface @@ -282,8 +285,8 @@ const f = Face() # Build surface state with saturated specific humidity surface_type = AtmosphericThermodynamics.Liquid() qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, 𝒬ₐ, - similarity_theory.water_mole_fraction, - similarity_theory.water_vapor_saturation, + 0.98, #similarity_theory.water_mole_fraction, + ClasiusClapyeronSaturation(), #similarity_theory.water_vapor_saturation, surface_type) # Thermodynamic and dynamic surface state @@ -293,6 +296,7 @@ const f = Face() Uₒ = SVector(uₒ, vₒ) 𝒰₀ = dynamic_ocean_state = SurfaceFluxes.StateValues(h₀, Uₒ, 𝒬₀) + #= turbulent_fluxes = compute_turbulent_fluxes(similarity_theory.roughness_lengths, similarity_theory, dynamic_atmos_state, @@ -340,6 +344,7 @@ const f = Face() Jᵀ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵀ) Jˢ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jˢ) end + =# end @kernel function reconstruct_momentum_fluxes!(grid, J, Jᶜᶜᶜ) From de0a69da25aa91fcbb831b92f7031d5b941acd4d Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 8 Feb 2024 15:00:17 -0700 Subject: [PATCH 130/182] Add in similarity theory flux computation --- .../prototype_omip_simulation/Manifest.toml | 10 +- .../test_single_column_omip_simulation.jl | 2 +- .../compute_turbulent_fluxes.jl | 286 --------------- .../ocean_sea_ice_surface_fluxes.jl | 20 +- .../similarity_theory_turbulent_fluxes.jl | 344 ++++++++++++------ 5 files changed, 248 insertions(+), 414 deletions(-) diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index ad26c010..833ff084 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0-beta3" +julia_version = "1.10.0-rc1" manifest_format = "2.0" project_hash = "0892c27a537f93187841c13e787e804f45c1eef4" @@ -1014,7 +1014,7 @@ 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.0.1+1" +version = "8.4.0+0" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -1304,7 +1304,9 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -path = "/home/greg/Projects/Oceananigans.jl" +git-tree-sha1 = "a086be6e839305355aa0c9cb373fa03d83561ef4" +repo-rev = "ss-glw/time-bcs" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.7" @@ -1953,7 +1955,7 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.0+1" +version = "7.2.1+1" [[deps.SurfaceFluxes]] deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] diff --git a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl index 49dcd41f..b414f606 100644 --- a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl @@ -24,7 +24,7 @@ locations = ( tasman_southern_ocean = (λ = 145, φ = -55), ) -arch = GPU() +arch = CPU() location = :ocean_station_papa start_time = time_ns() diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl index 07e5e62d..e69de29b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl @@ -1,286 +0,0 @@ -using Printf - -import Thermodynamics as AtmosphericThermodynamics - -using Thermodynamics: PhasePartition -using KernelAbstractions.Extras.LoopInfo: @unroll - -@inline update_turbulent_flux_fields!(::Nothing, args...) = nothing - -@inline function update_turbulent_flux_fields!(fields, i, j, grid, fluxes) - Qv = fields.latent_heat - Qc = fields.sensible_heat - Fv = fields.water_vapor - τx = fields.x_momentum - τy = fields.y_momentum - kᴺ = size(grid, 3) # index of the top ocean cell - inactive = inactive_node(i, j, kᴺ, grid, c, c, c) - @inbounds begin - # +0: cooling, -0: heating - Qv[i, j, 1] = ifelse(inactive, 0, fluxes.latent_heat) - Qc[i, j, 1] = ifelse(inactive, 0, fluxes.sensible_heat) - Fv[i, j, 1] = ifelse(inactive, 0, fluxes.water_vapor) - τx[i, j, 1] = ifelse(inactive, 0, fluxes.x_momentum) - τy[i, j, 1] = ifelse(inactive, 0, fluxes.y_momentum) - end - return nothing -end - -@inline compute_turbulent_fluxes(turbulent_fluxes, atmos_state, ocean_state) = - compute_turbulent_fluxes(turbulent_fluxes.roughness_lengths, turbulent_fluxes, atmos_state, ocean_state) - -##### -##### Struct that represents a 3-tuple of momentum, heat, and water vapor -##### - -struct SimilarityScales{U, T, Q} - momentum :: U - temperature :: T - water_vapor :: Q -end - -# Convenience default with water_vapor component = nothing -SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature, nothing) - -##### -##### Interface into SurfaceFluxes.jl -##### - -# This is the case that SurfaceFluxes.jl can do -const NothingVaporRoughnessLength = SimilarityScales{<:Number, <:Number, Nothing} - -@inline function compute_turbulent_fluxes(roughness_lengths::NothingVaporRoughnessLength, - turbulent_fluxes, - atmos_state, - ocean_state) - - # Constant roughness lengths - ℓu = roughness_lengths.momentum - ℓθ = roughness_lengths.temperature - - # Solve for the surface fluxes with initial roughness length guess - Uᵍ = zero(zm) # gustiness - β = one(zm) # surface "resistance" - values = SurfaceFluxes.ValuesOnly(atmos_state, ocean_state, ℓu, ℓθ, Uᵍ, β) - conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) - - fluxes = (; - sensible_heat = conditions.shf, - latent_heat = conditions.lhf, - water_vapor = conditions.evaporation, - x_momentum = conditions.ρτxz, - y_momentum = conditions.ρτyz, - ) - - return fluxes -end - -##### -##### Fixed-point iteration for roughness length -##### - -const ConstantRoughnessLength = SimilarityScales{<:Number, <:Number, <:Number} - -struct SimilarityFunction{FT, C} - a :: FT - b :: FT - c :: C -end - -@inline function (ψ::SimilarityFunction)(Ri) - a = ψ.a - b = ψ.b - c = ψ.c - - Ri⁻ = min(zero(Ri), Ri) - ϕ⁻¹ = (1 - b * Ri⁻)^c - ψ_unstable = log((1 + ϕ⁻¹)^2 * (1 + ϕ⁻¹^2) / 8) - (4 * atan(ϕ⁻¹) + π) / 2 - - ψ_stable = - a * Ri - - return ifelse(Ri < 0, ψ_unstable, ψ_stable) -end - -struct OneQuarter end -struct OneHalf end - -import Base: ^ -@inline ^(x, ::OneQuarter) = sqrt(sqrt(x)) -@inline ^(x, ::OneHalf) = sqrt(x) - -function businger_similarity_functions(FT=Float64) - au = convert(FT, 4.7) - bu = convert(FT, 15) - cu = OneQuarter() - ψu = SimilarityFunction(au, bu, cu) - - ah = convert(FT, 6.35) - bh = convert(FT, 9) - ch = OneHalf() - ψh = SimilarityFunction(ah, bh, ch) - - ψq = ψh - - return SimilarityScales(ψu, ψh, ψq) -end - -@inline function bulk_factor(ψ, h, ℓ, Ri) - L★ = h / Ri - χ⁻¹ = log(h / ℓ) - ψ(Ri) + ψ(ℓ / L★) - return 1 / χ⁻¹ -end - -@inline function buoyancy_scale(θ★, q★, 𝒬, parameters) - ℂ = parameters.thermodynamics_parameters - - 𝒯₀ = AtmosphericThermodynamics.virtual_temperature(ℂ, 𝒬) - θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) - q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬) - - ε = AtmosphericThermodynamics.Parameters.molmass_ratio(parameters) - δ = ε - 1 - g = SurfaceFluxes.Parameters.grav(parameters) - - b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * θ₀ * q★) - - return b★ -end - - -@inline function state_differences(ℂ, 𝒰₁, 𝒰₀) - z₁ = 𝒰₁.z - z₀ = 𝒰₀.z - Δh = z₁ - z₀ - - U₁ = 𝒰₁.u - U₀ = 𝒰₀.u - - @inbounds begin - Δu = U₁[1] - U₀[1] - Δv = U₁[2] - U₀[2] - end - - # Thermodynamic state - 𝒬₁ = 𝒰₁.ts - 𝒬₀ = 𝒰₀.ts - - θ₁ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₁) - θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₀) - Δθ = θ₁ - θ₀ - - q₁ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₁) - q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₀) - Δq = q₁ - q₀ - - return Δh, Δu, Δv, Δθ, Δq -end - -@inline function compute_turbulent_fluxes(roughness_lengths::ConstantRoughnessLength, - turbulent_fluxes, - atmos_state, - ocean_state) - - # Prescribed difference between two states - ℂₐ = thermodynamics_params(turbulent_fluxes) - Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, ocean_state) - differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) - - # Solve for the characteristic scales u★, θ★, q★, and thus for fluxes. - Γ₀ = Γ★ = SimilarityScales(1e-3, 1e-3, 1e-3) - - @unroll for iter = 1:10 - Γ★ = refine_characteristic_scales(Γ★, - roughness_lengths, - turbulent_fluxes.similarity_functions, - differences, - ocean_state, - turbulent_fluxes) - - #= - @debug begin - u★ = Γ★.momentum - θ★ = Γ★.temperature - q★ = Γ★.water_vapor - # u★² = Cᴰ * (Δu² + Δv²) - Cᴰ = u★^2 / (Δu^2 + Δv^2) - @sprintf("Iter: %d, Cᴰ: %.4e, u★: %.4e, θ★: %.4e, q★: %.4e", iter, Cᴰ, u★ , θ★, q★) - end - =# - end - - u★ = Γ★.momentum - θ★ = Γ★.temperature - q★ = Γ★.water_vapor - - # u★² ≡ sqrt(τx² + τy²) - τx = u★^2 * Δu / sqrt(Δu^2 + Δv^2) - τy = u★^2 * Δv / sqrt(Δu^2 + Δv^2) - - 𝒬ₐ = atmos_state.ts - ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) - cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity - ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) - - fluxes = (; - water_vapor = ρₐ * u★ * q★, - sensible_heat = ρₐ * cₚ * u★ * θ★, - latent_heat = ρₐ * u★ * q★ * ℰv, - x_momentum = ρₐ * τx, - y_momentum = ρₐ * τy, - ) - - return fluxes -end - -@inline function refine_characteristic_scales(estimated_characteristic_scales, - roughness_lengths, - similarity_functions, - differences, - ocean_state, - similarity_parameters) - - # "initial" scales because we will recompute them - u★ = estimated_characteristic_scales.momentum - θ★ = estimated_characteristic_scales.temperature - q★ = estimated_characteristic_scales.water_vapor - - # Extract roughness lengths - ℓu = roughness_lengths.momentum - ℓθ = roughness_lengths.temperature - ℓq = roughness_lengths.water_vapor - - # Compute flux Richardson number - h = differences.h - ϰ = similarity_parameters.von_karman_constant - - 𝒬ₒ = ocean_state.ts # thermodyanmic state - b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, similarity_parameters) - Riₕ = - ϰ * h * b★ / u★^2 - - # Compute similarity functions - fu = similarity_functions.momentum - fθ = similarity_functions.temperature - fq = similarity_functions.water_vapor - - χu = bulk_factor(fu, h, ℓu, Riₕ) - χθ = bulk_factor(fθ, h, ℓθ, Riₕ) - χq = bulk_factor(fq, h, ℓq, Riₕ) - - Δu = differences.u - Δv = differences.v - Δθ = differences.θ - Δq = differences.q - - u★ = ϰ * χu * sqrt(Δu^2 + Δv^2) - θ★ = ϰ * χθ * Δθ - q★ = ϰ * χq * Δq - - return SimilarityScales(u★, θ★, q★) -end - -struct GravityWaveRoughnessLength{FT} - gravitational_acceleration :: FT - gravity_wave_parameter :: FT - laminar_parameter :: FT -end - diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index d1aa8074..77330304 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -189,8 +189,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_backend, atmosphere_time_indexing, atmosphere.reference_height, # height at which the state is known - atmosphere.thermodynamics_parameters) - #similarity_theory) + atmosphere.thermodynamics_parameters, + similarity_theory.roughness_lengths) # centered_velocity_fluxes, # net_tracer_fluxes, # radiation_properties, @@ -224,8 +224,8 @@ const f = Face() atmos_backend, atmos_time_indexing, atmosphere_reference_height, - atmos_thermodynamics_parameters) - #similarity_theory) + atmos_thermodynamics_parameters, + roughness_lengths) # centered_velocity_fluxes, # net_tracer_fluxes, # radiation_properties, @@ -296,12 +296,14 @@ const f = Face() Uₒ = SVector(uₒ, vₒ) 𝒰₀ = dynamic_ocean_state = SurfaceFluxes.StateValues(h₀, Uₒ, 𝒬₀) - #= - turbulent_fluxes = compute_turbulent_fluxes(similarity_theory.roughness_lengths, - similarity_theory, - dynamic_atmos_state, - dynamic_ocean_state) + g = 9.81 + ϰ = 0.4 + turbulent_fluxes = compute_similarity_theory_fluxes(roughness_lengths, + dynamic_ocean_state, + dynamic_atmos_state, + ℂₐ, g, ϰ) + #= # Compute heat fluxes, bulk flux first Qc = turbulent_fluxes.sensible_heat # sensible or "conductive" heat flux Qv = turbulent_fluxes.latent_heat # latent heat flux associated with vapor tranpsort diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 9ba559e8..d8a6b5a9 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -6,6 +6,10 @@ using Thermodynamics: Liquid using SurfaceFluxes.Parameters: SurfaceFluxesParameters, AbstractSurfaceFluxesParameters using SurfaceFluxes.UniversalFunctions: BusingerParams, BusingerType +using Printf +using Thermodynamics: PhasePartition +using KernelAbstractions.Extras.LoopInfo: @unroll + using ..PrescribedAtmospheres: PrescribedAtmosphereThermodynamicsParameters import Thermodynamics as AtmosphericThermodynamics @@ -18,6 +22,7 @@ import SurfaceFluxes.Parameters: universal_func_type, grav + ##### ##### Bulk turbulent fluxes based on similarity theory ##### @@ -208,164 +213,275 @@ end return (1 - s) / (1 - s + α * s) end -#= -struct SimilarityFunction{FT} - a :: FT - b :: FT - c :: FT + +@inline update_turbulent_flux_fields!(::Nothing, args...) = nothing + +@inline function update_turbulent_flux_fields!(fields, i, j, grid, fluxes) + Qv = fields.latent_heat + Qc = fields.sensible_heat + Fv = fields.water_vapor + τx = fields.x_momentum + τy = fields.y_momentum + kᴺ = size(grid, 3) # index of the top ocean cell + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) + @inbounds begin + # +0: cooling, -0: heating + Qv[i, j, 1] = ifelse(inactive, 0, fluxes.latent_heat) + Qc[i, j, 1] = ifelse(inactive, 0, fluxes.sensible_heat) + Fv[i, j, 1] = ifelse(inactive, 0, fluxes.water_vapor) + τx[i, j, 1] = ifelse(inactive, 0, fluxes.x_momentum) + τy[i, j, 1] = ifelse(inactive, 0, fluxes.y_momentum) + end + return nothing end -struct GravityWaveRoughnessLength{FT} - gravity_wave_parameter :: FT - laminar_parameter :: FT - air_kinematic_viscosity :: FT +@inline compute_similarity_theory_fluxes(turbulent_fluxes, atmos_state, surface_state) = + compute_similarity_theory_fluxes(turbulent_fluxes.roughness_lengths, turbulent_fluxes, atmos_state, surface_state) + +##### +##### Struct that represents a 3-tuple of momentum, heat, and water vapor +##### + +struct SimilarityScales{U, T, Q} + momentum :: U + temperature :: T + water_vapor :: Q end -struct AtmosphericState{Q, T, U, V} - q :: Q - θ :: T - u :: U - v :: V +# Convenience default with water_vapor component = nothing +SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature, nothing) + +##### +##### Interface into SurfaceFluxes.jl +##### + +# This is the case that SurfaceFluxes.jl can do +const NothingVaporRoughnessLength = SimilarityScales{<:Number, <:Number, Nothing} + +@inline function compute_similarity_theory_fluxes(roughness_lengths::NothingVaporRoughnessLength, + turbulent_fluxes, + atmos_state, + surface_state) + + # Constant roughness lengths + ℓu = roughness_lengths.momentum + ℓθ = roughness_lengths.temperature + + # Solve for the surface fluxes with initial roughness length guess + Uᵍ = zero(zm) # gustiness + β = one(zm) # surface "resistance" + values = SurfaceFluxes.ValuesOnly(atmos_state, surface_state, ℓu, ℓθ, Uᵍ, β) + conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + + fluxes = (; + sensible_heat = conditions.shf, + latent_heat = conditions.lhf, + water_vapor = conditions.evaporation, + x_momentum = conditions.ρτxz, + y_momentum = conditions.ρτyz, + ) + + return fluxes end -AtmosphericState(q, θ, u) = AtmosphericState(q, θ, u, nothing) +##### +##### Fixed-point iteration for roughness length +##### + +const ConstantRoughnessLength = SimilarityScales{<:Number, <:Number, <:Number} + +struct SimilarityFunction{FT, C} + a :: FT + b :: FT + c :: C +end @inline function (ψ::SimilarityFunction)(Ri) a = ψ.a b = ψ.b c = ψ.c - ϕ⁻¹ = (1 - b * Ri)^c - ψ_unstable = log((1 + ϕ⁻¹)^2 * (1 + ϕ⁻¹^2) / 8) - 2 * atan(ϕ⁻¹) + π/2 + Ri⁻ = min(zero(Ri), Ri) + ϕ⁻¹ = (1 - b * Ri⁻)^c + ψ_unstable = log((1 + ϕ⁻¹)^2 * (1 + ϕ⁻¹^2) / 8) - (4 * atan(ϕ⁻¹) + π) / 2 + ψ_stable = - a * Ri + return ifelse(Ri < 0, ψ_unstable, ψ_stable) end -@inline similarity_scale(ψ, h, ℓ, Ri) = 1 / (log(h/ℓ) - ψ(Ri) + ψ(ℓ * Ri / h)) - -function buoyancy_scale(θ★, q★, surface_state, parameters) - θ★ = fluxes.θ - q★ = fluxes.q - 𝒯₀ = virtual_temperature(parameters, surface_state) - q₀ = surface_state.q - θ₀ = surface_state.θ - r = parameters.molar_mass_ratio - g = parameters.gravitational_acceleration - δ = r - 1 - b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * θ₀ * q★) - return b★ -end +struct OneQuarter end +struct OneHalf end -function fixed_point_fluxes(u★, θ★, q★, - surface_state, - inner_length_scales, - universal_function, - parameters) +import Base: ^ +@inline ^(x, ::OneQuarter) = sqrt(sqrt(x)) +@inline ^(x, ::OneHalf) = sqrt(x) - Δu = differences.u - Δv = differences.v - Δθ = differences.θ - Δq = differences.q +function businger_similarity_functions(FT=Float64) + au = convert(FT, 4.7) + bu = convert(FT, 15) + cu = OneQuarter() + ψu = SimilarityFunction(au, bu, cu) - ϰ = parameters.von_karman_constant - f = universal_function + ah = convert(FT, 6.35) + bh = convert(FT, 9) + ch = OneHalf() + ψh = SimilarityFunction(ah, bh, ch) - b★ = buoyancy_scale(θ★, q★, surface_state, parameters) - Riₕ = - ϰ * h * b★ / u★^2 + ψq = ψh + + return SimilarityScales(ψu, ψh, ψq) +end - ℓu = inner_length_scales.u(u★) - ℓθ = inner_length_scales.θ(u★) - ℓq = inner_length_scales.q(u★) +@inline function bulk_factor(ψ, h, ℓ, Ri) + L★ = h / Ri + χ⁻¹ = log(h / ℓ) - ψ(Ri) + ψ(ℓ / L★) + return 1 / χ⁻¹ +end - χu = momentum_flux_scale(f, h, ℓu, Riₕ) - χθ = tracer_flux_scale(f, h, ℓθ, Riₕ) - χq = tracer_flux_scale(f, h, ℓq, Riₕ) +@inline function buoyancy_scale(θ★, q★, 𝒬, ℂ, g) + 𝒯₀ = AtmosphericThermodynamics.virtual_temperature(ℂ, 𝒬) + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) + q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬) - u★ = ϰ * χu * sqrt(Δu^2 + Δv^2) - θ★ = ϰ * χθ * Δθ - q★ = ϰ * χq * Δq + ε = AtmosphericThermodynamics.Parameters.molmass_ratio(ℂ) + δ = ε - 1 + + b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * θ₀ * q★) - return u★, θ★, q★ + return b★ end -function GravityWaveRoughnessLengths(FT=Float64; - gravity_wave_parameter = 0.011, - laminar_parameter = 0.11, - air_kinematic_viscosity=1.5e-5) - return GravityWaveRoughnessLengths(convert(FT, gravity_wave_parameter), - convert(FT, laminar_parameter), - convert(FT, air_kinematic_viscosity)) -end +@inline function state_differences(ℂ, 𝒰₁, 𝒰₀) + z₁ = 𝒰₁.z + z₀ = 𝒰₀.z + Δh = z₁ - z₀ -@inline function compute_turbulent_surface_fluxes(similarity_function::BusingerParams, - roughness_lengths, - atmos_state, - ocean_state) + U₁ = 𝒰₁.u + U₀ = 𝒰₀.u - ℓu = roughness_lengths.momentum - ℓθ = roughness_lengths.heat - ℓq = roughness_lengths.water_vapor - + @inbounds begin + Δu = U₁[1] - U₀[1] + Δv = U₁[2] - U₀[2] + end - fluxes = (; - latent_heat_flux = conditions.lhf, - sensible_heat_flux = conditions.shf, - freshwater_flux = conditions.evaporation, - zonal_momentum_flux = conditions.ρτxz, - meridional_momentum_flux = conditions.ρτyz, - ) + # Thermodynamic state + 𝒬₁ = 𝒰₁.ts + 𝒬₀ = 𝒰₀.ts -@inline function compute_turbulent_surface_fluxes(similarity_function::BusingerParams, - roughness_lengths::SimplifiedRoughnessLengths, - atmos_state, - ocean_state) + θ₁ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₁) + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₀) + Δθ = θ₁ - θ₀ - # Solve for the surface fluxes with initial roughness length guess - Uᵍ = zero(grid) # gustiness - β = one(grid) # surface "resistance" - values = SurfaceFluxes.ValuesOnly(atmos_state, ocean_State, - roughness_lengths.momentum, - roughness_lengths.heat - Uᵍ, β) - conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + q₁ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₁) + q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₀) + Δq = q₁ - q₀ + + return Δh, Δu, Δv, Δθ, Δq +end + +@inline function compute_similarity_theory_fluxes(roughness_lengths::ConstantRoughnessLength, + surface_state, + atmos_state, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) + + # Prescribed difference between two states + ℂₐ = thermodynamics_parameters + Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, surface_state) + differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) + + # Solve for the characteristic scales u★, θ★, q★, and thus for fluxes. + Γ₀ = Γ★ = SimilarityScales(1e-3, 1e-3, 1e-3) + + @unroll for iter = 1:10 + Γ★ = refine_characteristic_scales(Γ★, + roughness_lengths, + surface_state, + differences, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) + end + + u★ = Γ★.momentum + θ★ = Γ★.temperature + q★ = Γ★.water_vapor + + # u★² ≡ sqrt(τx² + τy²) + τx = u★^2 * Δu / sqrt(Δu^2 + Δv^2) + τy = u★^2 * Δv / sqrt(Δu^2 + Δv^2) + + 𝒬ₐ = atmos_state.ts + ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) + cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity + ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) fluxes = (; - latent_heat_flux = conditions.lhf, - sensible_heat_flux = conditions.shf, - freshwater_flux = conditions.evaporation, - zonal_momentum_flux = conditions.ρτxz, - meridional_momentum_flux = conditions.ρτyz, + water_vapor = ρₐ * u★ * q★, + sensible_heat = ρₐ * cₚ * u★ * θ★, + latent_heat = ρₐ * u★ * q★ * ℰv, + x_momentum = ρₐ * τx, + y_momentum = ρₐ * τy, ) return fluxes end +@inline function refine_characteristic_scales(estimated_characteristic_scales, + roughness_lengths, + surface_state, + differences, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) -@inline function compute_turbulent_surface_fluxes(roughness_lengths::GravityWaveRoughnessLengths, - atmos_state, - ocean_state) + # "initial" scales because we will recompute them + u★ = estimated_characteristic_scales.momentum + θ★ = estimated_characteristic_scales.temperature + q★ = estimated_characteristic_scales.water_vapor - # Solve for the surface fluxes with initial roughness length guess - Uᵍ = zero(grid) # gustiness - β = one(grid) # surface "resistance" - values = SurfaceFluxes.ValuesOnly(atmos_state, ocean_State, - roughness_lengths.momentum, - roughness_lengths.heat - Uᵍ, β) + # Extract roughness lengths + ℓu = roughness_lengths.momentum + ℓθ = roughness_lengths.temperature + ℓq = roughness_lengths.water_vapor - conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) + # Compute flux Richardson number + h = differences.h + ϰ = von_karman_constant - fluxes = (; - latent_heat_flux = conditions.lhf, - sensible_heat_flux = conditions.shf, - freshwater_flux = conditions.evaporation, - zonal_momentum_flux = conditions.ρτxz, - meridional_momentum_flux = conditions.ρτyz, - ) + ℂ = thermodynamics_parameters + g = gravitational_acceleration + 𝒬ₒ = surface_state.ts # thermodyanmic state + b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, ℂ, g) + Riₕ = - ϰ * h * b★ / u★^2 - return fluxes + # Compute similarity functions + ψu = SimilarityFunction(4.7, 15.0, OneQuarter()) + ψc = SimilarityFunction(6.35, 9.0, OneHalf()) + + χu = bulk_factor(ψu, h, ℓu, Riₕ) + χθ = bulk_factor(ψc, h, ℓθ, Riₕ) + χq = bulk_factor(ψc, h, ℓq, Riₕ) + + Δu = differences.u + Δv = differences.v + Δθ = differences.θ + Δq = differences.q + + u★ = ϰ * χu * sqrt(Δu^2 + Δv^2) + θ★ = ϰ * χθ * Δθ + q★ = ϰ * χq * Δq + + return SimilarityScales(u★, θ★, q★) end +#= +struct GravityWaveRoughnessLength{FT} + gravitational_acceleration :: FT + gravity_wave_parameter :: FT + laminar_parameter :: FT +end =# - From b05572274942d72a236c73b85060fd96bebb1dd2 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 8 Feb 2024 15:00:28 -0700 Subject: [PATCH 131/182] Delete compute turbulent fluxes --- .../CrossRealmFluxes/compute_turbulent_fluxes.jl | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/compute_turbulent_fluxes.jl deleted file mode 100644 index e69de29b..00000000 From 1e54fd557549480266df231ec37ed67382782019 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 8 Feb 2024 17:09:49 -0500 Subject: [PATCH 132/182] Bugfix --- src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 9dd9ebfa..f14c8b56 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -60,7 +60,6 @@ function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) end include("radiation.jl") -include("compute_turbulent_fluxes.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") # include("atmosphere_sea_ice_fluxes.jl") From 3aeb25581473cec022a84ab48e35f99a33258b4a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 8 Feb 2024 17:28:23 -0500 Subject: [PATCH 133/182] Minimal implementation working --- .../test_single_column_omip_simulation.jl | 2 +- .../ocean_sea_ice_surface_fluxes.jl | 26 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl index b414f606..49dcd41f 100644 --- a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl @@ -24,7 +24,7 @@ locations = ( tasman_southern_ocean = (λ = 145, φ = -55), ) -arch = CPU() +arch = GPU() location = :ocean_station_papa start_time = time_ns() diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 77330304..3f3612ac 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -190,13 +190,14 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_time_indexing, atmosphere.reference_height, # height at which the state is known atmosphere.thermodynamics_parameters, - similarity_theory.roughness_lengths) + similarity_theory.roughness_lengths, + similarity_theory.fields) # centered_velocity_fluxes, # net_tracer_fluxes, # radiation_properties, # coupled_model.fluxes.ocean_reference_density, # coupled_model.fluxes.ocean_heat_capacity, - # coupled_model.fluxes.freshwater_density, + # coupled_model.fluxes.freshwater_density) # ice_concentration) # Note: I think this can be avoided if we modify the preceding kernel @@ -225,13 +226,14 @@ const f = Face() atmos_time_indexing, atmosphere_reference_height, atmos_thermodynamics_parameters, - roughness_lengths) - # centered_velocity_fluxes, - # net_tracer_fluxes, - # radiation_properties, - # ocean_reference_density, - # ocean_heat_capacity, - # freshwater_density, + roughness_lengths, + similarity_theory_fields) + #centered_velocity_fluxes, + #net_tracer_fluxes, + #radiation_properties, + #ocean_reference_density, + #ocean_heat_capacity, + #freshwater_density) # ice_concentration) i, j = @index(Global, NTuple) @@ -303,6 +305,8 @@ const f = Face() dynamic_atmos_state, ℂₐ, g, ϰ) + update_turbulent_flux_fields!(similarity_theory_fields, i, j, grid, turbulent_fluxes) + #= # Compute heat fluxes, bulk flux first Qc = turbulent_fluxes.sensible_heat # sensible or "conductive" heat flux @@ -320,9 +324,9 @@ const f = Face() # Add the contribution from the turbulent water vapor flux Fv = turbulent_fluxes.water_vapor / ρᶠ ΣF += Fv + =# - update_turbulent_flux_fields!(similarity_theory.fields, i, j, grid, turbulent_fluxes) - + #= # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes Jᵘ = centered_velocity_fluxes.u Jᵛ = centered_velocity_fluxes.v From 45d49bdae26ad955ddebaf2dc7fd867fff6d66b0 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 8 Feb 2024 15:58:55 -0700 Subject: [PATCH 134/182] Split flux calculation into two kernels --- .../ocean_sea_ice_surface_fluxes.jl | 167 +++++++++++------- .../similarity_theory_turbulent_fluxes.jl | 17 +- 2 files changed, 108 insertions(+), 76 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 3f3612ac..80c48b1c 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -176,29 +176,40 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) Ql = atmosphere.downwelling_radiation.longwave downwelling_radiation = (shortwave=Qs.data, longwave=Ql.data) - launch!(arch, grid, :xy, compute_atmosphere_ocean_turbulent_fluxes!, + launch!(arch, grid, :xy, compute_atmosphere_ocean_similarity_theory_fluxes!, + similarity_theory.fields, grid, clock, ocean_state, coupled_model.fluxes.ocean_temperature_units, atmosphere_state, - downwelling_radiation, - freshwater_flux, atmosphere_grid, atmosphere_times, atmosphere_backend, atmosphere_time_indexing, atmosphere.reference_height, # height at which the state is known atmosphere.thermodynamics_parameters, - similarity_theory.roughness_lengths, - similarity_theory.fields) - # centered_velocity_fluxes, - # net_tracer_fluxes, - # radiation_properties, - # coupled_model.fluxes.ocean_reference_density, - # coupled_model.fluxes.ocean_heat_capacity, - # coupled_model.fluxes.freshwater_density) - # ice_concentration) + similarity_theory.roughness_lengths) + + launch!(arch, grid, :xy, assemble_atmosphere_ocean_fluxes!, + centered_velocity_fluxes, + net_tracer_fluxes, + grid, + clock, + ocean_state.T, + ocean_state.S, + coupled_model.fluxes.ocean_temperature_units, + similarity_theory.fields, + downwelling_radiation, + freshwater_flux, + atmosphere_grid, + atmosphere_times, + atmosphere_backend, + atmosphere_time_indexing, + radiation_properties, + coupled_model.fluxes.ocean_reference_density, + coupled_model.fluxes.ocean_heat_capacity, + coupled_model.fluxes.freshwater_density) # Note: I think this can be avoided if we modify the preceding kernel # to compute from 0:Nx+1, ie in halo regions @@ -213,29 +224,20 @@ end const c = Center() const f = Face() -@kernel function compute_atmosphere_ocean_turbulent_fluxes!(grid, - clock, - ocean_state, - ocean_temperature_units, - atmos_state, - downwelling_radiation, - prescribed_freshwater_flux, - atmos_grid, - atmos_times, - atmos_backend, - atmos_time_indexing, - atmosphere_reference_height, - atmos_thermodynamics_parameters, - roughness_lengths, - similarity_theory_fields) - #centered_velocity_fluxes, - #net_tracer_fluxes, - #radiation_properties, - #ocean_reference_density, - #ocean_heat_capacity, - #freshwater_density) - # ice_concentration) - +@kernel function compute_atmosphere_ocean_similarity_theory_fluxes!(similarity_theory_fields, + grid, + clock, + ocean_state, + ocean_temperature_units, + atmos_state, + atmos_grid, + atmos_times, + atmos_backend, + atmos_time_indexing, + atmosphere_reference_height, + atmos_thermodynamics_parameters, + roughness_lengths) + i, j = @index(Global, NTuple) kᴺ = size(grid, 3) @@ -256,21 +258,14 @@ const f = Face() # The third index "k" should not matter but we put the correct index to get # a surface node anyways. X = node(i, j, kᴺ + 1, grid, c, c, f) - atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) + uₐ = interp_atmos_time_series(atmos_state.u, X, time, atmos_args...) vₐ = interp_atmos_time_series(atmos_state.v, X, time, atmos_args...) Tₐ = interp_atmos_time_series(atmos_state.T, X, time, atmos_args...) pₐ = interp_atmos_time_series(atmos_state.p, X, time, atmos_args...) qₐ = interp_atmos_time_series(atmos_state.q, X, time, atmos_args...) - - Qs = interp_atmos_time_series(downwelling_radiation.shortwave, X, time, atmos_args...) - Qℓ = interp_atmos_time_series(downwelling_radiation.longwave, X, time, atmos_args...) - - # Accumulate mass fluxes of freshwater due to rain, snow, rivers, - # icebergs, and whatever else. - M = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_args...) end # Build thermodynamic and dynamic states in the atmosphere and surface. @@ -305,28 +300,85 @@ const f = Face() dynamic_atmos_state, ℂₐ, g, ϰ) - update_turbulent_flux_fields!(similarity_theory_fields, i, j, grid, turbulent_fluxes) + Qv = similarity_theory_fields.latent_heat + Qc = similarity_theory_fields.sensible_heat + Fv = similarity_theory_fields.water_vapor + τx = similarity_theory_fields.x_momentum + τy = similarity_theory_fields.y_momentum + kᴺ = size(grid, 3) # index of the top ocean cell + + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) + + @inbounds begin + # +0: cooling, -0: heating + Qv[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.latent_heat) + Qc[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.sensible_heat) + Fv[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.water_vapor) + τx[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.x_momentum) + τy[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.y_momentum) + end +end + +@kernel function assemble_atmosphere_ocean_fluxes!(centered_velocity_fluxes, + net_tracer_fluxes, + grid, + clock, + ocean_temperature, + ocean_salinity, + ocean_temperature_units, + similarity_theory_fields, + downwelling_radiation, + prescribed_freshwater_flux, + atmos_grid, + atmos_times, + atmos_backend, + atmos_time_indexing, + radiation_properties, + ocean_reference_density, + ocean_heat_capacity, + freshwater_density) + + i, j = @index(Global, NTuple) + kᴺ = size(grid, 3) + time = Time(clock.time) + + @inbounds begin + Tₒ = ocean_temperature[i, j, 1] + Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) + Sₒ = ocean_salinity[i, j, 1] + + X = node(i, j, kᴺ + 1, grid, c, c, f) + atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) + + Qs = interp_atmos_time_series(downwelling_radiation.shortwave, X, time, atmos_args...) + Qℓ = interp_atmos_time_series(downwelling_radiation.longwave, X, time, atmos_args...) + + # Accumulate mass fluxes of freshwater due to rain, snow, rivers, + # icebergs, and whatever else. + Mp = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_args...) + + Qc = similarity_theory_fields.sensible_heat[i, j, 1] # sensible or "conductive" heat flux + Qv = similarity_theory_fields.latent_heat[i, j, 1] # sensible or "conductive" heat flux + Mv = similarity_theory_fields.water_vapor[i, j, 1] # sensible or "conductive" heat flux + τx = similarity_theory_fields.x_momentum[i, j, 1] # sensible or "conductive" heat flux + τy = similarity_theory_fields.y_momentum[i, j, 1] # sensible or "conductive" heat flux + end - #= # Compute heat fluxes, bulk flux first - Qc = turbulent_fluxes.sensible_heat # sensible or "conductive" heat flux - Qv = turbulent_fluxes.latent_heat # latent heat flux associated with vapor tranpsort Qd = net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation_properties) - Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, ocean_state, ocean_temperature_units) + Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, Tₒ) ΣQ = Qd + Qu + Qc + Qv # Convert from a mass flux to a volume flux (aka velocity) # by dividing by the density of freshwater. # Also switch the sign, for some reason we are given freshwater flux as positive down. ρᶠ = freshwater_density - ΣF = - M / ρᶠ + ΣF = - Mp / ρᶠ # Add the contribution from the turbulent water vapor flux - Fv = turbulent_fluxes.water_vapor / ρᶠ + Fv = Mv / ρᶠ ΣF += Fv - =# - #= # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes Jᵘ = centered_velocity_fluxes.u Jᵛ = centered_velocity_fluxes.v @@ -336,8 +388,8 @@ const f = Face() ρₒ = ocean_reference_density cₒ = ocean_heat_capacity - atmos_ocean_Jᵘ = turbulent_fluxes.x_momentum / ρₒ - atmos_ocean_Jᵛ = turbulent_fluxes.y_momentum / ρₒ + atmos_ocean_Jᵘ = τx / ρₒ + atmos_ocean_Jᵛ = τy / ρₒ atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) atmos_ocean_Jˢ = - Sₒ * ΣF @@ -350,7 +402,6 @@ const f = Face() Jᵀ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵀ) Jˢ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jˢ) end - =# end @kernel function reconstruct_momentum_fluxes!(grid, J, Jᶜᶜᶜ) @@ -367,14 +418,10 @@ end return @inbounds - (1 - α) * Qs - Qℓ end -@inline function net_upwelling_radiation(i, j, grid, time, radiation, ocean_state, ocean_temperature_units) +@inline function net_upwelling_radiation(i, j, grid, time, radiation, Tₒ) σ = radiation.stefan_boltzmann_constant ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) - # Ocean surface temperature (departure from reference, typically in ᵒC) - Tₒ = @inbounds ocean_state.T[i, j, 1] - Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) - # Note: positive implies _upward_ heat flux, and therefore cooling. return ϵ * σ * Tₒ^4 end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index d8a6b5a9..f89f4599 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -217,22 +217,7 @@ end @inline update_turbulent_flux_fields!(::Nothing, args...) = nothing @inline function update_turbulent_flux_fields!(fields, i, j, grid, fluxes) - Qv = fields.latent_heat - Qc = fields.sensible_heat - Fv = fields.water_vapor - τx = fields.x_momentum - τy = fields.y_momentum - kᴺ = size(grid, 3) # index of the top ocean cell - inactive = inactive_node(i, j, kᴺ, grid, c, c, c) - @inbounds begin - # +0: cooling, -0: heating - Qv[i, j, 1] = ifelse(inactive, 0, fluxes.latent_heat) - Qc[i, j, 1] = ifelse(inactive, 0, fluxes.sensible_heat) - Fv[i, j, 1] = ifelse(inactive, 0, fluxes.water_vapor) - τx[i, j, 1] = ifelse(inactive, 0, fluxes.x_momentum) - τy[i, j, 1] = ifelse(inactive, 0, fluxes.y_momentum) - end - return nothing + return nothing end @inline compute_similarity_theory_fluxes(turbulent_fluxes, atmos_state, surface_state) = From 3e0aded194d0b7fe24aa874de42c3e70768d9db5 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sat, 10 Feb 2024 15:32:14 -0500 Subject: [PATCH 135/182] Updates to get sea ice working provisionally --- .../freely_decaying_regional_simulation.jl | 144 ++++++++++++++++++ .../omip_components.jl | 85 ++++++++++- .../regional_omip_simulation.jl | 122 +++------------ .../test_single_column_omip_simulation.jl | 4 +- .../CrossRealmFluxes/CrossRealmFluxes.jl | 2 +- .../CrossRealmFluxes/sea_ice_ocean_fluxes.jl | 13 +- src/OceanSeaIceModels/OceanSeaIceModels.jl | 2 + .../PrescribedAtmospheres.jl | 2 + .../time_step_ocean_sea_ice_model.jl | 6 +- 9 files changed, 264 insertions(+), 116 deletions(-) create mode 100644 experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl diff --git a/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl b/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl new file mode 100644 index 00000000..ad100524 --- /dev/null +++ b/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl @@ -0,0 +1,144 @@ +using Oceananigans +using Oceananigans.Architectures: arch_array +using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time + +using ClimaOcean +using ClimaOcean.OceanSeaIceModels: Radiation +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +# using GLMakie +using Printf +using Dates + +start_time = time_ns() + +include("omip_components.jl") + +arch = GPU() +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 1) +start_seconds = Second(date - epoch).value +Te = ecco2_field(:temperature, date) +Se = ecco2_field(:salinity, date) +ℋe = ecco2_field(:sea_ice_thickness, date) + +land = interior(Te) .< -10 +interior(Te)[land] .= NaN +interior(Se)[land] .= NaN + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +latitude = (-80, -20) +longitude = (0, 360) + +i₁ = 4 * first(longitude) + 1 +i₂ = 1440 - 4 * (360 - last(longitude)) +Nx = i₂ - i₁ + 1 + +j₁ = 4 * (90 + first(latitude)) + 1 +j₂ = 720 - 4 * (90 - last(latitude)) +Ny = j₂ - j₁ + 1 + +zc = znodes(Te) +zf = znodes(Te.grid, Face()) +Δz = first(zspacings(Te.grid, Center())) + +Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) +Sᵢ = interior(Se, i₁:i₂, j₁:j₂, :) +ℋᵢ = interior(ℋe, i₁:i₂, j₁:j₂, :) + +# Construct bottom_height depth by analyzing T +Nx, Ny, Nz = size(Tᵢ) +bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) + +for i = 1:Nx, j = 1:Ny + @inbounds for k = Nz:-1:1 + if isnan(Tᵢ[i, j, k]) + bottom_height[i, j] = zf[k+1] + break + end + end +end + +Tᵢ = arch_array(arch, Tᵢ) +Sᵢ = arch_array(arch, Sᵢ) +ℋᵢ = arch_array(arch, ℋᵢ) + +if longitude[2] - longitude[1] == 360 + TX = Periodic +else + TX = Bounded +end + +grid = LatitudeLongitudeGrid(arch; latitude, longitude, + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = zf, + topology = (Periodic, Bounded, Bounded)) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) +ocean = omip_ocean_component(grid) +sea_ice = omip_sea_ice_component(ocean.model) + +coupled_model = OceanSeaIceModel(ocean, sea_ice) +stop_time = 4 * 360days +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=stop_time) + +set!(sea_ice.model, h=ℋᵢ) +#set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) +set!(ocean.model, T=Tᵢ, S=Sᵢ) + +wall_clock = Ref(time_ns()) + +function progress(sim) + msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", maximum(T), minimum(T)) + msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) + + # e = sim.model.ocean.model.tracers.e + # msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) + + @info msg +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +N² = buoyancy_frequency(ocean.model) +κᶜ = ocean.model.diffusivity_fields.κᶜ +auxiliary_fields = (; N², κᶜ) +fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + +filename = "free_decay_heat_only_cold_ice_surface" + +coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; + filename = filename * "_fields", + indices = (:, :, Nz), + schedule = TimeInterval(10days), + overwrite_existing = true) + +coupled_simulation.output_writers[:seaice] = JLD2OutputWriter(sea_ice.model, (; h = sea_ice.model.ice_thickness); + filename = filename * "_sea_ice_thickness", + schedule = TimeInterval(10days), + overwrite_existing = true) + +run!(coupled_simulation) diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl index 0a0cf5a6..5ab4a1c6 100644 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -11,7 +11,73 @@ using ClimaSeaIce.HeatBoundaryConditions: IceWaterThermalEquilibrium using SeawaterPolynomials.TEOS10: TEOS10EquationOfState -function omip_ocean_component(grid) +function regional_ecco2_grid(arch, Te, other_fields...; latitude, longitude) + + i₁ = 4 * first(longitude) + 1 + i₂ = 1440 - 4 * (360 - last(longitude)) + i₂ > i₁ || error("longitude $longitude is invalid.") + Nx = i₂ - i₁ + 1 + + j₁ = 4 * (90 + first(latitude)) + 1 + j₂ = 720 - 4 * (90 - last(latitude)) + j₂ > j₁ || error("latitude $latitude is invalid.") + Ny = j₂ - j₁ + 1 + + zc = znodes(Te) + zf = znodes(Te.grid, Face()) + Δz = first(zspacings(Te.grid, Center())) + + Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) + + # Construct bottom_height depth by analyzing T + Nx, Ny, Nz = size(Tᵢ) + bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) + + land = Tᵢ .< -10 + Tᵢ[land] .= NaN + + for i = 1:Nx, j = 1:Ny + @inbounds for k = Nz:-1:1 + if isnan(Tᵢ[i, j, k]) + bottom_height[i, j] = zf[k+1] + break + end + end + end + + Tᵢ = arch_array(arch, Tᵢ) + + Tx = if longitude[2] - longitude[1] == 360 + Periodic + else + Bounded + end + + grid = LatitudeLongitudeGrid(arch; latitude, longitude, + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = zf, + topology = (Periodic, Bounded, Bounded)) + + grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + + Nf = length(other_fields) + + ft = ntuple(Nf) do n + fe = other_fields[n] + fᵢ = interior(fe, i₁:i₂, j₁:j₂, :) + fᵢ[land] .= NaN + fᵢ = arch_array(arch, fᵢ) + end + + all_fields = tuple(Tᵢ, ft...) + + return grid, all_fields +end + +function omip_ocean_component(grid; + closure = :default, + passive_tracers = tuple()) start_time = time_ns() @@ -41,13 +107,18 @@ function omip_ocean_component(grid) vertical_scheme = WENO()) end - mixing_length = MixingLength(Cᵇ=0.01) - turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) - closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) + tracers = tuple(:T, :S, passive_tracers...) + + if closure == :default + mixing_length = MixingLength(Cᵇ=0.01) + turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) + tracers = tuple(:e, tracers...) + end ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, tracer_advection, momentum_advection, - tracers = (:T, :S, :e), + tracers = (:T, :S), #, :e), free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), boundary_conditions = ocean_boundary_conditions, coriolis = HydrostaticSphericalCoriolis()) @@ -99,12 +170,12 @@ function omip_sea_ice_component(ocean_model) sea_ice_model = SlabSeaIceModel(sea_ice_grid; velocities = ocean_surface_velocities, - advection = nothing, + advection = WENO(), ice_consolidation_thickness = 0.05, ice_salinity = 4, internal_heat_flux = ConductiveFlux(conductivity=2), top_heat_flux = ConstantField(0), # W m⁻² - top_heat_boundary_condition = PrescribedTemperature(0), + top_heat_boundary_condition = PrescribedTemperature(-10), bottom_heat_boundary_condition = bottom_bc, bottom_heat_flux = sea_ice_ocean_heat_flux) diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index 59db2c89..abd6192a 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -18,108 +18,36 @@ start_time = time_ns() include("omip_components.jl") arch = GPU() + +##### +##### Construct initial conditions + grid +##### + epoch = Date(1992, 1, 1) -date = Date(1992, 10, 1) +date = Date(1992, 1, 2) start_seconds = Second(date - epoch).value -# uᵢ = ecco2_field(:u_velocity, date) -# vᵢ = ecco2_field(:v_velocity, date) Te = ecco2_field(:temperature, date) Se = ecco2_field(:salinity, date) -ℋe = ecco2_field(:sea_ice_thickness, date) - -land = interior(Te) .< -10 -interior(Te)[land] .= NaN -interior(Se)[land] .= NaN - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### -latitude = (-75, -30) +latitude = (-45, +45) longitude = (0, 360) +grid, (Tᵢ, Sᵢ) = regional_ecco2_grid(arch, Te, Se; latitude, longitude) -i₁ = 4 * first(longitude) + 1 -i₂ = 1440 - 4 * (360 - last(longitude)) -Nx = i₂ - i₁ + 1 - -j₁ = 4 * (90 + first(latitude)) + 1 -j₂ = 720 - 4 * (90 - last(latitude)) -Ny = j₂ - j₁ + 1 - -zc = znodes(Te) -zf = znodes(Te.grid, Face()) -Δz = first(zspacings(Te.grid, Center())) - -Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) -Sᵢ = interior(Se, i₁:i₂, j₁:j₂, :) -ℋᵢ = interior(ℋe, i₁:i₂, j₁:j₂, :) - -# Construct bottom_height depth by analyzing T -Nx, Ny, Nz = size(Tᵢ) -bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) - -for i = 1:Nx, j = 1:Ny - @inbounds for k = Nz:-1:1 - if isnan(Tᵢ[i, j, k]) - bottom_height[i, j] = zf[k+1] - break - end - end -end - -Tᵢ = arch_array(arch, Tᵢ) -Sᵢ = arch_array(arch, Sᵢ) -ℋᵢ = arch_array(arch, ℋᵢ) - -if longitude[2] - longitude[1] == 360 - TX = Periodic -else - TX = Bounded -end - -grid = LatitudeLongitudeGrid(arch; latitude, longitude, - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = zf, - topology = (Periodic, Bounded, Bounded)) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - -elapsed = time_ns() - start_time -@info "Grid constructed. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -ocean = omip_ocean_component(grid) -elapsed = time_ns() - start_time -@info "Ocean component built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -#= -Ndays = 30 -Nt = 8 * Ndays +Nt = 8 * 30 atmosphere = JRA55_prescribed_atmosphere(arch, 1:Nt; backend=InMemory(8)) -elapsed = time_ns() - start_time -@info "Atmosphere built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() -=# +radiation = Radiation() +sea_ice = nothing -atmosphere = nothing +ocean = omip_ocean_component(grid, closure=RiBasedVerticalDiffusivity()) +set!(ocean.model, T=Tᵢ, S=Sᵢ) -ocean.model.clock.time = start_seconds -ocean.model.clock.iteration = 0 -set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) - -sea_ice = omip_sea_ice_component(ocean.model) #nothing -set!(sea_ice.model, h=ℋᵢ) +if :e ∈ keys(ocean.model.tracers) + set!(ocean.model, e=1e-6) +end -radiation = nothing # Radiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) - -stop_time = start_seconds + 90days +coupled_model.clock.time = start_seconds +stop_time = start_seconds + 30days coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=stop_time) elapsed = time_ns() - start_time @@ -140,17 +68,21 @@ function progress(sim) T = sim.model.ocean.model.tracers.T S = sim.model.ocean.model.tracers.S - e = sim.model.ocean.model.tracers.e msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", maximum(T), minimum(T)) msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) - msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) + + #e = sim.model.ocean.model.tracers.e + #msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) @info msg end coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +run!(coupled_simulation) + +#= # Build flux outputs Jᵘ = coupled_model.fluxes.total.ocean.momentum.u Jᵛ = coupled_model.fluxes.total.ocean.momentum.v @@ -191,9 +123,3 @@ coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, field schedule = TimeInterval(1days), overwrite_existing = true) -coupled_simulation.output_writers[:seaice] = JLD2OutputWriter(sea_ice.model, (; h = sea_ice.model.ice_thickness); - filename = filename * "_sea_ice_thickness", - schedule = TimeInterval(1days), - overwrite_existing = true) - -run!(coupled_simulation) diff --git a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl index 49dcd41f..2c4995ee 100644 --- a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl @@ -94,7 +94,7 @@ start_time = time_ns() Ndays = 2 Nt = 8 * Ndays # atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(8), architecture=GPU()) #, 1:21) -atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(), architecture=arch) +atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(8), architecture=arch) @info "Atmosphere built. " * prettytime((time_ns() - start_time) * 1e-9) # Build coupled simulation @@ -102,7 +102,7 @@ start_time = time_ns() sea_ice = nothing radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_iteration=10)#stop_time=14days) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=14days) @info "Coupled simulation built. " * prettytime((time_ns() - start_time) * 1e-9) wall_clock = Ref(time_ns()) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index f14c8b56..815ba70f 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -62,8 +62,8 @@ end include("radiation.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") +include("sea_ice_ocean_fluxes.jl") # include("atmosphere_sea_ice_fluxes.jl") -# include("sea_ice_ocean_fluxes.jl") end # module diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl index bda1319c..dbc9077d 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl @@ -1,7 +1,8 @@ using ClimaSeaIce: melting_temperature +using Oceananigans.Operators: Δzᶜᶜᶜ function compute_sea_ice_ocean_fluxes!(coupled_model) - compute_sea_ice_ocean_salinity_flux!(coupled_model) + #compute_sea_ice_ocean_salinity_flux!(coupled_model) sea_ice_ocean_latent_heat_flux!(coupled_model) return nothing end @@ -18,7 +19,7 @@ function compute_sea_ice_ocean_salinity_flux!(coupled_model) Sᵢ = sea_ice.model.ice_salinity Δt = ocean.Δt hⁿ = sea_ice.model.ice_thickness - h⁻ = coupled_model.previous_ice_thickness + h⁻ = coupled_model.fluxes.previous_ice_thickness launch!(arch, grid, :xy, _compute_sea_ice_ocean_salinity_flux!, Qˢ, grid, hⁿ, h⁻, Sᵢ, Sₒ, Δt) @@ -60,8 +61,8 @@ end function sea_ice_ocean_latent_heat_flux!(coupled_model) ocean = coupled_model.ocean sea_ice = coupled_model.sea_ice - ρₒ = coupled_model.ocean_reference_density - cₒ = coupled_model.ocean_heat_capacity + ρₒ = coupled_model.fluxes.ocean_reference_density + cₒ = coupled_model.fluxes.ocean_heat_capacity Qₒ = sea_ice.model.external_heat_fluxes.bottom Tₒ = ocean.model.tracers.T Sₒ = ocean.model.tracers.S @@ -80,6 +81,7 @@ function sea_ice_ocean_latent_heat_flux!(coupled_model) return nothing end +#= function adjust_ice_covered_ocean_temperature!(coupled_model) sea_ice_ocean_latent_heat_flux!(coupled_model) sea_ice = coupled_model.sea_ice @@ -87,6 +89,7 @@ function adjust_ice_covered_ocean_temperature!(coupled_model) parent(Qₒ) .= 0 return nothing end +=# @kernel function _compute_sea_ice_ocean_latent_heat_flux!(latent_heat_flux, grid, @@ -107,7 +110,7 @@ end δQ = zero(grid) icy_cell = @inbounds hᵢ[i, j, 1] > 0 # make ice bath approximation then - @unroll for k = Nz:-1:1 + for k = Nz:-1:1 @inbounds begin # Various quantities Δz = Δzᶜᶜᶜ(i, j, k, grid) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index c4f31f15..871cbfa1 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -56,7 +56,9 @@ import .CrossRealmFluxes: compute_atmosphere_ocean_fluxes! # "No atmosphere" implementation const NoAtmosphereModel = OceanSeaIceModel{<:Any, Nothing} +const NoSeaIceModel = OceanSeaIceModel{Nothing} compute_atmosphere_ocean_fluxes!(coupled_model::NoAtmosphereModel) = nothing +compute_sea_ice_ocean_fluxes!(coupled_model::NoSeaIceModel) = nothing end # module diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 0091a75e..10925962 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -335,6 +335,8 @@ function PrescribedAtmosphere(times, FT=Float64; convert(FT, reference_height)) end +update_model_field_time_series!(::Nothing, time) = nothing + function update_model_field_time_series!(atmos::PrescribedAtmosphere, time) ftses = extract_field_time_series(atmos) for fts in ftses diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index 1bb5020b..914db440 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -1,4 +1,4 @@ -using .CrossRealmFluxes: compute_atmosphere_ocean_fluxes! +using .CrossRealmFluxes: compute_atmosphere_ocean_fluxes!, compute_sea_ice_ocean_fluxes! function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean @@ -44,8 +44,8 @@ function update_state!(coupled_model::OceanSeaIceModel, callbacks=[]; compute_te time = Time(coupled_model.clock.time) update_model_field_time_series!(coupled_model.atmosphere, time) compute_atmosphere_ocean_fluxes!(coupled_model) - # compute_atmosphere_sea_ice_fluxes!(coupled_model) - # compute_sea_ice_ocean_fluxes!(coupled_model) + compute_sea_ice_ocean_fluxes!(coupled_model) + #compute_atmosphere_sea_ice_fluxes!(coupled_model) return nothing end From f57edb328c64c27b875e0f732c9d304ce933030e Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Mon, 12 Feb 2024 13:21:11 +0200 Subject: [PATCH 136/182] resolve deps --- Manifest.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index ec617c0a..f8603fe9 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -741,17 +741,17 @@ 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 = "85b0b81c4f6d542ab79b095d98de4e2773e03d65" +git-tree-sha1 = "f6e83dea28d816e28b1765b84503815c43ebf697" repo-rev = "ss-glw/time-bcs" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.7" [deps.Oceananigans.extensions] - OceananigansEnzymeCoreExt = "EnzymeCore" + OceananigansEnzymeExt = "Enzyme" [deps.Oceananigans.weakdeps] - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" [[deps.OffsetArrays]] git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" From d628e0f03832806430479da910b1ca096f849c93 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Mon, 12 Feb 2024 13:21:27 +0200 Subject: [PATCH 137/182] import compute_sea_ice_ocean_fluxes! --- src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl | 1 - .../CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl | 5 ++--- src/OceanSeaIceModels/OceanSeaIceModels.jl | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 815ba70f..2607a7ff 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -66,4 +66,3 @@ include("sea_ice_ocean_fluxes.jl") # include("atmosphere_sea_ice_fluxes.jl") end # module - diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 80c48b1c..b10cf51c 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -237,7 +237,7 @@ const f = Face() atmosphere_reference_height, atmos_thermodynamics_parameters, roughness_lengths) - + i, j = @index(Global, NTuple) kᴺ = size(grid, 3) @@ -299,7 +299,7 @@ const f = Face() dynamic_ocean_state, dynamic_atmos_state, ℂₐ, g, ϰ) - + Qv = similarity_theory_fields.latent_heat Qc = similarity_theory_fields.sensible_heat Fv = similarity_theory_fields.water_vapor @@ -456,4 +456,3 @@ end interp_atmos_time_series(ΣJ[2], args...) + interp_atmos_time_series(ΣJ[3], args...) + interp_atmos_time_series(ΣJ[4], args...) - diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 871cbfa1..20262e86 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -52,7 +52,7 @@ include("ocean_sea_ice_model.jl") include("ocean_only_model.jl") include("time_step_ocean_sea_ice_model.jl") -import .CrossRealmFluxes: compute_atmosphere_ocean_fluxes! +import .CrossRealmFluxes: compute_atmosphere_ocean_fluxes!, compute_sea_ice_ocean_fluxes! # "No atmosphere" implementation const NoAtmosphereModel = OceanSeaIceModel{<:Any, Nothing} From 1633849d6a934da3094043316375d3de22bab9f2 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 12 Feb 2024 08:25:25 -0500 Subject: [PATCH 138/182] Seems to be working with constant roughness length --- .../prototype_omip_simulation/Project.toml | 1 + .../freely_decaying_regional_simulation.jl | 11 +- .../omip_components.jl | 60 +- .../regional_omip_simulation.jl | 67 +- .../updated_Manifest.toml | 2290 +++++++++++++++++ .../ocean_sea_ice_surface_fluxes.jl | 8 +- .../similarity_theory_turbulent_fluxes.jl | 53 +- src/OceanSeaIceModels/OceanSeaIceModels.jl | 5 +- 8 files changed, 2432 insertions(+), 63 deletions(-) create mode 100644 experiments/prototype_omip_simulation/updated_Manifest.toml diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml index 4f05c844..987de0e0 100644 --- a/experiments/prototype_omip_simulation/Project.toml +++ b/experiments/prototype_omip_simulation/Project.toml @@ -1,4 +1,5 @@ [deps] +CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" diff --git a/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl b/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl index ad100524..23585c82 100644 --- a/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl +++ b/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl @@ -17,13 +17,13 @@ start_time = time_ns() include("omip_components.jl") -arch = GPU() +arch = CPU() epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) start_seconds = Second(date - epoch).value Te = ecco2_field(:temperature, date) Se = ecco2_field(:salinity, date) -ℋe = ecco2_field(:sea_ice_thickness, date) +# ℋe = ecco2_field(:sea_ice_thickness, date) land = interior(Te) .< -10 interior(Te)[land] .= NaN @@ -54,7 +54,7 @@ zf = znodes(Te.grid, Face()) Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) Sᵢ = interior(Se, i₁:i₂, j₁:j₂, :) -ℋᵢ = interior(ℋe, i₁:i₂, j₁:j₂, :) +# ℋᵢ = interior(ℋe, i₁:i₂, j₁:j₂, :) # Construct bottom_height depth by analyzing T Nx, Ny, Nz = size(Tᵢ) @@ -71,7 +71,7 @@ end Tᵢ = arch_array(arch, Tᵢ) Sᵢ = arch_array(arch, Sᵢ) -ℋᵢ = arch_array(arch, ℋᵢ) +# ℋᵢ = arch_array(arch, ℋᵢ) if longitude[2] - longitude[1] == 360 TX = Periodic @@ -86,6 +86,8 @@ grid = LatitudeLongitudeGrid(arch; latitude, longitude, topology = (Periodic, Bounded, Bounded)) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + +#= ocean = omip_ocean_component(grid) sea_ice = omip_sea_ice_component(ocean.model) @@ -142,3 +144,4 @@ coupled_simulation.output_writers[:seaice] = JLD2OutputWriter(sea_ice.model, (; overwrite_existing = true) run!(coupled_simulation) +=# diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl index 5ab4a1c6..bd5e7629 100644 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -11,7 +11,22 @@ using ClimaSeaIce.HeatBoundaryConditions: IceWaterThermalEquilibrium using SeawaterPolynomials.TEOS10: TEOS10EquationOfState -function regional_ecco2_grid(arch, Te, other_fields...; latitude, longitude) +function regional_ecco2_grid(arch, Te, other_fields...; + latitude, + longitude = (0, 360), + halo = (3, 3, 3)) + + start_time = time_ns() + + land = interior(Te) .< -10 + interior(Te)[land] .= NaN + + Nf = length(other_fields) + + ft = ntuple(Nf) do n + fe = other_fields[n] + interior(fe)[land] .= NaN + end i₁ = 4 * first(longitude) + 1 i₂ = 1440 - 4 * (360 - last(longitude)) @@ -23,21 +38,22 @@ function regional_ecco2_grid(arch, Te, other_fields...; latitude, longitude) j₂ > j₁ || error("latitude $latitude is invalid.") Ny = j₂ - j₁ + 1 - zc = znodes(Te) zf = znodes(Te.grid, Face()) - Δz = first(zspacings(Te.grid, Center())) + Nz = length(zf) - 1 - Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) + grid = LatitudeLongitudeGrid(arch; latitude, longitude, + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = zf) # Construct bottom_height depth by analyzing T - Nx, Ny, Nz = size(Tᵢ) + Δz = first(zspacings(Te.grid, Center())) bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) - land = Tᵢ .< -10 - Tᵢ[land] .= NaN + Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) for i = 1:Nx, j = 1:Ny - @inbounds for k = Nz:-1:1 + for k = Nz:-1:1 if isnan(Tᵢ[i, j, k]) bottom_height[i, j] = zf[k+1] break @@ -45,33 +61,24 @@ function regional_ecco2_grid(arch, Te, other_fields...; latitude, longitude) end end - Tᵢ = arch_array(arch, Tᵢ) - - Tx = if longitude[2] - longitude[1] == 360 - Periodic - else - Bounded - end - - grid = LatitudeLongitudeGrid(arch; latitude, longitude, - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = zf, - topology = (Periodic, Bounded, Bounded)) - grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + Tᵢ = arch_array(arch, Tᵢ) + Nf = length(other_fields) ft = ntuple(Nf) do n fe = other_fields[n] fᵢ = interior(fe, i₁:i₂, j₁:j₂, :) - fᵢ[land] .= NaN fᵢ = arch_array(arch, fᵢ) end all_fields = tuple(Tᵢ, ft...) + elapsed = 1e-9 * (time_ns() - start_time) + @info string("Grid for regional omip simulation generated in ", prettytime(elapsed), ".") + @show grid + return grid, all_fields end @@ -116,9 +123,8 @@ function omip_ocean_component(grid; tracers = tuple(:e, tracers...) end - ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, + ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, tracers, tracer_advection, momentum_advection, - tracers = (:T, :S), #, :e), free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), boundary_conditions = ocean_boundary_conditions, coriolis = HydrostaticSphericalCoriolis()) @@ -126,7 +132,7 @@ function omip_ocean_component(grid; ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) elapsed = time_ns() - start_time - msg = string("Finished building ocean component. (" * prettytime(elapsed * 1e-9), ")") + msg = string("Finished building ocean component (" * prettytime(elapsed * 1e-9), ").") @info msg return ocean @@ -182,7 +188,7 @@ function omip_sea_ice_component(ocean_model) sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) elapsed = time_ns() - start_time - msg = string("Finished building sea ice component. (" * prettytime(elapsed * 1e-9), ")") + msg = string("Finished building sea ice component (" * prettytime(elapsed * 1e-9), ").") @info msg return sea_ice diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index abd6192a..c6cde586 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -29,16 +29,18 @@ start_seconds = Second(date - epoch).value Te = ecco2_field(:temperature, date) Se = ecco2_field(:salinity, date) -latitude = (-45, +45) -longitude = (0, 360) -grid, (Tᵢ, Sᵢ) = regional_ecco2_grid(arch, Te, Se; latitude, longitude) +latitude = (-30, 30) +grid, (Tᵢ, Sᵢ) = regional_ecco2_grid(arch, Te, Se; latitude) Nt = 8 * 30 atmosphere = JRA55_prescribed_atmosphere(arch, 1:Nt; backend=InMemory(8)) radiation = Radiation() sea_ice = nothing -ocean = omip_ocean_component(grid, closure=RiBasedVerticalDiffusivity()) +#closure = RiBasedVerticalDiffusivity(maximum_diffusivity=1e2, maximum_viscosity=1e2) +#closure = RiBasedVerticalDiffusivity() +closure = :default +ocean = omip_ocean_component(grid; closure) set!(ocean.model, T=Tᵢ, S=Sᵢ) if :e ∈ keys(ocean.model.tracers) @@ -48,14 +50,50 @@ end coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) coupled_model.clock.time = start_seconds stop_time = start_seconds + 30days -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=stop_time) +coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=stop_time) -elapsed = time_ns() - start_time -@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) +elapsed = 1e-9 * (time_ns() - start_time) +@info string("Coupled simulation built ", prettytime(elapsed), ".") start_time = time_ns() wall_clock = Ref(time_ns()) +# Hm... + +function clip_diffusivity(coupled_simulation) + ocean_model = coupled_simulation.model.ocean.model + κᶜ = parent(ocean_model.diffusivity_fields.κᶜ) + κᵘ = parent(ocean_model.diffusivity_fields.κᵘ) + @. κᶜ = min(κᶜ, 100) + @. κᵘ = min(κᵘ, 100) + return nothing +end + +coupled_simulation.callbacks[:clip] = Callback(clip_diffusivity) + +##### +##### Progress +##### + +Jᵘ = coupled_model.fluxes.total.ocean.momentum.u +Jᵛ = coupled_model.fluxes.total.ocean.momentum.v +Jᵀ = coupled_model.fluxes.total.ocean.tracers.T +Jˢ = coupled_model.fluxes.total.ocean.tracers.S +Fv = coupled_model.fluxes.turbulent.fields.water_vapor +Qc = coupled_model.fluxes.turbulent.fields.sensible_heat +Qv = coupled_model.fluxes.turbulent.fields.latent_heat +ρₒ = coupled_model.fluxes.ocean_reference_density +cₚ = coupled_model.fluxes.ocean_heat_capacity + +import Oceananigans.Fields: reduced_dimensions +reduced_dimensions(::Oceananigans.AbstractOperations.BinaryOperation) = tuple(3) + +ΣQ = ρₒ * cₚ * Jᵀ +τˣ = ρₒ * Jᵘ +τʸ = ρₒ * Jᵛ +N² = buoyancy_frequency(ocean.model) +κᶜ = ocean.model.diffusivity_fields.κᶜ + function progress(sim) msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) @@ -69,8 +107,14 @@ function progress(sim) T = sim.model.ocean.model.tracers.T S = sim.model.ocean.model.tracers.S - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", maximum(T), minimum(T)) - msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) + msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) + msg *= @sprintf(", max|τ|: (%.2e, %.2e) N m⁻²", maximum(τˣ), maximum(τʸ)) + msg *= @sprintf(", max|Qv|: %.2e W m⁻²", maximum(Qv)) + msg *= @sprintf(", max|Qc|: %.2e W m⁻²", maximum(Qc)) + msg *= @sprintf(", extrema(ΣQ): (%.2e, %.2e) W m⁻²", minimum(ΣQ), maximum(ΣQ)) + msg *= @sprintf(", extrema(Fv): (%.2e, %.2e) kg s⁻¹ m⁻²", minimum(Fv), maximum(Fv)) + msg *= @sprintf(", extrema(κᶜ): (%.2e, %.2e) m² s⁻¹", minimum(κᶜ), maximum(κᶜ)) #e = sim.model.ocean.model.tracers.e #msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) @@ -78,7 +122,7 @@ function progress(sim) @info msg end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) run!(coupled_simulation) @@ -110,12 +154,10 @@ outputs = merge(fields, fluxes) filename = "regional_omip_simulation" -#= coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, fluxes; filename = filename * "_fluxes", schedule = TimeInterval(1days), overwrite_existing = true) -=# coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; filename = filename * "_fields", @@ -123,3 +165,4 @@ coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, field schedule = TimeInterval(1days), overwrite_existing = true) +=# diff --git a/experiments/prototype_omip_simulation/updated_Manifest.toml b/experiments/prototype_omip_simulation/updated_Manifest.toml new file mode 100644 index 00000000..7aa5a0b8 --- /dev/null +++ b/experiments/prototype_omip_simulation/updated_Manifest.toml @@ -0,0 +1,2290 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.0-beta3" +manifest_format = "2.0" +project_hash = "0892c27a537f93187841c13e787e804f45c1eef4" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.3.0" + +[[deps.AbstractTrees]] +git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.4" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Test"] +git-tree-sha1 = "cb96992f1bec110ad211b7e410e57ddf7944c16f" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.35" + + [deps.Accessors.extensions] + AccessorsAxisKeysExt = "AxisKeys" + AccessorsIntervalSetsExt = "IntervalSets" + AccessorsStaticArraysExt = "StaticArrays" + AccessorsStructArraysExt = "StructArrays" + + [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" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "3.7.2" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "bbec08a37f8722786d87bedf84eae19c020c4efa" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.7.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + 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" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.Automa]] +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "1.0.3" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random", "Test"] +git-tree-sha1 = "dbf84058d0a8cbbadee18d25cf606934b22d7c66" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.4.2" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.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 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.2" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm]] +deps = ["CRlibm_jll"] +git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "1.0.1" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "Statistics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "95ac638373ac40e29c1b6d086a3698f5026ff6a6" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.1.2" +weakdeps = ["ChainRulesCore", "SpecialFunctions"] + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.7.0+1" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "bcc4a23cbbd99c8535a5318455dcf0f2546ec536" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.2.2" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "9704e50c9158cf8896c2776b8dbc5edd136caf80" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.10.1+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.16.1+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "c1deebd76f7a443d527fc0430d5758b8b2112ed8" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.19.1" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ClimaOcean]] +deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +path = "../.." +uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +version = "0.1.0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" +repo-rev = "main" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.1.0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.3" + +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf"] +git-tree-sha1 = "7f5717cbb2c1ce650cfd454451f282df33103596" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.2.5" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.12.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.0.5+1" + +[[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 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.3.0" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.4" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.2" + +[[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 = "253193dfb0384646936c5ff3230b27a20d91261e" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.2.4" + +[[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 = "d481f6419c262edcb7294179bd63249d123eb081" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.12" + +[[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 = "ac67408d9ddf207de5cfa9a97e114352430f01ed" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.16" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "26eb8e2331b55735c3d305d949aabd7363f07ba7" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.11" + +[[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 = ["OffsetArrays"] +git-tree-sha1 = "1bfa9de80f35ac63c6c381b2d43c590875896a1f" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.3.22" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.107" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.Elliptic]] +git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" +uuid = "b305315f-e792-5b7a-8f41-49f472929428" +version = "1.0.1" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.ErrorfreeArithmetic]] +git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.5.2" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] +git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.5" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.Extents]] +git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.2" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "4.4.4+1" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.8.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + +[[deps.FastRounding]] +deps = ["ErrorfreeArithmetic", "LinearAlgebra"] +git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.3.1" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.2" + +[[deps.FilePaths]] +deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] +git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" +uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" +version = "0.8.3" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] +git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.21" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra", "Random"] +git-tree-sha1 = "5b93957f6dcd33fc343044af3d48c215be2562f1" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.9.3" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "73d1214fec245096717847c62d389a5d2ac86504" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.22.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Formatting]] +deps = ["Printf"] +git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8" +uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" +version = "0.4.2" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.1" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.1" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GLFW]] +deps = ["GLFW_jll"] +git-tree-sha1 = "35dbc482f0967d8dceaa7ce007d16f9064072166" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "3.4.1" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.3.9+0" + +[[deps.GLMakie]] +deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] +git-tree-sha1 = "e53267e2fc64f81b939849ca7bd70d8f879b5293" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.9.5" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] +git-tree-sha1 = "85d7fb51afb3def5dcb85ad31c3707795c8bccc1" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "9.1.0" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "2d6ca471a6c7b536127afccfa7564b5b39227fe0" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.5" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.25.0" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.3" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "424a5a6ce7c5d97cca7bcc4eac551b97294c54af" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.9" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "e94c92c7bf4819685eb80186d51c43e71d4afa17" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.76.5+0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "af13a277efd8a6e716d79ef635d5342ccb75be61" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.10.0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "38c8874692d48d5440d5752d6c74b0c6b0b60739" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.2+1" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "abbbb9ec3afd783a7cbd82ef01dcd088ea051398" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.1" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.10.0+0" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.7" + +[[deps.ImageCore]] +deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "fc5d1d3443a124fde6e92d0260cd9e064eba69f8" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.1" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IncompleteLU]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" +uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" +version = "0.2.1" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.0.2+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.15.1" + + [deps.Interpolations.extensions] + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] +git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.20.9" + +[[deps.IntervalSets]] +deps = ["Dates", "Random"] +git-tree-sha1 = "3d8866c029dd6b16e69e0d4a939c4dfcb98fac47" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.8" +weakdeps = ["Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsStatisticsExt = "Statistics" + +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "68772f49f54b479fa88ace904f6127f0a3bb2e46" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.12" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.10.0" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "b435d190ef8369cf4d79cc9dd5fba88ba0165307" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.3" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] +git-tree-sha1 = "7c0008f0b7622c6c0ee5c65cbc667b69f8a65672" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.45" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.5" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "60b1194df0a3298f460063de985eae7b01bc011a" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.1+0" + +[[deps.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "4e0cb2f5aad44dcfdc91088e85dee4ecb22c791c" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.16" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.8" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] +git-tree-sha1 = "cb4619f7353fc62a1a22ffa3d7ed9791cfb47ad8" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "6.4.2" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "98eaee04d96d973e79c25d49167668c5c8fb50e2" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.27+1" + +[[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.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.0.1+1" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.6.0+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.35.0+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.36.0+0" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.1" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] +git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.2.7" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.26" + + [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.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.0.0+0" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "b4d8707e42b693720b54f0b3434abee6dd4d947a" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.16" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "2ee75365ca243c1a39d467e35ffd3d4d32eef11e" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.1.2+1" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.10" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "8eeb3c73bbc0ca203d0dc8dad4008350bbe5797b" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.3.1+1" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "a37c6610dd20425b131caf65d52abdf859da5ab1" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.20.4" + +[[deps.MakieCore]] +deps = ["Observables", "REPL"] +git-tree-sha1 = "ec5db7bb2dc9b85072658dcb2d3ad09569b09ac9" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.7.2" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] +git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.7" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] +git-tree-sha1 = "8be09d84a2d597c7c0c34d7d604c039c9763e48c" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.4.10" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "b01beb91d20b0d1312a9471a36017b5b339d26de" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+1" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "b76ea40b5c0f45790ae09492712dd326208c28b2" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.1.7" + +[[deps.Mods]] +git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "2.2.4" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "173a378f357e9bb24b22019efb5e4778223ce8cf" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.13.2" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "0.3.4" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.1.0+2" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "XML2_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "10c612c81eaffdd6b7c28a45a554cdd9d2f40ff1" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "400.902.208+0" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.Oceananigans]] +deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "6e05bd0bf05a8f9fc09c8cc387d0160d0724e014" +repo-rev = "ss-glw/time-bcs" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.90.7" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+2" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+2" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] +git-tree-sha1 = "1d1421618bab0e820bdc7ae1a2b46ce576981273" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.1+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.1" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.12+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.Optim]] +deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.7.8" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.31" + +[[deps.PMIx_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] +git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" +uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" +version = "4.2.7+0" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.3" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.PencilArrays]] +deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] +git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" +uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" +version = "0.19.3" + + [deps.PencilArrays.extensions] + PencilArraysDiffEqExt = ["DiffEqBase"] + PencilArraysHDF5Ext = ["HDF5"] + + [deps.PencilArrays.weakdeps] + DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" + HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" + +[[deps.PencilFFTs]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" +uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" +version = "0.15.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.20" + +[[deps.PikaParser]] +deps = ["DocStringExtensions"] +git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" +uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" +version = "0.6.1" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "862942baf5663da528f66d24996eb6da85218e76" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.0" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.6" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.0" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.1" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.1" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "1d05623b5952aed1307bf8b43bec8b8d1ef94b6e" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.5" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.ProgressBars]] +deps = ["Printf"] +git-tree-sha1 = "b437cdb0385ed38312d91d9c00c20f3798b30256" +uuid = "49802e3a-d2f1-5c88-81d8-b72133a6f568" +version = "1.5.1" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.9.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.4" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "9a46862d248ea548e340e30e2894118749dc7f51" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.5" + +[[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 = "c860e84651f58ce240dd79e5d9e055d55234c35a" +uuid = "74087812-796a-5b5d-8853-05524746bad3" +version = "1.6.2" + +[[deps.RandomNumbers]] +deps = ["Random", "Requires"] +git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111" +uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" +version = "1.5.3" + +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.RootSolvers]] +deps = ["ForwardDiff"] +git-tree-sha1 = "833d9914e748ca9329b762a82ec912897975f8d8" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.1" + +[[deps.Roots]] +deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] +git-tree-sha1 = "af540898b1e6ca7aa6ba7213c05052809c6c522a" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.1.0" + + [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 = "792d8fd4ad770b6d517a13ebb8dadfcac79405b8" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.6.1" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +repo-rev = "glw/heat-capacity" +repo-url = "https://github.com/CliMA/SeawaterPolynomials.jl.git" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.4" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SetRounding]] +git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.1" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "db0219befe4507878b1a90e07820fed3e62c289d" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.4.0" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.6" + +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "e9330391d04241eafdc358713b48396619c83bcb" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.1" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.17" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableHashTraits]] +deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "662f56ffe22b3985f3be7474f0aecbaf214ecf0f" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.1.6" + +[[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 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "0.8.8" + +[[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 = "f68dd04d131d9a8a8eb836173ee8f105c360b0c5" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.1" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.StaticPermutations]] +git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" +uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" +version = "0.3.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.2" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.0" +weakdeps = ["ChainRulesCore", "InverseFunctions"] + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + +[[deps.Strided]] +deps = ["LinearAlgebra", "StridedViews", "TupleTools"] +git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "2.0.4" + +[[deps.StridedViews]] +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" +uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" +version = "0.2.2" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructArrays]] +deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] +git-tree-sha1 = "1b0b1205a56dc288b71b1961d48e351520702e24" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.17" + +[[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", "Pkg", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.0+1" + +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "6431256ee7c06ed2900fd46688f355e5a43e90eb" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.9.1" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "CLIMAParameters" + + [deps.SurfaceFluxes.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TaylorSeries]] +deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] +git-tree-sha1 = "9138fdc8ee4e3b8839eca696a76d15e16c9c7af0" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.15.4" +weakdeps = ["IntervalArithmetic"] + + [deps.TaylorSeries.extensions] + TaylorSeriesIAExt = "IntervalArithmetic" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "f4555e1302df12011b836fbdcdd3e10e5df7329a" +repo-rev = "glw/density-example" +repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.11.5" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "CLIMAParameters" + + [deps.Thermodynamics.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.8" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.23" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.2" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + +[[deps.TupleTools]] +git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.4.3" + +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.2.1" + +[[deps.UnsafeAtomicsLLVM]] +deps = ["LLVM", "UnsafeAtomics"] +git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.3" + +[[deps.VersionParsing]] +git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.3.0" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.2+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.0+4" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "5.0.3+4" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.7.10+4" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] +git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.4+4" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.2+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.5+0" + +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eddd19a8dea6b139ea97bdc8a0e2667d4b661720" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.0.6+1" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.libevent_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll"] +git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" +uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" +version = "2.1.13+1" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "93284c28274d9e75218a416c65ec49d0e0fcdf3d" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.40+0" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[deps.prrte_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_jll"] +git-tree-sha1 = "5adb2d7a18a30280feb66cad6f1a1dfdca2dc7b0" +uuid = "eb928a42-fffd-568d-ab9c-3f5d54fc65b9" +version = "3.0.2+0" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 80c48b1c..e59fafa6 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -358,10 +358,10 @@ end Mp = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_args...) Qc = similarity_theory_fields.sensible_heat[i, j, 1] # sensible or "conductive" heat flux - Qv = similarity_theory_fields.latent_heat[i, j, 1] # sensible or "conductive" heat flux - Mv = similarity_theory_fields.water_vapor[i, j, 1] # sensible or "conductive" heat flux - τx = similarity_theory_fields.x_momentum[i, j, 1] # sensible or "conductive" heat flux - τy = similarity_theory_fields.y_momentum[i, j, 1] # sensible or "conductive" heat flux + Qv = similarity_theory_fields.latent_heat[i, j, 1] # latent heat flux + Mv = similarity_theory_fields.water_vapor[i, j, 1] # mass flux of water vapor + τx = similarity_theory_fields.x_momentum[i, j, 1] # zonal momentum flux + τy = similarity_theory_fields.y_momentum[i, j, 1] # meridional momentum flux end # Compute heat fluxes, bulk flux first diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index f89f4599..8f1267b1 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -50,11 +50,11 @@ const STTF = SimilarityTheoryTurbulentFluxes Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), adapt(to, fluxes.von_karman_constant), - adapt(to, fluxes.bulk_velocity_scale), + nothing, # adapt(to, fluxes.bulk_velocity_scale), adapt(to, fluxes.similarity_functions), adapt(to, fluxes.thermodynamics_parameters), - adapt(to, fluxes.water_vapor_saturation), - adapt(to, fluxes.water_mole_fraction), + nothing, #adapt(to, fluxes.water_vapor_saturation), + nothing, #adapt(to, fluxes.water_mole_fraction), adapt(to, fluxes.roughness_lengths), adapt(to, fluxes.fields)) @@ -107,8 +107,8 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), - # roughness_lengths = default_roughness_lengths(FT), - roughness_lengths = SimilarityScales(1e-3, 1e-3, 1e-3), + #roughness_lengths = default_roughness_lengths(FT), + roughness_lengths = SimilarityScales(1e-4, 1e-4, 1e-4), fields = nothing) return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), @@ -244,17 +244,40 @@ SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature const NothingVaporRoughnessLength = SimilarityScales{<:Number, <:Number, Nothing} @inline function compute_similarity_theory_fluxes(roughness_lengths::NothingVaporRoughnessLength, - turbulent_fluxes, - atmos_state, - surface_state) + surface_state, + atmos_state, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) + + # turbulent_fluxes, + # atmos_state, + # surface_state) + + FT = Float64 + similarity_functions = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), + a_m = convert(FT, 4.7), + a_h = convert(FT, 4.7), + ζ_a = convert(FT, 2.5), + γ = convert(FT, 4.42)) + + turbulent_fluxes = SimilarityTheoryTurbulentFluxes(gravitational_acceleration, + von_karman_constant, + nothing, + similarity_functions, + thermodynamics_parameters, + nothing, + nothing, + nothing, + nothing) # Constant roughness lengths ℓu = roughness_lengths.momentum ℓθ = roughness_lengths.temperature # Solve for the surface fluxes with initial roughness length guess - Uᵍ = zero(zm) # gustiness - β = one(zm) # surface "resistance" + Uᵍ = zero(ℓu) # gustiness + β = one(ℓu) # surface "resistance" values = SurfaceFluxes.ValuesOnly(atmos_state, surface_state, ℓu, ℓθ, Uᵍ, β) conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) @@ -405,11 +428,11 @@ end ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) fluxes = (; - water_vapor = ρₐ * u★ * q★, - sensible_heat = ρₐ * cₚ * u★ * θ★, - latent_heat = ρₐ * u★ * q★ * ℰv, - x_momentum = ρₐ * τx, - y_momentum = ρₐ * τy, + water_vapor = + ρₐ * u★ * q★, + sensible_heat = + ρₐ * cₚ * u★ * θ★, + latent_heat = - ρₐ * u★ * q★ * ℰv, + x_momentum = + ρₐ * τx, + y_momentum = + ρₐ * τy, ) return fluxes diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 871cbfa1..170c3baa 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -52,11 +52,14 @@ include("ocean_sea_ice_model.jl") include("ocean_only_model.jl") include("time_step_ocean_sea_ice_model.jl") -import .CrossRealmFluxes: compute_atmosphere_ocean_fluxes! +import .CrossRealmFluxes: + compute_atmosphere_ocean_fluxes!, + compute_sea_ice_ocean_fluxes! # "No atmosphere" implementation const NoAtmosphereModel = OceanSeaIceModel{<:Any, Nothing} const NoSeaIceModel = OceanSeaIceModel{Nothing} + compute_atmosphere_ocean_fluxes!(coupled_model::NoAtmosphereModel) = nothing compute_sea_ice_ocean_fluxes!(coupled_model::NoSeaIceModel) = nothing From fde49accea04688564667639cee2602e4d6fd87b Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 12 Feb 2024 12:27:23 -0500 Subject: [PATCH 139/182] Fix sign error in flux-scale relationship --- .../prototype_omip_simulation/regional_omip_simulation.jl | 4 ++-- .../similarity_theory_turbulent_fluxes.jl | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index c6cde586..e02c2481 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -29,7 +29,7 @@ start_seconds = Second(date - epoch).value Te = ecco2_field(:temperature, date) Se = ecco2_field(:salinity, date) -latitude = (-30, 30) +latitude = (-75, 75) grid, (Tᵢ, Sᵢ) = regional_ecco2_grid(arch, Te, Se; latitude) Nt = 8 * 30 @@ -122,7 +122,7 @@ function progress(sim) @info msg end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) run!(coupled_simulation) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 8f1267b1..2cecefe3 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -419,8 +419,8 @@ end q★ = Γ★.water_vapor # u★² ≡ sqrt(τx² + τy²) - τx = u★^2 * Δu / sqrt(Δu^2 + Δv^2) - τy = u★^2 * Δv / sqrt(Δu^2 + Δv^2) + τx = - u★^2 * Δu / sqrt(Δu^2 + Δv^2) + τy = - u★^2 * Δv / sqrt(Δu^2 + Δv^2) 𝒬ₐ = atmos_state.ts ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) @@ -428,8 +428,8 @@ end ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) fluxes = (; - water_vapor = + ρₐ * u★ * q★, - sensible_heat = + ρₐ * cₚ * u★ * θ★, + water_vapor = - ρₐ * u★ * q★, + sensible_heat = - ρₐ * cₚ * u★ * θ★, latent_heat = - ρₐ * u★ * q★ * ℰv, x_momentum = + ρₐ * τx, y_momentum = + ρₐ * τy, From 0a891d86506706120f6353c722ca2764921bdd42 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 12 Feb 2024 10:29:06 -0700 Subject: [PATCH 140/182] Start working on realistic roughness length --- .../similarity_theory_turbulent_fluxes.jl | 52 +++++++++++++++---- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 8f1267b1..ec2dbc9d 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -91,12 +91,6 @@ function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) end -function default_roughness_lengths(FT=Float64) - momentum = convert(FT, 1e-4) - heat = convert(FT, 1e-4) - return SimilarityScales(momentum, heat) -end - const PATP = PrescribedAtmosphereThermodynamicsParameters function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; @@ -107,8 +101,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), - #roughness_lengths = default_roughness_lengths(FT), - roughness_lengths = SimilarityScales(1e-4, 1e-4, 1e-4), + roughness_lengths = default_roughness_lengths(FT), fields = nothing) return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), @@ -428,7 +421,7 @@ end ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) fluxes = (; - water_vapor = + ρₐ * u★ * q★, + water_vapor = - ρₐ * u★ * q★, sensible_heat = + ρₐ * cₚ * u★ * θ★, latent_heat = - ρₐ * u★ * q★ * ℰv, x_momentum = + ρₐ * τx, @@ -438,6 +431,8 @@ end return fluxes end +@inline compute_roughness_length(ℓ::Number, Γ★) + @inline function refine_characteristic_scales(estimated_characteristic_scales, roughness_lengths, surface_state, @@ -450,12 +445,17 @@ end u★ = estimated_characteristic_scales.momentum θ★ = estimated_characteristic_scales.temperature q★ = estimated_characteristic_scales.water_vapor + Γ★ = estimated_characteristic_scales # Extract roughness lengths ℓu = roughness_lengths.momentum ℓθ = roughness_lengths.temperature ℓq = roughness_lengths.water_vapor + ℓu₀ = compute_roughness_length(ℓu₀, Γ★) + ℓθ₀ = compute_roughness_length(ℓθ₀, Γ★) + ℓq₀ = compute_roughness_length(ℓq₀, Γ★) + # Compute flux Richardson number h = differences.h ϰ = von_karman_constant @@ -486,10 +486,40 @@ end return SimilarityScales(u★, θ★, q★) end -#= struct GravityWaveRoughnessLength{FT} gravitational_acceleration :: FT + air_kinematic_viscosity :: FT gravity_wave_parameter :: FT laminar_parameter :: FT end -=# + +function GravityWaveRoughnessLength(FT=Float64; + gravitational_acceleration = default_gravitational_acceleration, + air_kinematic_viscosity = 1.5e-5, + gravity_wave_parameter = 0.011, + laminar_parameter = 0.11) + + return GravityWaveRoughnessLength(convert(FT, gravitational_acceleration), + convert(FT, air_kinematic_viscosity), + convert(FT, gravity_wave_parameter), + convert(FT, laminar_parameter)) +end + +@inline function compute_roughness_length(ℓ::GravityWaveRoughnessLength, Γ★) + u★ = Γ★.momentum + g = ℓ.gravitational_acceleration + ν = ℓ.air_kinematic_viscosity + α = ℓ.gravity_wave_parameter + β = ℓ.laminar_parameter + + return α * u★^2 / g + β * ν / u★ +end + +function default_roughness_lengths(FT=Float64) + momentum = GravityWaveRoughnessLength(FT) + temperature = convert(FT, 1e-4) + water_vapor = convert(FT, 1e-4) + return SimilarityScales(momentum, temperature, water_vapor) +end + + From 298c1c501d056d4ab158d50d753dd9ad1f35e72d Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 12 Feb 2024 10:43:51 -0700 Subject: [PATCH 141/182] Change notation and fix a bug --- .../similarity_theory_turbulent_fluxes.jl | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 7463d2ae..2ba309b9 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -395,10 +395,10 @@ end differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) # Solve for the characteristic scales u★, θ★, q★, and thus for fluxes. - Γ₀ = Γ★ = SimilarityScales(1e-3, 1e-3, 1e-3) + Σ₀ = Σ★ = SimilarityScales(1e-3, 1e-3, 1e-3) @unroll for iter = 1:10 - Γ★ = refine_characteristic_scales(Γ★, + Σ★ = refine_characteristic_scales(Σ★, roughness_lengths, surface_state, differences, @@ -407,9 +407,9 @@ end von_karman_constant) end - u★ = Γ★.momentum - θ★ = Γ★.temperature - q★ = Γ★.water_vapor + u★ = Σ★.momentum + θ★ = Σ★.temperature + q★ = Σ★.water_vapor # u★² ≡ sqrt(τx² + τy²) τx = - u★^2 * Δu / sqrt(Δu^2 + Δv^2) @@ -431,7 +431,7 @@ end return fluxes end -@inline compute_roughness_length(ℓ::Number, Γ★) +@inline compute_roughness_length(ℓ::Number, Σ★) @inline function refine_characteristic_scales(estimated_characteristic_scales, roughness_lengths, @@ -445,16 +445,16 @@ end u★ = estimated_characteristic_scales.momentum θ★ = estimated_characteristic_scales.temperature q★ = estimated_characteristic_scales.water_vapor - Γ★ = estimated_characteristic_scales + Σ★ = estimated_characteristic_scales # Extract roughness lengths ℓu = roughness_lengths.momentum ℓθ = roughness_lengths.temperature ℓq = roughness_lengths.water_vapor - ℓu₀ = compute_roughness_length(ℓu₀, Γ★) - ℓθ₀ = compute_roughness_length(ℓθ₀, Γ★) - ℓq₀ = compute_roughness_length(ℓq₀, Γ★) + ℓu₀ = compute_roughness_length(ℓu, Σ★) + ℓθ₀ = compute_roughness_length(ℓθ, Σ★) + ℓq₀ = compute_roughness_length(ℓq, Σ★) # Compute flux Richardson number h = differences.h @@ -505,8 +505,8 @@ function GravityWaveRoughnessLength(FT=Float64; convert(FT, laminar_parameter)) end -@inline function compute_roughness_length(ℓ::GravityWaveRoughnessLength, Γ★) - u★ = Γ★.momentum +@inline function compute_roughness_length(ℓ::GravityWaveRoughnessLength, Σ★) + u★ = Σ★.momentum g = ℓ.gravitational_acceleration ν = ℓ.air_kinematic_viscosity α = ℓ.gravity_wave_parameter From 8079f1b53db7e3a9326a2ba938aad6ba85d557da Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 12 Feb 2024 10:52:15 -0700 Subject: [PATCH 142/182] Allow old fluxes to be used for first guess --- .../ocean_sea_ice_surface_fluxes.jl | 21 +++++++++++++++++-- .../similarity_theory_turbulent_fluxes.jl | 8 ++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index c8e909af..9a1a6c8e 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -293,12 +293,29 @@ const f = Face() Uₒ = SVector(uₒ, vₒ) 𝒰₀ = dynamic_ocean_state = SurfaceFluxes.StateValues(h₀, Uₒ, 𝒬₀) - g = 9.81 + @inbounds begin + Qcᵢ = Qc[i, j, 1] + Fvᵢ = Fv[i, j, 1] + τxᵢ = τx[i, j, 1] + τyᵢ = τy[i, j, 1] + end + + # Compute initial guess based on previous fluxes + 𝒬ₐ = atmos_state.ts + ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) + cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity + + u★ = sqrt(sqrt(τxᵢ^2 + τyᵢ^2)) + θ★ = - Qcᵢ / (ρₐ * cₚ * u★) + q★ = - Fvᵢ / (ρₐ * u★) + Σ★ = SimilarityScales(u★, θ★, q★) + + g = default_gravitational_acceleration ϰ = 0.4 turbulent_fluxes = compute_similarity_theory_fluxes(roughness_lengths, dynamic_ocean_state, dynamic_atmos_state, - ℂₐ, g, ϰ) + ℂₐ, g, ϰ, Σ★) Qv = similarity_theory_fields.latent_heat Qc = similarity_theory_fields.sensible_heat diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 2ba309b9..f65705a8 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -387,7 +387,8 @@ end atmos_state, thermodynamics_parameters, gravitational_acceleration, - von_karman_constant) + von_karman_constant, + Σ₀ = SimilarityScales(1e-3, 1e-3, 1e-3)) # Prescribed difference between two states ℂₐ = thermodynamics_parameters @@ -395,8 +396,8 @@ end differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) # Solve for the characteristic scales u★, θ★, q★, and thus for fluxes. - Σ₀ = Σ★ = SimilarityScales(1e-3, 1e-3, 1e-3) - + Σ★ = Σ₀ + @unroll for iter = 1:10 Σ★ = refine_characteristic_scales(Σ★, roughness_lengths, @@ -465,6 +466,7 @@ end 𝒬ₒ = surface_state.ts # thermodyanmic state b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, ℂ, g) Riₕ = - ϰ * h * b★ / u★^2 + Riₕ = ifelse(isnan(Riₕ), zero(Riₕ), Riₕ) # Compute similarity functions ψu = SimilarityFunction(4.7, 15.0, OneQuarter()) From 003b74496b244858c734ab8821bc52b801e100bf Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 12 Feb 2024 11:09:02 -0700 Subject: [PATCH 143/182] Add a silly sea ice model --- src/ClimaOcean.jl | 2 +- .../CrossRealmFluxes/sea_ice_ocean_fluxes.jl | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 21db7b57..e7191d97 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -1,6 +1,6 @@ module ClimaOcean -export OceanSeaIceModel +export OceanSeaIceModel, FreezingLimitedOceanTemperature using Oceananigans using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl index dbc9077d..7866953b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl @@ -163,3 +163,39 @@ end @inbounds Qₒ[i, j, 1] = δQ end +##### +##### A fairly dumb, but nevertheless effective "sea ice model" +##### + +struct FreezingLimitedOceanTemperature{L} + liquidus :: L +end + +const FreezingLimitedCoupledModel = OceanSeaIceModel{<:FreezingLimitedOceanTemperature} + +function compute_sea_ice_ocean_fluxes!(cm::FreezingLimitedCoupledModel) + ocean = cm.ocean + liquidus = cm.sea_ice.liquidus + grid = ocean_model.grid + arch = architecture(grid) + Sₒ = ocean.model.tracers.S + Tₒ = ocean.model.tracers.T + + launch!(arch, grid, :xyz, above_freezing_ocean_temperature!, Tₒ, grid, Sₒ, liquidus) + + return nothing +end + +@kernel function above_freezing_ocean_temperature!(Tₒ, Sₒ, liquidus) + + i, j, k = @index(Global, NTuple) + + @inbounds begin + Sᵢ = Sₒ[i, j, k] + Tᵢ = Tₒ[i, j, k] + end + + Tₘ = melting_temperature(liquidus, Sᵢ) + Tₒ = ifelse(Tᵢ < Tₘ, Tₘ, Tᵢ) +end + From df649b97b71f906e0247eb3430b12406fabdad31 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 12 Feb 2024 17:04:33 -0500 Subject: [PATCH 144/182] Bugfixes --- .../regional_omip_simulation.jl | 12 +++--- .../CrossRealmFluxes/CrossRealmFluxes.jl | 2 +- .../ocean_sea_ice_surface_fluxes.jl | 22 +++++----- .../CrossRealmFluxes/sea_ice_ocean_fluxes.jl | 37 ----------------- .../similarity_theory_turbulent_fluxes.jl | 11 ++--- src/OceanSeaIceModels/OceanSeaIceModels.jl | 40 +++++++++++++++++++ .../time_step_ocean_sea_ice_model.jl | 6 ++- 7 files changed, 71 insertions(+), 59 deletions(-) diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index e02c2481..08427e0e 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -5,10 +5,12 @@ using Oceananigans.BuoyancyModels: buoyancy_frequency using Oceananigans.Units: Time using ClimaOcean -using ClimaOcean.OceanSeaIceModels: Radiation +using ClimaOcean.OceanSeaIceModels: Radiation, FreezingLimitedOceanTemperature using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere using ClimaOcean.DataWrangling.ECCO2: ecco2_field +using ClimaSeaIce: LinearLiquidus + # using GLMakie using Printf using Dates @@ -29,13 +31,11 @@ start_seconds = Second(date - epoch).value Te = ecco2_field(:temperature, date) Se = ecco2_field(:salinity, date) -latitude = (-75, 75) +latitude = (-75, -30) grid, (Tᵢ, Sᵢ) = regional_ecco2_grid(arch, Te, Se; latitude) -Nt = 8 * 30 -atmosphere = JRA55_prescribed_atmosphere(arch, 1:Nt; backend=InMemory(8)) +atmosphere = JRA55_prescribed_atmosphere(arch, 1:56; backend=InMemory(8)) radiation = Radiation() -sea_ice = nothing #closure = RiBasedVerticalDiffusivity(maximum_diffusivity=1e2, maximum_viscosity=1e2) #closure = RiBasedVerticalDiffusivity() @@ -47,6 +47,8 @@ if :e ∈ keys(ocean.model.tracers) set!(ocean.model, e=1e-6) end +sea_ice = FreezingLimitedOceanTemperature(LinearLiquidus(eltype(grid))) + coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) coupled_model.clock.time = start_seconds stop_time = start_seconds + 30days diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 2607a7ff..8a423205 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -5,7 +5,7 @@ using Oceananigans export Radiation, OceanSeaIceSurfaceFluxes -using ..OceanSeaIceModels: SKOFTS +using ..OceanSeaIceModels: SKOFTS, default_gravitational_acceleration import ..OceanSeaIceModels: surface_velocities, surface_tracers diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 9a1a6c8e..a71484e5 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -51,6 +51,8 @@ const celsius_to_kelvin = 273.15 Base.summary(crf::OceanSeaIceSurfaceFluxes) = "OceanSeaIceSurfaceFluxes" Base.show(io::IO, crf::OceanSeaIceSurfaceFluxes) = print(io, summary(crf)) +const SlabSeaIceSimulation = Simulation{<:SlabSeaIceModel} + function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; atmosphere = nothing, radiation = nothing, @@ -77,12 +79,12 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; prescribed_fluxes = nothing - if isnothing(sea_ice) - previous_ice_thickness = nothing - previous_ice_concentration = nothing - else + if sea_ice isa SlabSeaIceSimulation previous_ice_thickness = deepcopy(sea_ice.model.ice_thickness) previous_ice_concentration = deepcopy(sea_ice.model.ice_concentration) + else + previous_ice_thickness = nothing + previous_ice_concentration = nothing end ocean_grid = ocean.model.grid @@ -293,6 +295,12 @@ const f = Face() Uₒ = SVector(uₒ, vₒ) 𝒰₀ = dynamic_ocean_state = SurfaceFluxes.StateValues(h₀, Uₒ, 𝒬₀) + Qv = similarity_theory_fields.latent_heat + Qc = similarity_theory_fields.sensible_heat + Fv = similarity_theory_fields.water_vapor + τx = similarity_theory_fields.x_momentum + τy = similarity_theory_fields.y_momentum + @inbounds begin Qcᵢ = Qc[i, j, 1] Fvᵢ = Fv[i, j, 1] @@ -301,7 +309,6 @@ const f = Face() end # Compute initial guess based on previous fluxes - 𝒬ₐ = atmos_state.ts ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity @@ -317,11 +324,6 @@ const f = Face() dynamic_atmos_state, ℂₐ, g, ϰ, Σ★) - Qv = similarity_theory_fields.latent_heat - Qc = similarity_theory_fields.sensible_heat - Fv = similarity_theory_fields.water_vapor - τx = similarity_theory_fields.x_momentum - τy = similarity_theory_fields.y_momentum kᴺ = size(grid, 3) # index of the top ocean cell inactive = inactive_node(i, j, kᴺ, grid, c, c, c) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl index 7866953b..93ddea05 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/sea_ice_ocean_fluxes.jl @@ -1,4 +1,3 @@ -using ClimaSeaIce: melting_temperature using Oceananigans.Operators: Δzᶜᶜᶜ function compute_sea_ice_ocean_fluxes!(coupled_model) @@ -163,39 +162,3 @@ end @inbounds Qₒ[i, j, 1] = δQ end -##### -##### A fairly dumb, but nevertheless effective "sea ice model" -##### - -struct FreezingLimitedOceanTemperature{L} - liquidus :: L -end - -const FreezingLimitedCoupledModel = OceanSeaIceModel{<:FreezingLimitedOceanTemperature} - -function compute_sea_ice_ocean_fluxes!(cm::FreezingLimitedCoupledModel) - ocean = cm.ocean - liquidus = cm.sea_ice.liquidus - grid = ocean_model.grid - arch = architecture(grid) - Sₒ = ocean.model.tracers.S - Tₒ = ocean.model.tracers.T - - launch!(arch, grid, :xyz, above_freezing_ocean_temperature!, Tₒ, grid, Sₒ, liquidus) - - return nothing -end - -@kernel function above_freezing_ocean_temperature!(Tₒ, Sₒ, liquidus) - - i, j, k = @index(Global, NTuple) - - @inbounds begin - Sᵢ = Sₒ[i, j, k] - Tᵢ = Tₒ[i, j, k] - end - - Tₘ = melting_temperature(liquidus, Sᵢ) - Tₒ = ifelse(Tᵢ < Tₘ, Tₘ, Tᵢ) -end - diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index f65705a8..29e47274 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -432,7 +432,8 @@ end return fluxes end -@inline compute_roughness_length(ℓ::Number, Σ★) +@inline compute_roughness_length(ℓ::Number, Σ★) = ℓ +@inline compute_roughness_length(ℓ, Σ★) = ℓ(Σ★) @inline function refine_characteristic_scales(estimated_characteristic_scales, roughness_lengths, @@ -472,9 +473,9 @@ end ψu = SimilarityFunction(4.7, 15.0, OneQuarter()) ψc = SimilarityFunction(6.35, 9.0, OneHalf()) - χu = bulk_factor(ψu, h, ℓu, Riₕ) - χθ = bulk_factor(ψc, h, ℓθ, Riₕ) - χq = bulk_factor(ψc, h, ℓq, Riₕ) + χu = bulk_factor(ψu, h, ℓu₀, Riₕ) + χθ = bulk_factor(ψc, h, ℓθ₀, Riₕ) + χq = bulk_factor(ψc, h, ℓq₀, Riₕ) Δu = differences.u Δv = differences.v @@ -518,7 +519,7 @@ end end function default_roughness_lengths(FT=Float64) - momentum = GravityWaveRoughnessLength(FT) + momentum = 1e-4 #GravityWaveRoughnessLength(FT) temperature = convert(FT, 1e-4) water_vapor = convert(FT, 1e-4) return SimilarityScales(momentum, temperature, water_vapor) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 170c3baa..7bc8e851 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -13,6 +13,8 @@ using Oceananigans.TimeSteppers: tick! using Oceananigans.Models: AbstractModel using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries +using ClimaSeaIce: melting_temperature + using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll @@ -63,5 +65,43 @@ const NoSeaIceModel = OceanSeaIceModel{Nothing} compute_atmosphere_ocean_fluxes!(coupled_model::NoAtmosphereModel) = nothing compute_sea_ice_ocean_fluxes!(coupled_model::NoSeaIceModel) = nothing +##### +##### A fairly dumb, but nevertheless effective "sea ice model" +##### + +struct FreezingLimitedOceanTemperature{L} + liquidus :: L +end + +const FreezingLimitedCoupledModel = OceanSeaIceModel{<:FreezingLimitedOceanTemperature} + +sea_ice_concentration(::FreezingLimitedOceanTemperature) = nothing + +function compute_sea_ice_ocean_fluxes!(cm::FreezingLimitedCoupledModel) + ocean = cm.ocean + liquidus = cm.sea_ice.liquidus + grid = ocean.model.grid + arch = architecture(grid) + Sₒ = ocean.model.tracers.S + Tₒ = ocean.model.tracers.T + + launch!(arch, grid, :xyz, above_freezing_ocean_temperature!, Tₒ, Sₒ, liquidus) + + return nothing +end + +@kernel function above_freezing_ocean_temperature!(Tₒ, Sₒ, liquidus) + + i, j, k = @index(Global, NTuple) + + @inbounds begin + Sᵢ = Sₒ[i, j, k] + Tᵢ = Tₒ[i, j, k] + end + + Tₘ = melting_temperature(liquidus, Sᵢ) + Tₒ = ifelse(Tᵢ < Tₘ, Tₘ, Tᵢ) +end + end # module diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index 914db440..0f8941e6 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -1,5 +1,9 @@ using .CrossRealmFluxes: compute_atmosphere_ocean_fluxes!, compute_sea_ice_ocean_fluxes! +using ClimaSeaIce: SlabSeaIceModel + +const SlabSeaIceSimulation = Simulation{<:SlabSeaIceModel} + function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean sea_ice = coupled_model.sea_ice @@ -8,7 +12,7 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_ coupled_model.clock.iteration == 0 && update_state!(coupled_model, callbacks) # Eventually, split out into OceanOnlyModel - if !isnothing(sea_ice) + if sea_ice isa SlabSeaIceSimulation h = sea_ice.model.ice_thickness fill_halo_regions!(h) From 89a51a5c22f64c2649f792cc1e40fed077f8f6b3 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 13 Feb 2024 11:00:26 -0700 Subject: [PATCH 145/182] Implement custom backend in JRA55 --- src/DataWrangling/JRA55.jl | 95 +++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 12 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index d90e3c78..4bc37cd1 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -6,7 +6,7 @@ using Oceananigans.Units using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Grids: λnodes, φnodes, on_architecture using Oceananigans.Fields: interpolate! -using Oceananigans.OutputReaders: Cyclical, TotallyInMemory +using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, @@ -14,6 +14,10 @@ using ClimaOcean.OceanSeaIceModels: using NCDatasets using JLD2 +using Dates + +import Oceananigans.Fields: set! +import Oceananigans.OutputReaders: new_backend # A list of all variables provided in the JRA55 dataset: JRA55_variable_names = (:freshwater_river_flux, @@ -165,13 +169,70 @@ function compute_bounding_indices(grid, LX, LY, λc, φc) return i₁, i₂, j₁, j₂, TX end -function jra55_times(Nt, start_time=0) - Δt = 3hours # just what it is +# Convert dates to range until Oceananigans supports dates natively +function jra55_times(native_times, start_time=DateTimeNoLeap(1900, 01, 01)) + Nt = length(native_times) + Δt = native_times[2] - native_times[1] # assume all times are equispaced + Δt = Second(Δt).value + + start_time = native_times[1] - start_time + start_time = Second(start_time).value + stop_time = start_time + Δt * (Nt - 1) times = start_time:Δt:stop_time + return times end +struct JRA55NetCDFBackend <: AbstractInMemoryBackend{Int} + start :: Int + length :: Int +end + +""" + JRA55NetCDFBackend(length) + +Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. +""" +JRA55NetCDFBackend(length) = JRA55NetCDFBackend(1, length) + +Base.length(backend::JRA55NetCDFBackend) = backend.length +Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") + +const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} + +function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) + + ds = Dataset(path) + + # Note that each file should have the variables + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data + + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + LX, LY, LZ = location(fts) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(fts.grid, LX, LY, λc, φc) + + ti = time_indices(fts) + native_times = ds["time"][ti] + times = jra55_times(native_times) + data = ds[name][i₁:i₂, j₁:j₂, ti] + close(ds) + + interior(fts) .= data + fill_halo_regions!(fts) + + return nothing +end + +new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length) + """ JRA55_field_time_series(variable_name; architecture = CPU(), @@ -271,6 +332,7 @@ function JRA55_field_time_series(variable_name; # Record some important user decisions totally_in_memory = backend isa TotallyInMemory on_native_grid = isnothing(grid) + !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") fts_name = field_time_series_short_names[variable_name] @@ -373,7 +435,7 @@ function JRA55_field_time_series(variable_name; TX = Periodic =# - times = ds["time"][time_indices_in_memory] + native_times = ds["time"][time_indices_in_memory] data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] φr = φn[j₁:j₂+1] @@ -393,20 +455,29 @@ function JRA55_field_time_series(variable_name; # Hack together the `times` for the JRA55 dataset we are currently using. # We might want to use the acutal dates instead though. # So the following code might need to change. - times = jra55_times(length(times)) + times = jra55_times(native_times) # Make times into an array for later preprocessing if !totally_in_memory times = collect(times) end - native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - time_indexing, - boundary_conditions) - - # Fill the data in a GPU-friendly manner - copyto!(interior(native_fts, :, :, 1, :), data) - fill_halo_regions!(native_fts) + if backend isa JRA55NetCDFBackend + fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = filename, + name = shortname) + return fts + else + native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + time_indexing, + boundary_conditions) + # Fill the data in a GPU-friendly manner + copyto!(interior(native_fts, :, :, 1, :), data) + fill_halo_regions!(native_fts) + end if on_native_grid fts = native_fts From f1a6a5b79050841182d9a6597796f4cc9997ec66 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 13 Feb 2024 11:00:51 -0700 Subject: [PATCH 146/182] Fix bug in FreezingLimitedTemperature sea ice model --- src/OceanSeaIceModels/OceanSeaIceModels.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 7bc8e851..90629718 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -100,7 +100,7 @@ end end Tₘ = melting_temperature(liquidus, Sᵢ) - Tₒ = ifelse(Tᵢ < Tₘ, Tₘ, Tᵢ) + @inbounds Tₒ[i, j, k] = ifelse(Tᵢ < Tₘ, Tₘ, Tᵢ) end end # module From a9d26da4e3fdfbaa7ce70ddca5a5cb7b4c77ed1d Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 13 Feb 2024 11:01:09 -0700 Subject: [PATCH 147/182] Update regional omip to use new JRA55 backend --- experiments/prototype_omip_simulation/Manifest.toml | 4 ++-- .../regional_omip_simulation.jl | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 833ff084..1babde95 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0-rc1" manifest_format = "2.0" -project_hash = "0892c27a537f93187841c13e787e804f45c1eef4" +project_hash = "0204d58122a575f7f52ca1de92995a3fd07761d1" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -1304,7 +1304,7 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "a086be6e839305355aa0c9cb373fa03d83561ef4" +git-tree-sha1 = "049eaac46129363e968e01388345a8fce8e9badb" repo-rev = "ss-glw/time-bcs" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index 08427e0e..5531694e 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -6,7 +6,7 @@ using Oceananigans.Units: Time using ClimaOcean using ClimaOcean.OceanSeaIceModels: Radiation, FreezingLimitedOceanTemperature -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend using ClimaOcean.DataWrangling.ECCO2: ecco2_field using ClimaSeaIce: LinearLiquidus @@ -19,7 +19,7 @@ start_time = time_ns() include("omip_components.jl") -arch = GPU() +arch = CPU() ##### ##### Construct initial conditions + grid @@ -31,10 +31,11 @@ start_seconds = Second(date - epoch).value Te = ecco2_field(:temperature, date) Se = ecco2_field(:salinity, date) -latitude = (-75, -30) +latitude = (-75, -70) grid, (Tᵢ, Sᵢ) = regional_ecco2_grid(arch, Te, Se; latitude) -atmosphere = JRA55_prescribed_atmosphere(arch, 1:56; backend=InMemory(8)) +backend = JRA55NetCDFBackend(8) # InMemory(8) +atmosphere = JRA55_prescribed_atmosphere(arch, 1:56; backend) radiation = Radiation() #closure = RiBasedVerticalDiffusivity(maximum_diffusivity=1e2, maximum_viscosity=1e2) From 91a777aa514f206115d27e31665016288dd47557 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 13 Feb 2024 22:46:49 -0700 Subject: [PATCH 148/182] Complete JRA55NetCDFBackend --- experiments/prototype_omip_simulation/Manifest.toml | 4 +--- src/DataWrangling/JRA55.jl | 13 +++---------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 1babde95..926d2c18 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1304,9 +1304,7 @@ version = "0.5.5" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "049eaac46129363e968e01388345a8fce8e9badb" -repo-rev = "ss-glw/time-bcs" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +path = "/Users/gregorywagner/Projects/Oceananigans.jl" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.7" diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 4bc37cd1..501956d8 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -6,7 +6,7 @@ using Oceananigans.Units using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Grids: λnodes, φnodes, on_architecture using Oceananigans.Fields: interpolate! -using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS +using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, @@ -220,12 +220,13 @@ function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) i₁, i₂, j₁, j₂, TX = compute_bounding_indices(fts.grid, LX, LY, λc, φc) ti = time_indices(fts) + ti = collect(ti) native_times = ds["time"][ti] times = jra55_times(native_times) data = ds[name][i₁:i₂, j₁:j₂, ti] close(ds) - interior(fts) .= data + copyto!(interior(fts, :, :, 1, :), data) fill_halo_regions!(fts) return nothing @@ -427,14 +428,6 @@ function JRA55_field_time_series(variable_name; # Probably with arguments that take latitude, longitude bounds. i₁, i₂, j₁, j₂, TX = compute_bounding_indices(grid, LX, LY, λc, φc) - #= - Nx = length(λc) - Ny = length(φc) - i₁, i₂ = (1, Nx) - j₁, j₂ = (1, Ny) - TX = Periodic - =# - native_times = ds["time"][time_indices_in_memory] data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] From 4d448458d9ee1000db48d7a7e37d60b0fbc5611d Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Sat, 17 Feb 2024 15:46:26 -0800 Subject: [PATCH 149/182] Fix some bugs --- .../prototype_omip_simulation/Manifest.toml | 6 +- .../prototype_omip_simulation/Project.toml | 1 + .../omip_components.jl | 170 ++++++++++++------ .../plot_freely_decaying_simulation.jl | 40 +++++ .../regional_omip_simulation.jl | 11 +- 5 files changed, 169 insertions(+), 59 deletions(-) create mode 100644 experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml index 926d2c18..a1639eaa 100644 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0-rc1" +julia_version = "1.10.0" manifest_format = "2.0" -project_hash = "0204d58122a575f7f52ca1de92995a3fd07761d1" +project_hash = "2a1113e8d87161459303d19589de1d2641041954" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -1951,7 +1951,7 @@ deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.1+1" diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml index 987de0e0..deaf8c37 100644 --- a/experiments/prototype_omip_simulation/Project.toml +++ b/experiments/prototype_omip_simulation/Project.toml @@ -6,6 +6,7 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl index bd5e7629..c4d6bb87 100644 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -1,85 +1,101 @@ -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: + using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity, MixingLength, TurbulentKineticEnergyEquation -using Oceananigans.Grids: halo_size, topology, φnodes, λnodes -using Oceananigans.Fields: ConstantField, ZeroField +using Oceananigans.Architectures: architecture +using Oceananigans.Grids: halo_size, topology, φnodes, λnodes, znode +using Oceananigans.Fields: ConstantField, ZeroField, interpolate! +using Oceananigans.Utils: launch! using ClimaSeaIce using ClimaSeaIce.HeatBoundaryConditions: IceWaterThermalEquilibrium -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState - -function regional_ecco2_grid(arch, Te, other_fields...; - latitude, - longitude = (0, 360), - halo = (3, 3, 3)) - - start_time = time_ns() - - land = interior(Te) .< -10 - interior(Te)[land] .= NaN +using KernelAbstractions: @kernel, @index - Nf = length(other_fields) +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState - ft = ntuple(Nf) do n - fe = other_fields[n] - interior(fe)[land] .= NaN +#= +Nf = length(other_fields) +ft = ntuple(Nf) do n + fe = other_fields[n] + interior(fe)[land] .= NaN +end +=# + +#= +i₁ = 4 * first(longitude) + 1 +i₂ = 1440 - 4 * (360 - last(longitude)) +i₂ > i₁ || error("longitude $longitude is invalid.") +Nx = i₂ - i₁ + 1 + +j₁ = 4 * (90 + first(latitude)) + 1 +j₂ = 720 - 4 * (90 - last(latitude)) +j₂ > j₁ || error("latitude $latitude is invalid.") +Ny = j₂ - j₁ + 1 +=# +#= +Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) +bottom_height = - Inf .* ones(Nx, Ny) +for i = 1:Nx, j = 1:Ny + for k = Nz:-1:1 + if isnan(Tᵢ[i, j, k]) + bottom_height[i, j] = znode(i, j, k+1, grid, c, c, f) + break + end end +end +Tᵢ = arch_array(arch, Tᵢ) +=# - i₁ = 4 * first(longitude) + 1 - i₂ = 1440 - 4 * (360 - last(longitude)) - i₂ > i₁ || error("longitude $longitude is invalid.") - Nx = i₂ - i₁ + 1 +function regional_omip_grid(arch, ecco_2_temperature_field; + latitude, + longitude = (0, 360), + z = znodes(ecco_2_temperature_field.grid, Face()), + resolution = 1/4, # degree + halo = (7, 7, 7)) - j₁ = 4 * (90 + first(latitude)) + 1 - j₂ = 720 - 4 * (90 - last(latitude)) - j₂ > j₁ || error("latitude $latitude is invalid.") - Ny = j₂ - j₁ + 1 + start_time = time_ns() - zf = znodes(Te.grid, Face()) - Nz = length(zf) - 1 + Te = ecco_2_temperature_field + launch!(architecture(Te), Te.grid, :xyz, nan_land!, Te) + + ΔΛ = last(longitude) - first(longitude) + ΔΦ = last(latitude) - first(latitude) + Nx = Int(ΔΛ / resolution) + Ny = Int(ΔΦ / resolution) - grid = LatitudeLongitudeGrid(arch; latitude, longitude, + Nz = length(z) - 1 + grid = LatitudeLongitudeGrid(arch; latitude, longitude, halo, size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = zf) - - # Construct bottom_height depth by analyzing T - Δz = first(zspacings(Te.grid, Center())) - bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) + z = z) + + Tᵢ = CenterField(grid) + interpolate!(Tᵢ, Te) - Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) - - for i = 1:Nx, j = 1:Ny - for k = Nz:-1:1 - if isnan(Tᵢ[i, j, k]) - bottom_height[i, j] = zf[k+1] - break - end - end - end + bottom_height = Field{Center, Center, Nothing}(grid) + set!(bottom_height, -Inf) + # Construct bottom_height depth by analyzing T + launch!(arch, grid, :xy, infer_bottom_height!, bottom_height, Tᵢ, grid) + grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - Tᵢ = arch_array(arch, Tᵢ) - + #= Nf = length(other_fields) - ft = ntuple(Nf) do n fe = other_fields[n] fᵢ = interior(fe, i₁:i₂, j₁:j₂, :) fᵢ = arch_array(arch, fᵢ) end - all_fields = tuple(Tᵢ, ft...) + =# elapsed = 1e-9 * (time_ns() - start_time) @info string("Grid for regional omip simulation generated in ", prettytime(elapsed), ".") @show grid - return grid, all_fields + return grid, Tᵢ end function omip_ocean_component(grid; @@ -117,8 +133,33 @@ function omip_ocean_component(grid; tracers = tuple(:T, :S, passive_tracers...) if closure == :default - mixing_length = MixingLength(Cᵇ=0.01) - turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + CᵂwΔ = 1.154 + Cᵂu★ = 0.382 + CˡᵒD = 0.378 + CʰⁱD = 0.938 + CᶜD = 1.428 + Cᵂϵ = 1.0 + turbulent_kinetic_energy_equation = + TurbulentKineticEnergyEquation(; Cᵂϵ, CᵂwΔ, Cᵂu★, CˡᵒD, CʰⁱD, CᶜD) + + Cʰⁱc = 0.273 + Cʰⁱu = 0.489 + Cʰⁱe = 1.908 + Cˡᵒc = 0.915 + Cˡᵒu = 0.661 + Cˡᵒe = 1.635 + CRi⁰ = 0.151 + CRiᵟ = 0.113 + Cᶜc = 0.738 + Cᶜe = 0.310 + Cᵉc = 0.392 + Cˢᵖ = 0.517 + Cˢ = 0.746 + Cᵇ = 0.01 + + mixing_length = MixingLength(; Cʰⁱc, Cʰⁱu, Cʰⁱe, Cˢ, Cᵇ, Cˡᵒc, + Cˡᵒu, Cˡᵒe, CRi⁰, CRiᵟ, Cᶜc, Cᶜe, Cᵉc, Cˢᵖ) + closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) tracers = tuple(:e, tracers...) end @@ -194,3 +235,28 @@ function omip_sea_ice_component(ocean_model) return sea_ice end +const c = Center() +const f = Face() + +@kernel function infer_bottom_height!(bottom_height, T, grid) + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + + @inbounds for k = Nz:-1:1 + if isnan(T[i, j, k]) + bottom_height[i, j] = znode(i, j, k+1, grid, c, c, f) + break + end + end +end + +@kernel function nan_land!(T) + i, j, k = @index(Global, NTuple) + + @inbounds begin + Tᵢ = T[i, j, k] + land = Tᵢ < -10 + T[i, j, k] = ifelse(land, NaN, Tᵢ) + end +end diff --git a/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl b/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl new file mode 100644 index 00000000..9238a70f --- /dev/null +++ b/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl @@ -0,0 +1,40 @@ +using GLMakie +using Oceananigans +using JLD2 + +sea_ice_filename = "freely_decaying_regional_simulation_heat_only_sea_ice_thickness.jld2" +fields_filename = "freely_decaying_regional_simulation_heat_only_fields.jld2" + +ht = FieldTimeSeries(sea_ice_filename, "h") +Tt = FieldTimeSeries(fields_filename, "T") +times = ht.times +Nt = length(times) + +for n = 1:Nt + Tn = interior(Tt[n]) + hn = interior(ht[n]) + land = Tn .== 0 + Tn[land] .= NaN + hn[land] .= NaN +end + +fig = Figure(resolution=(1200, 600)) +axT = Axis(fig[1, 1], xlabel="Longitude", ylabel="Latitude") +axh = Axis(fig[2, 1], xlabel="Longitude", ylabel="Latitude") + +n = Observable(1) +Tn = @lift interior(Tt[$n], :, :, 1) +hn = @lift interior(ht[$n], :, :, 1) + +λ, φ, z = nodes(Tt) + +hmT = heatmap!(axT, λ, φ, Tn, nan_color=:lightyellow, colormap=:thermal, colorrange=(-2, 22)) +hmh = heatmap!(axh, λ, φ, hn, nan_color=:lightyellow, colormap=:grays, colorrange=(0, 1)) + +Colorbar(fig[1, 2], hmT, label="Temperature (ᵒC)") +Colorbar(fig[2, 2], hmh, label="Sea ice thickness (m)") + +record(fig, "free_decay_southern_ocean.mp4", 1:Nt, framerate=12) do nn + @info "Plotting frame $nn of $Nt..." + n[] = nn +end diff --git a/experiments/prototype_omip_simulation/regional_omip_simulation.jl b/experiments/prototype_omip_simulation/regional_omip_simulation.jl index 5531694e..bf9bce40 100644 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/regional_omip_simulation.jl @@ -28,11 +28,10 @@ arch = CPU() epoch = Date(1992, 1, 1) date = Date(1992, 1, 2) start_seconds = Second(date - epoch).value -Te = ecco2_field(:temperature, date) -Se = ecco2_field(:salinity, date) +Te = ecco2_field(:temperature, date, architecture=arch) latitude = (-75, -70) -grid, (Tᵢ, Sᵢ) = regional_ecco2_grid(arch, Te, Se; latitude) +grid, Tᵢ = regional_omip_grid(arch, Te; latitude) backend = JRA55NetCDFBackend(8) # InMemory(8) atmosphere = JRA55_prescribed_atmosphere(arch, 1:56; backend) @@ -42,7 +41,11 @@ radiation = Radiation() #closure = RiBasedVerticalDiffusivity() closure = :default ocean = omip_ocean_component(grid; closure) -set!(ocean.model, T=Tᵢ, S=Sᵢ) +@show size(Tᵢ) ocean.model.grid +set!(ocean.model, T=Tᵢ) #, S=Sᵢ) + +Se = ecco2_field(:salinity, date, architecture=arch) +interpolate!(ocean.model.tracers.S, Se) if :e ∈ keys(ocean.model.tracers) set!(ocean.model, e=1e-6) From 86565bce17c0ab744fd3432c5b5bcf23ae3fcaf8 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 26 Feb 2024 10:53:13 -0700 Subject: [PATCH 150/182] New CATKE values? --- .../omip_components.jl | 48 +- .../single_column_omip_simulation.jl | 696 ++++++++---------- src/ClimaOcean.jl | 13 +- src/DataWrangling/ECCO2.jl | 20 +- src/DataWrangling/JRA55.jl | 324 ++++---- 5 files changed, 528 insertions(+), 573 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl index c4d6bb87..fa3f2ea9 100644 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -133,34 +133,44 @@ function omip_ocean_component(grid; tracers = tuple(:T, :S, passive_tracers...) if closure == :default - CᵂwΔ = 1.154 - Cᵂu★ = 0.382 - CˡᵒD = 0.378 - CʰⁱD = 0.938 - CᶜD = 1.428 + + CᵂwΔ = 0.42488 + Cᵂu★ = 0.77035 + CʰⁱD = 1.32927 + CˡᵒD = 1.78434 + CᶜD = 1.77713 Cᵂϵ = 1.0 + turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(; Cᵂϵ, CᵂwΔ, Cᵂu★, CˡᵒD, CʰⁱD, CᶜD) - Cʰⁱc = 0.273 - Cʰⁱu = 0.489 - Cʰⁱe = 1.908 - Cˡᵒc = 0.915 - Cˡᵒu = 0.661 - Cˡᵒe = 1.635 - CRi⁰ = 0.151 - CRiᵟ = 0.113 - Cᶜc = 0.738 - Cᶜe = 0.310 - Cᵉc = 0.392 - Cˢᵖ = 0.517 - Cˢ = 0.746 + Cʰⁱc = 0.35506 + Cʰⁱu = 0.73705 + Cʰⁱe = 2.95645 + Cˢ = 1.51574 + Cˡᵒc = 0.70216 + Cˡᵒu = 0.41751 + Cˡᵒe = 2.12289 + CRi⁰ = 0.31406 + CRiᵟ = 0.31180 + Cᶜc = 1.42944 + Cᶜe = 0.52468 + Cᵉc = 0.84486 + Cˢᵖ = 0.46480 Cᵇ = 0.01 mixing_length = MixingLength(; Cʰⁱc, Cʰⁱu, Cʰⁱe, Cˢ, Cᵇ, Cˡᵒc, Cˡᵒu, Cˡᵒe, CRi⁰, CRiᵟ, Cᶜc, Cᶜe, Cᵉc, Cˢᵖ) - closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) + closure = CATKEVerticalDiffusivity(; mixing_length, + turbulent_kinetic_energy_equation, + maximum_tracer_diffusivity = 1e-1, + maximum_tke_diffusivity = 1e-1, + maximum_viscosity = 1e-1, + negative_turbulent_kinetic_energy_damping_time_scale = 30, + minimum_turbulent_kinetic_energy = 1e-6, + minimum_convective_buoyancy_flux = 1e-11) + tracers = tuple(:e, tracers...) end diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl index 0ddc255f..093b9415 100644 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -4,9 +4,7 @@ using Oceananigans.BuoyancyModels: buoyancy_frequency using Oceananigans.Units: Time using ClimaOcean -using ClimaOcean.OceanSeaIceModels: Radiation -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere -using ClimaOcean.DataWrangling.ECCO2: ecco2_field +using ClimaOcean.DataWrangling.ECCO2: ecco2_column using GLMakie using Printf @@ -15,7 +13,7 @@ using Dates include("omip_components.jl") locations = ( - #eastern_mediterranean = (λ = 30, φ = 32), + eastern_mediterranean = (λ = 30, φ = 32), ocean_station_papa = (λ = 215, φ = 50), north_atlantic = (λ = 325, φ = 50), drake_passage = (λ = 300, φ = -60), @@ -23,384 +21,322 @@ locations = ( tasman_southern_ocean = (λ = 145, φ = -55), ) -#for location in keys(locations) location = :ocean_station_papa - start_time = time_ns() - - epoch = Date(1992, 1, 1) - date = Date(1992, 10, 1) - start_seconds = Second(date - epoch).value - uᵢ = ecco2_field(:u_velocity, date) - vᵢ = ecco2_field(:v_velocity, date) - Tᵢ = ecco2_field(:temperature, date) - Sᵢ = ecco2_field(:salinity, date) - - land = interior(Tᵢ) .< -10 - interior(Tᵢ)[land] .= NaN - interior(Sᵢ)[land] .= NaN - - teos10 = TEOS10EquationOfState() - buoyancy = SeawaterBuoyancy(equation_of_state=teos10) - tracers = (T=Tᵢ, S=Sᵢ) - N²_op = buoyancy_frequency(buoyancy, Tᵢ.grid, tracers) - N² = Field(N²_op) - compute!(N²) - - elapsed = time_ns() - start_time - @info "Initial condition built. " * prettytime(elapsed * 1e-9) - start_time = time_ns() - - ##### - ##### Construct the grid - ##### - - zc = znodes(Tᵢ) - zf = znodes(N²) - - arch = CPU() - - Δ = 1/4 # resolution in degrees - φ₁ = -90 + Δ/2 - φ₂ = +90 - Δ/2 - λ₁ = 0 + Δ/2 - λ₂ = 360 - Δ/2 - φe = φ₁:Δ:φ₂ - λe = λ₁:Δ:λ₂ - - λ★, φ★ = locations[location] - - i★ = searchsortedfirst(λe, λ★) - j★ = searchsortedfirst(φe, φ★) - - longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) - latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) - - # Column - uc = interior(uᵢ, i★:i★, j★:j★, :) - vc = interior(vᵢ, i★:i★, j★:j★, :) - Tc = interior(Tᵢ, i★:i★, j★:j★, :) - Sc = interior(Sᵢ, i★:i★, j★:j★, :) - - # Find bottom - zm = -400 - zf = znodes(Tᵢ.grid, Face()) - kb = findlast(T -> T < -20, Tc[1, 1, :]) - km = findlast(z -> z < zm, zf) - k★ = isnothing(kb) ? km : max(kb + 1, km) - - Nz = size(Tc, 3) - kf = k★:Nz+1 - kc = k★:Nz - zf = zf[kf] - uc = uc[:, :, kc] - vc = vc[:, :, kc] - Tc = Tc[:, :, kc] - Sc = Sc[:, :, kc] - Nz′ = length(kc) - - grid = LatitudeLongitudeGrid(arch; longitude, latitude, - size = (1, 1, Nz′), - z = zf, - topology = (Periodic, Periodic, Bounded)) - - elapsed = time_ns() - start_time - @info "Grid constructed. " * prettytime(elapsed * 1e-9) - start_time = time_ns() - - ocean = omip_ocean_component(grid) - elapsed = time_ns() - start_time - @info "Ocean component built. " * prettytime(elapsed * 1e-9) - start_time = time_ns() - - Ndays = 365 - Nt = 8 * Ndays - atmosphere = JRA55_prescribed_atmosphere(1:2, backend=InMemory()) #, 1:21) - elapsed = time_ns() - start_time - @info "Atmosphere built. " * prettytime(elapsed * 1e-9) - start_time = time_ns() - - # ocean.model.clock.time = start_seconds - ocean.model.clock.iteration = 0 - set!(ocean.model, T=Tc, S=Sc, e=1e-6) - - ua = atmosphere.velocities.u - va = atmosphere.velocities.v - Ta = atmosphere.tracers.T - qa = atmosphere.tracers.q - times = ua.times - - #= - fig = Figure(size=(1200, 1800)) - axu = Axis(fig[1, 1]) - axT = Axis(fig[2, 1]) - axq = Axis(fig[3, 1]) - - lines!(axu, times ./ days, interior(ua, 1, 1, 1, :)) - lines!(axu, times ./ days, interior(va, 1, 1, 1, :)) - lines!(axT, times ./ days, interior(Ta, 1, 1, 1, :)) - lines!(axq, times ./ days, interior(qa, 1, 1, 1, :)) - - display(fig) - =# - - sea_ice = nothing - radiation = Radiation() - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) - - coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 60days) - - elapsed = time_ns() - start_time - @info "Coupled simulation built. " * prettytime(elapsed * 1e-9) - start_time = time_ns() - - wall_clock = Ref(time_ns()) - - function progress(sim) - msg = string("(", location, ")") - msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg *= string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - e = sim.model.ocean.model.tracers.e - - τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) - τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) - u★ = (τˣ^2 + τʸ^2)^(1/4) - Q = first(sim.model.fluxes.total.ocean.heat) - - Nz = size(T, 3) - msg *= @sprintf(", u★: %.2f m s⁻¹", u★) - msg *= @sprintf(", Q: %.2f W m⁻²", Q) - msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) - msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) - msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) - - @info msg - end - - coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) - - # Build flux outputs - Jᵘ = coupled_model.fluxes.total.ocean.momentum.u - Jᵛ = coupled_model.fluxes.total.ocean.momentum.v - Jᵀ = coupled_model.fluxes.total.ocean.tracers.T - Jˢ = coupled_model.fluxes.total.ocean.tracers.S - E = coupled_model.fluxes.turbulent.fields.water_vapor - Qse = coupled_model.fluxes.turbulent.fields.sensible_heat - Qla = coupled_model.fluxes.turbulent.fields.latent_heat - ρₒ = coupled_model.fluxes.ocean_reference_density - cₚ = coupled_model.fluxes.ocean_heat_capacity - - Q = ρₒ * cₚ * Jᵀ - τˣ = ρₒ * Jᵘ - τʸ = ρₒ * Jᵛ - N² = buoyancy_frequency(ocean.model) - κᶜ = ocean.model.diffusivity_fields.κᶜ - - fluxes = (; τˣ, τʸ, E, Jˢ, Q, Qse, Qla) - - auxiliary_fields = (; N², κᶜ) - fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) - - # Slice fields at the surface - outputs = merge(fields, fluxes) - - output_attributes = Dict{String, Any}( - "κᶜ" => Dict("long_name" => "Tracer diffusivity", "units" => "m^2 / s"), - "Q" => Dict("long_name" => "Net heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "Qla" => Dict("long_name" => "Latent heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "Qse" => Dict("long_name" => "Sensible heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "Jˢ" => Dict("long_name" => "Salt flux", "units" => "g kg⁻¹ m s⁻¹", "convention" => "positive upwards"), - "E" => Dict("long_name" => "Freshwater evaporation flux", "units" => "m s⁻¹", "convention" => "positive upwards"), - "e" => Dict("long_name" => "Turbulent kinetic energy", "units" => "m^2 / s^2"), - "τˣ" => Dict("long_name" => "Zonal momentum flux", "units" => "m^2 / s^2"), - "τʸ" => Dict("long_name" => "Meridional momentum flux", "units" => "m^2 / s^2"), - ) - - filename = "single_column_omip_$location" - - coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, - schedule = TimeInterval(3hours), - overwrite_existing = true) - - coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, - schedule = AveragedTimeInterval(1days), - output_attributes, - overwrite_existing = true) - - run!(coupled_simulation) - - #= - filename *= ".jld2" - - ut = FieldTimeSeries(filename, "u") - vt = FieldTimeSeries(filename, "v") - Tt = FieldTimeSeries(filename, "T") - St = FieldTimeSeries(filename, "S") - et = FieldTimeSeries(filename, "e") - N²t = FieldTimeSeries(filename, "N²") - κt = FieldTimeSeries(filename, "κᶜ") - - Qt = FieldTimeSeries(filename, "Q") - Qset = FieldTimeSeries(filename, "Qse") - Qlat = FieldTimeSeries(filename, "Qla") - Jˢt = FieldTimeSeries(filename, "Jˢ") - Et = FieldTimeSeries(filename, "E") - τˣt = FieldTimeSeries(filename, "τˣ") - τʸt = FieldTimeSeries(filename, "τʸ") - - Nz = size(Tt, 3) - times = Qt.times - - ua = atmosphere.velocities.u - va = atmosphere.velocities.v - Ta = atmosphere.tracers.T - qa = atmosphere.tracers.q - Qlw = atmosphere.downwelling_radiation.longwave - Qsw = atmosphere.downwelling_radiation.shortwave - Pr = atmosphere.freshwater_flux.rain - Ps = atmosphere.freshwater_flux.snow - - Nt = length(times) - uat = zeros(Nt) - vat = zeros(Nt) - Tat = zeros(Nt) - qat = zeros(Nt) - Qswt = zeros(Nt) - Qlwt = zeros(Nt) - Pt = zeros(Nt) - - for n = 1:Nt - t = times[n] - uat[n] = ua[1, 1, 1, Time(t)] - vat[n] = va[1, 1, 1, Time(t)] - Tat[n] = Ta[1, 1, 1, Time(t)] - qat[n] = qa[1, 1, 1, Time(t)] - Qswt[n] = Qsw[1, 1, 1, Time(t)] - Qlwt[n] = Qlw[1, 1, 1, Time(t)] - Pt[n] = Pr[1, 1, 1, Time(t)] + Ps[1, 1, 1, Time(t)] - end - - set_theme!(Theme(linewidth=3)) - - fig = Figure(size=(2400, 1800)) - - axτ = Axis(fig[1, 1:2], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") - axu = Axis(fig[2, 1:2], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") - axQ = Axis(fig[1, 3:4], xlabel="Days since Oct 1 1992", ylabel="Heat flux (W m⁻²)") - axT = Axis(fig[2, 3:4], xlabel="Days since Oct 1 1992", ylabel="Surface temperature (ᵒC)") - axF = Axis(fig[1, 5:6], xlabel="Days since Oct 1 1992", ylabel="Freshwater volume flux (m s⁻¹)") - axS = Axis(fig[2, 5:6], xlabel="Days since Oct 1 1992", ylabel="Surface salinity (g kg⁻¹)") - - axuz = Axis(fig[3, 1], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") - axTz = Axis(fig[3, 2], xlabel="Temperature (ᵒC)", ylabel="z (m)") - axSz = Axis(fig[3, 3], xlabel="Salinity (g kg⁻¹)", ylabel="z (m)") - axNz = Axis(fig[3, 4], xlabel="Buoyancy frequency (s⁻²)", ylabel="z (m)") - axκz = Axis(fig[3, 5], xlabel="Eddy diffusivity (m² s⁻¹)", ylabel="z (m)", xscale=log10) - axez = Axis(fig[3, 6], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)", xscale=log10) - - title = @sprintf("Single column simulation at %.2f, %.2f", φ★, λ★) - Label(fig[0, 1:6], title) - - slider = Slider(fig[4, 1:6], range=1:Nt, startvalue=1) - n = slider.value - - times = (times .- times[1]) ./days - tn = @lift times[$n] - - colors = Makie.wong_colors() - - #lines!(axu, times, uat, color=colors[1]) - #lines!(axu, times, vat, color=colors[2]) - - ρₒ = coupled_model.fluxes.ocean_reference_density - Jᵘt = interior(τˣt, 1, 1, 1, :) ./ ρₒ - Jᵛt = interior(τʸt, 1, 1, 1, :) ./ ρₒ - u★ = @. (Jᵘt^2 + Jᵛt^2)^(1/4) - - lines!(axu, times, interior(ut, 1, 1, Nz, :), color=colors[1], label="Zonal") - lines!(axu, times, interior(vt, 1, 1, Nz, :), color=colors[2], label="Meridional") - lines!(axu, times, u★, color=colors[3], label="Ocean-side u★") - vlines!(axu, tn, linewidth=4, color=(:black, 0.5)) - axislegend(axu) - - lines!(axτ, times, interior(τˣt, 1, 1, 1, :), label="Zonal") - lines!(axτ, times, interior(τʸt, 1, 1, 1, :), label="Meridional") - vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) - axislegend(axτ) - - lines!(axT, times, Tat .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") - lines!(axT, times, interior(Tt, 1, 1, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") - vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) - axislegend(axT) - - lines!(axQ, times, interior(Qt, 1, 1, 1, :), color=colors[1], label="Total", linewidth=6) - lines!(axQ, times, interior(Qset, 1, 1, 1, :), color=colors[2], label="Sensible", linewidth=2) - lines!(axQ, times, interior(Qlat, 1, 1, 1, :), color=colors[3], label="Latent", linewidth=2) - lines!(axQ, times, - Qswt, color=colors[4], label="Shortwave", linewidth=2) - lines!(axQ, times, - Qlwt, color=colors[5], label="Longwave", linewidth=2) - vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) - axislegend(axQ) - - #lines!(axF, times, interior(Jˢt, 1, 1, 1, :), label="Net freshwater flux") - lines!(axF, times, Pt, label="Prescribed freshwater flux") - lines!(axF, times, - interior(Et, 1, 1, 1, :), label="Evaporation") - vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) - axislegend(axF) - - lines!(axS, times, interior(St, 1, 1, Nz, :)) - vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) - - zc = znodes(Tt) - zf = znodes(κt) - un = @lift interior(ut[$n], 1, 1, :) - vn = @lift interior(vt[$n], 1, 1, :) - Tn = @lift interior(Tt[$n], 1, 1, :) - Sn = @lift interior(St[$n], 1, 1, :) - κn = @lift interior(κt[$n], 1, 1, :) - en = @lift max.(1e-6, interior(et[$n], 1, 1, :)) - N²n = @lift interior(N²t[$n], 1, 1, :) - - scatterlines!(axuz, un, zc, label="u") - scatterlines!(axuz, vn, zc, label="v") - scatterlines!(axTz, Tn, zc) - scatterlines!(axSz, Sn, zc) - scatterlines!(axez, en, zc) - scatterlines!(axNz, N²n, zf) - scatterlines!(axκz, κn, zf) - - axislegend(axuz) - - Tmax = maximum(interior(Tt)) - Tmin = minimum(interior(Tt)) - xlims!(axTz, Tmin - 0.1, Tmax + 0.1) - - Nmax = maximum(interior(N²t)) - Nmin = minimum(interior(N²t)) - xlims!(axNz, Nmin / 2, Nmin * 1.1) - - emax = maximum(interior(et)) - xlims!(axez, 8e-7, emax * 1.1) - xlims!(axκz, 1e-7, 10) - - Smax = maximum(interior(St)) - Smin = minimum(interior(St)) - xlims!(axSz, Smin - 0.2, Smax + 0.2) - - display(fig) - - record(fig, "$(location)_single_column_simulation.mp4", 1:Nt, framerate=24) do nn - @info "Drawing frame $nn of $Nt..." - n[] = nn +start_time = time_ns() + +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 1) +start_seconds = Second(date - epoch).value +Tᵢ = ecco2_field(:temperature, date) +Sᵢ = ecco2_field(:salinity, date) + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +Nz = 80 +H = 400 +arch = CPU() +λ★, φ★ = locations[location] +i★, j★, longitude, latitude = ecco2_column(λ★, φ★) + +grid = LatitudeLongitudeGrid(arch; longitude, latitude, + size = (1, 1, Nz), + z = (-H, 0), + topology = (Periodic, Periodic, Bounded)) + +ocean = omip_ocean_component(grid) + +backend = JRA55NetCDFBackend(8 * 60) +atmosphere = JRA55_prescribed_atmosphere(:; longitude, latitude, backend) + +ocean.model.clock.time = start_seconds +ocean.model.clock.iteration = 0 +interpolate!(ocean.model.tracers.T, Tᵢ) +interpolate!(ocean.model.tracers.S, Sᵢ) +set!(ocean.model, e=1e-6) + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +times = ua.times + +fig = Figure(size=(1200, 1800)) +axu = Axis(fig[1, 1]) +axT = Axis(fig[2, 1]) +axq = Axis(fig[3, 1]) + +lines!(axu, times ./ days, interior(ua, 1, 1, 1, :)) +lines!(axu, times ./ days, interior(va, 1, 1, 1, :)) +lines!(axT, times ./ days, interior(Ta, 1, 1, 1, :)) +lines!(axq, times ./ days, interior(qa, 1, 1, 1, :)) + +display(fig) + +sea_ice = nothing +radiation = Radiation() +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 30days) + +elapsed = time_ns() - start_time +@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +wall_clock = Ref(time_ns()) + +function progress(sim) + msg = string("(", location, ")") + msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + e = sim.model.ocean.model.tracers.e + + τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) + τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) + u★ = sqrt(sqrt(τˣ^2 + τʸ^2)) + Q = first(sim.model.fluxes.total.ocean.heat) + + Nz = size(T, 3) + msg *= @sprintf(", u★: %.2f m s⁻¹", u★) + msg *= @sprintf(", Q: %.2f W m⁻²", Q) + msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) + msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) + msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) + + @info msg +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) + +# Build flux outputs +Ju = coupled_model.fluxes.total.ocean.momentum.u +Jv = coupled_model.fluxes.total.ocean.momentum.v +JT = coupled_model.fluxes.total.ocean.tracers.T +Js = coupled_model.fluxes.total.ocean.tracers.S +E = coupled_model.fluxes.turbulent.fields.water_vapor +Qc = coupled_model.fluxes.turbulent.fields.sensible_heat +Qv = coupled_model.fluxes.turbulent.fields.latent_heat +ρₒ = coupled_model.fluxes.ocean_reference_density +cₚ = coupled_model.fluxes.ocean_heat_capacity + +Q = ρₒ * cₚ * Jᵀ +τx = ρₒ * Jᵘ +τy = ρₒ * Jᵛ +N² = buoyancy_frequency(ocean.model) +κc = ocean.model.diffusivity_fields.κᶜ + +fluxes = (; τx, τy, E, Js, Q, Qc, Qc) + +auxiliary_fields = (; N², κc) +fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + +# Slice fields at the surface +outputs = merge(fields, fluxes) + +output_attributes = Dict{String, Any}( + "κc" => Dict("long_name" => "Tracer diffusivity", "units" => "m^2 / s"), + "Q" => Dict("long_name" => "Net heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Qv" => Dict("long_name" => "Latent heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Qc" => Dict("long_name" => "Sensible heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Js" => Dict("long_name" => "Salt flux", "units" => "g kg⁻¹ m s⁻¹", "convention" => "positive upwards"), + "E" => Dict("long_name" => "Freshwater evaporation flux", "units" => "m s⁻¹", "convention" => "positive upwards"), + "e" => Dict("long_name" => "Turbulent kinetic energy", "units" => "m^2 / s^2"), + "τx" => Dict("long_name" => "Zonal momentum flux", "units" => "m^2 / s^2"), + "τx" => Dict("long_name" => "Meridional momentum flux", "units" => "m^2 / s^2"), +) + +filename = "single_column_omip_$location" + +coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, + schedule = TimeInterval(3hours), + overwrite_existing = true) + +#= +coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, + schedule = AveragedTimeInterval(1days), + output_attributes, + overwrite_existing = true) +=# + +run!(coupled_simulation) + +#= +filename *= ".jld2" + +ut = FieldTimeSeries(filename, "u") +vt = FieldTimeSeries(filename, "v") +Tt = FieldTimeSeries(filename, "T") +St = FieldTimeSeries(filename, "S") +et = FieldTimeSeries(filename, "e") +N²t = FieldTimeSeries(filename, "N²") +κt = FieldTimeSeries(filename, "κᶜ") + +Qt = FieldTimeSeries(filename, "Q") +Qset = FieldTimeSeries(filename, "Qse") +Qlat = FieldTimeSeries(filename, "Qla") +Jˢt = FieldTimeSeries(filename, "Jˢ") +Et = FieldTimeSeries(filename, "E") +τˣt = FieldTimeSeries(filename, "τˣ") +τʸt = FieldTimeSeries(filename, "τʸ") + +Nz = size(Tt, 3) +times = Qt.times + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +Qlw = atmosphere.downwelling_radiation.longwave +Qsw = atmosphere.downwelling_radiation.shortwave +Pr = atmosphere.freshwater_flux.rain +Ps = atmosphere.freshwater_flux.snow + +Nt = length(times) +uat = zeros(Nt) +vat = zeros(Nt) +Tat = zeros(Nt) +qat = zeros(Nt) +Qswt = zeros(Nt) +Qlwt = zeros(Nt) +Pt = zeros(Nt) + +for n = 1:Nt + t = times[n] + uat[n] = ua[1, 1, 1, Time(t)] + vat[n] = va[1, 1, 1, Time(t)] + Tat[n] = Ta[1, 1, 1, Time(t)] + qat[n] = qa[1, 1, 1, Time(t)] + Qswt[n] = Qsw[1, 1, 1, Time(t)] + Qlwt[n] = Qlw[1, 1, 1, Time(t)] + Pt[n] = Pr[1, 1, 1, Time(t)] + Ps[1, 1, 1, Time(t)] +end + +set_theme!(Theme(linewidth=3)) + +fig = Figure(size=(2400, 1800)) + +axτ = Axis(fig[1, 1:2], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") +axu = Axis(fig[2, 1:2], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") +axQ = Axis(fig[1, 3:4], xlabel="Days since Oct 1 1992", ylabel="Heat flux (W m⁻²)") +axT = Axis(fig[2, 3:4], xlabel="Days since Oct 1 1992", ylabel="Surface temperature (ᵒC)") +axF = Axis(fig[1, 5:6], xlabel="Days since Oct 1 1992", ylabel="Freshwater volume flux (m s⁻¹)") +axS = Axis(fig[2, 5:6], xlabel="Days since Oct 1 1992", ylabel="Surface salinity (g kg⁻¹)") + +axuz = Axis(fig[3, 1], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") +axTz = Axis(fig[3, 2], xlabel="Temperature (ᵒC)", ylabel="z (m)") +axSz = Axis(fig[3, 3], xlabel="Salinity (g kg⁻¹)", ylabel="z (m)") +axNz = Axis(fig[3, 4], xlabel="Buoyancy frequency (s⁻²)", ylabel="z (m)") +axκz = Axis(fig[3, 5], xlabel="Eddy diffusivity (m² s⁻¹)", ylabel="z (m)", xscale=log10) +axez = Axis(fig[3, 6], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)", xscale=log10) + +title = @sprintf("Single column simulation at %.2f, %.2f", φ★, λ★) +Label(fig[0, 1:6], title) + +slider = Slider(fig[4, 1:6], range=1:Nt, startvalue=1) +n = slider.value + +times = (times .- times[1]) ./days +tn = @lift times[$n] + +colors = Makie.wong_colors() + +#lines!(axu, times, uat, color=colors[1]) +#lines!(axu, times, vat, color=colors[2]) + +ρₒ = coupled_model.fluxes.ocean_reference_density +Jᵘt = interior(τˣt, 1, 1, 1, :) ./ ρₒ +Jᵛt = interior(τʸt, 1, 1, 1, :) ./ ρₒ +u★ = @. (Jᵘt^2 + Jᵛt^2)^(1/4) + +lines!(axu, times, interior(ut, 1, 1, Nz, :), color=colors[1], label="Zonal") +lines!(axu, times, interior(vt, 1, 1, Nz, :), color=colors[2], label="Meridional") +lines!(axu, times, u★, color=colors[3], label="Ocean-side u★") +vlines!(axu, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axu) + +lines!(axτ, times, interior(τˣt, 1, 1, 1, :), label="Zonal") +lines!(axτ, times, interior(τʸt, 1, 1, 1, :), label="Meridional") +vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axτ) + +lines!(axT, times, Tat .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") +lines!(axT, times, interior(Tt, 1, 1, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") +vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axT) + +lines!(axQ, times, interior(Qt, 1, 1, 1, :), color=colors[1], label="Total", linewidth=6) +lines!(axQ, times, interior(Qset, 1, 1, 1, :), color=colors[2], label="Sensible", linewidth=2) +lines!(axQ, times, interior(Qlat, 1, 1, 1, :), color=colors[3], label="Latent", linewidth=2) +lines!(axQ, times, - Qswt, color=colors[4], label="Shortwave", linewidth=2) +lines!(axQ, times, - Qlwt, color=colors[5], label="Longwave", linewidth=2) +vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axQ) + +#lines!(axF, times, interior(Jˢt, 1, 1, 1, :), label="Net freshwater flux") +lines!(axF, times, Pt, label="Prescribed freshwater flux") +lines!(axF, times, - interior(Et, 1, 1, 1, :), label="Evaporation") +vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axF) + +lines!(axS, times, interior(St, 1, 1, Nz, :)) +vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) + +zc = znodes(Tt) +zf = znodes(κt) +un = @lift interior(ut[$n], 1, 1, :) +vn = @lift interior(vt[$n], 1, 1, :) +Tn = @lift interior(Tt[$n], 1, 1, :) +Sn = @lift interior(St[$n], 1, 1, :) +κn = @lift interior(κt[$n], 1, 1, :) +en = @lift max.(1e-6, interior(et[$n], 1, 1, :)) +N²n = @lift interior(N²t[$n], 1, 1, :) + +scatterlines!(axuz, un, zc, label="u") +scatterlines!(axuz, vn, zc, label="v") +scatterlines!(axTz, Tn, zc) +scatterlines!(axSz, Sn, zc) +scatterlines!(axez, en, zc) +scatterlines!(axNz, N²n, zf) +scatterlines!(axκz, κn, zf) + +axislegend(axuz) + +Tmax = maximum(interior(Tt)) +Tmin = minimum(interior(Tt)) +xlims!(axTz, Tmin - 0.1, Tmax + 0.1) + +Nmax = maximum(interior(N²t)) +Nmin = minimum(interior(N²t)) +xlims!(axNz, Nmin / 2, Nmin * 1.1) + +emax = maximum(interior(et)) +xlims!(axez, 8e-7, emax * 1.1) +xlims!(axκz, 1e-7, 10) + +Smax = maximum(interior(St)) +Smin = minimum(interior(St)) +xlims!(axSz, Smin - 0.2, Smax + 0.2) + +display(fig) + +record(fig, "$(location)_single_column_simulation.mp4", 1:Nt, framerate=24) do nn + @info "Drawing frame $nn of $Nt..." + n[] = nn # end end =# diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index e7191d97..3374406c 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -1,6 +1,12 @@ module ClimaOcean -export OceanSeaIceModel, FreezingLimitedOceanTemperature +export + OceanSeaIceModel, + FreezingLimitedOceanTemperature, + Radiation, + JRA55_prescribed_atmosphere, + JRA55NetCDFBackend, + ecco2_field using Oceananigans using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ @@ -69,7 +75,10 @@ include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") using .DataWrangling: JRA55, ECCO2 -using .OceanSeaIceModels: OceanSeaIceModel +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +using .OceanSeaIceModels: OceanSeaIceModel, Radiation end # module diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 590a5a0d..baf70f2a 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -128,8 +128,6 @@ shortnames = Dict( :v_velocity => "VVEL", ) - - surface_variable(variable_name) = variable_name == :sea_ice_thickness function ecco2_field(variable_name, date=Date(1992, 01, 02); @@ -196,5 +194,23 @@ function ecco2_bottom_height_from_temperature() return bottom_height end +function ecco2_column(λ★, φ★) + Δ = 1/4 # resolution in degrees + φ₁ = -90 + Δ/2 + φ₂ = +90 - Δ/2 + λ₁ = 0 + Δ/2 + λ₂ = 360 - Δ/2 + φe = φ₁:Δ:φ₂ + λe = λ₁:Δ:λ₂ + + i★ = searchsortedfirst(λe, λ★) + j★ = searchsortedfirst(φe, φ★) + + longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) + latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) + + return i★, j★, longitude, latitude +end + end # module diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 501956d8..1dfc3f77 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -119,52 +119,62 @@ urls = Dict( "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", ) -function compute_bounding_indices(grid, LX, LY, λc, φc) - - Nx = length(λc) - Ny = length(φc) - - if isnothing(grid) - i₁, i₂ = (1, Nx) - j₁, j₂ = (1, Ny) - TX = Periodic - else # only load the data we need - # Nodes where we need to find data - λg = λnodes(grid, LX()) - φg = φnodes(grid, LY()) - - λ₁, λ₂ = extrema(λg) - φ₁, φ₂ = extrema(φg) - - # The following should work. If ᵒ are the extrema of nodes we want to - # interpolate to, and the following is a sketch of the JRA55 native grid, - # - # 1 2 3 4 5 - # | | | | | | - # | x ᵒ | x | x | x ᵒ | x | - # | | | | | | - # 1 2 3 4 5 6 - # - # then for example, we should find that (iᵢ, i₂) = (1, 5). - # So we want to reduce the first index by one, and limit them - # both by the available data. There could be some mismatch due - # to the use of different coordinate systems (ie whether λ ∈ (0, 360) - # which we may also need to handle separately. - - i₁ = searchsortedfirst(λc, λ₁) - j₁ = searchsortedfirst(φc, φ₁) - - i₂ = searchsortedfirst(λc, λ₂) - j₂ = searchsortedfirst(φc, φ₂) - - i₁ = max(1, i₁ - 1) - j₁ = max(1, j₁ - 1) - - i₂ = min(Nx, i₂) - j₂ = min(Ny, j₂) - - TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded - end +compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing +compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds + +function compute_bounding_nodes(::Nothing, grid, LH, hnodes) + hg = hnodes(grid, LH()) + h₁, h₂ = extrema(hg) + return h₁, h₂ +end + +function compute_bounding_indices(::Nothing, hc) + Nh = length(hc) + return 1, Nh +end + +function compute_bounding_indices(bounds, hc) + h₁, h₂ = bounds + Nh = length(hc) + + # The following should work. If ᵒ are the extrema of nodes we want to + # interpolate to, and the following is a sketch of the JRA55 native grid, + # + # 1 2 3 4 5 + # | | | | | | + # | x ᵒ | x | x | x ᵒ | x | + # | | | | | | + # 1 2 3 4 5 6 + # + # then for example, we should find that (iᵢ, i₂) = (1, 5). + # So we want to reduce the first index by one, and limit them + # both by the available data. There could be some mismatch due + # to the use of different coordinate systems (ie whether λ ∈ (0, 360) + # which we may also need to handle separately. + i₁ = searchsortedfirst(hc, h₁) + i₂ = searchsortedfirst(hc, h₂) + i₁ = max(1, i₁ - 1) + i₂ = min(Nh, i₂) + + return i₁, i₂ +end + +infer_longitudinal_topology(::Nothing) = Periodic + +function infer_longitudinal_topology(λbounds) + λ₁, λ₂ = λbounds + TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded + return TX +end + + +function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + λbounds = compute_bounding_nodes(longitude, grid, LX, λnodes) + φbounds = compute_bounding_nodes(latitude, grid, LY, φnodes) + + i₁, i₂ = compute_bounding_indices(λbounds, λc) + j₁, j₂ = compute_bounding_indices(φbounds, φc) + TX = infer_longitudinal_topology(λbounds) return i₁, i₂, j₁, j₂, TX end @@ -217,7 +227,7 @@ function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) λc = ds["lon"][:] φc = ds["lat"][:] LX, LY, LZ = location(fts) - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(fts.grid, LX, LY, λc, φc) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) ti = time_indices(fts) ti = collect(ti) @@ -303,6 +313,8 @@ function JRA55_field_time_series(variable_name; url = nothing, filename = nothing, shortname = nothing, + latitude = nothing, + longitude = nothing, backend = InMemory(), time_indexing = Cyclical(), preprocess_chunk_size = 10, @@ -338,60 +350,36 @@ function JRA55_field_time_series(variable_name; jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") fts_name = field_time_series_short_names[variable_name] - # TODO: figure out how to use existing jld2 files - # Eg we have to check correctness, etc + # Note, we don't re-use existing jld2 files. isfile(filename) || download(url, filename) isfile(jld2_filename) && rm(jld2_filename) - #= - # Decision tree: - # 1. jld2 file exists? - # - yes -> load and return FieldTimeSeries - # check time_indices and all that? - # - no -> download .nc data if not available - if isfile(jld2_filename) - isnothing(time_indices) && (time_indices = Colon()) - - # Infer the `times` before loading data - temporary_fts = FieldTimeSeries(jld2_filename, fts_name; backend=OnDisk()) - - #try - times = temporary_fts.times[time_indices] - fts = FieldTimeSeries(jld2_filename, fts_name; backend, architecture, times) - return fts - #catch - # if !totally_in_memory # will need to overwrite - # msg = string("Cannot use backend=$backend with time_indices=$time_indices", '\n', - # " and the existing $jld2_filename, which does not", '\n', - # " have enough `times`. Delete $jld2_filename in order", '\n', - # " to re-generate it.") - # error(msg) - # end - #end - end - =# - + # Determine default time indices if totally_in_memory # In this case, the whole time series is in memory. # Either the time series is short, or we are doing a limited-area - # simulation, like in a single column. In this case we conservatively - # set a default time_indices = 1:1. + # simulation, like in a single column. So, we conservatively + # set a default `time_indices = 1:1`. isnothing(time_indices) && (time_indices = 1:1) time_indices_in_memory = time_indices native_fts_architecture = architecture else # In this case, part or all of the time series will be stored in a file. - # If we've gotten this far, it means that a suitable existing .jld2 file - # was not found and we need to preprocess data from the native .nc files. - # Now, time_indices refers to the time_indices that we will preprocess; + # Note: if the user has provided a grid, we will have to preprocess the + # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers + # to the time_indices that we will preprocess; # by default we choose all of them. The architecture is only the # architecture used for preprocessing, which typically will be CPU() # even if we would like the final FieldTimeSeries on the GPU. - # Finally, `time_indices_in_memory` only refers to preprocessing, - # and we determine it using the kwarg `preprocess_chunk_size`. isnothing(time_indices) && (time_indices = :) - time_indices_in_memory = 1:preprocess_chunk_size - native_fts_architecture = preprocess_architecture + + if backend isa JRA55NetCDFBackend + time_indices_in_memory = 1:length(backend) + native_fts_architecture = architecture + else # then `time_indices_in_memory` refers to preprocessing + time_indices_in_memory = 1:preprocess_chunk_size + native_fts_architecture = preprocess_architecture + end end # Set a default location. @@ -426,7 +414,7 @@ function JRA55_field_time_series(variable_name; # TODO: support loading just part of the JRA55 data. # Probably with arguments that take latitude, longitude bounds. - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(grid, LX, LY, λc, φc) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) native_times = ds["time"][time_indices_in_memory] data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] @@ -443,18 +431,8 @@ function JRA55_field_time_series(variable_name; topology = (TX, Bounded, Flat)) boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) - - # TODO: fix this and use dates? - # Hack together the `times` for the JRA55 dataset we are currently using. - # We might want to use the acutal dates instead though. - # So the following code might need to change. times = jra55_times(native_times) - - # Make times into an array for later preprocessing - if !totally_in_memory - times = collect(times) - end - + if backend isa JRA55NetCDFBackend fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; backend, @@ -462,95 +440,102 @@ function JRA55_field_time_series(variable_name; boundary_conditions, path = filename, name = shortname) + + # Fill the data in a GPU-friendly manner + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) + return fts else + # Make times into an array for later preprocessing + if !totally_in_memory + times = collect(times) + end + native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; time_indexing, boundary_conditions) + # Fill the data in a GPU-friendly manner copyto!(interior(native_fts, :, :, 1, :), data) fill_halo_regions!(native_fts) - end - if on_native_grid - fts = native_fts - else # make a new FieldTimeSeries and interpolate native data onto it. - boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) - fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) - interpolate!(fts, native_fts) + if on_native_grid && totally_in_memory + return native_fts + + elseif totally_in_memory # but not on the native grid! + boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) + fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) + interpolate!(fts, native_fts) + return fts + end end - if totally_in_memory - return fts - else # we're gonna save to disk! - # TODO: something's wrong here - @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." + @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(fts.grid; - # time_indexing, - boundary_conditions, - backend = OnDisk(), - path = jld2_filename, - name = fts_name) - - # Re-open the dataset! - ds = Dataset(filename) - all_datetimes = ds["time"][time_indices] - all_Nt = length(all_datetimes) - chunk = last(preprocess_chunk_size) - all_times = jra55_times(all_Nt) - - # Save data to disk, one field at a time - start_clock = time_ns() - n = 1 # on disk - m = 0 # in memory - while n <= all_Nt - print(" ... processing time index $n of $all_Nt \r") - - if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory - m += 1 - else # load new data - # Update time_indices - time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size - n₁ = first(time_indices_in_memory) - - # Clip time_indices if they extend past the end of the dataset - if last(time_indices_in_memory) > all_Nt - time_indices_in_memory = UnitRange(n₁, all_Nt) - end - - # Re-compute times - Nt = length(time_indices_in_memory) - new_times = jra55_times(Nt, all_times[n₁]) - native_fts.times = new_times - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - - if !on_native_grid - fts.times = new_times - interpolate!(fts, native_fts) - end - - m = 1 # reset + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(fts.grid; + boundary_conditions, + backend = OnDisk(), + path = jld2_filename, + name = fts_name) + + # Re-open the dataset! + ds = Dataset(filename) + all_datetimes = ds["time"][time_indices] + all_Nt = length(all_datetimes) + chunk = last(preprocess_chunk_size) + all_times = jra55_times(all_Nt) + + # Save data to disk, one field at a time + start_clock = time_ns() + n = 1 # on disk + m = 0 # in memory + while n <= all_Nt + print(" ... processing time index $n of $all_Nt \r") + + if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory + m += 1 + else # load new data + # Update time_indices + time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size + n₁ = first(time_indices_in_memory) + + # Clip time_indices if they extend past the end of the dataset + if last(time_indices_in_memory) > all_Nt + time_indices_in_memory = UnitRange(n₁, all_Nt) end - set!(on_disk_fts, fts[m], n, all_times[n]) + # Re-compute times + Nt = length(time_indices_in_memory) + new_times = jra55_times(Nt, all_times[n₁]) + native_fts.times = new_times - n += 1 - end + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) - elapsed = 1e-9 * (time_ns() - start_clock) - elapsed_str = prettytime(elapsed) - @info " ... done ($elapsed_str)" * repeat(" ", 20) + if !on_native_grid + fts.times = new_times + interpolate!(fts, native_fts) + end + + m = 1 # reset + end - close(ds) + set!(on_disk_fts, fts[m], n, all_times[n]) - user_fts = FieldTimeSeries(jld2_filename, fts_name; architecture, backend, time_indexing) - return user_fts + n += 1 end + + elapsed = 1e-9 * (time_ns() - start_clock) + elapsed_str = prettytime(elapsed) + @info " ... done ($elapsed_str)" * repeat(" ", 20) + + close(ds) + + user_fts = FieldTimeSeries(jld2_filename, fts_name; architecture, backend, time_indexing) + return user_fts end const AA = Oceananigans.Architectures.AbstractArchitecture @@ -574,8 +559,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); # Manufacture a default for the number of fields to keep InMemory Nf = min(24, Ni) - - backend = InMemory(Nf) + backend = JRA55NetCDFBackend(Nf) end kw = (; time_indices, time_indexing, backend, architecture) From cb0386bd0d787a9113065ae8bfac23fd1a356cd9 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 28 Feb 2024 07:07:30 -0700 Subject: [PATCH 151/182] Remove cruft --- .../CATKE_column_simulations/Manifest.toml | 1696 ------------ .../CATKE_column_simulations/Project.toml | 3 - .../CATKE_column_simulations/take_a_look.jl | 14 - .../omip_sea_ice_component.jl | 0 .../omip_simulation.jl | 311 --- .../surface_fluxes.jl | 209 -- .../test_field_time_series.jl | 37 - .../test_single_column_omip_simulation.jl | 166 -- .../updated_Manifest.toml | 2290 ----------------- 9 files changed, 4726 deletions(-) delete mode 100644 experiments/prototype_omip_simulation/CATKE_column_simulations/Manifest.toml delete mode 100644 experiments/prototype_omip_simulation/CATKE_column_simulations/Project.toml delete mode 100644 experiments/prototype_omip_simulation/CATKE_column_simulations/take_a_look.jl delete mode 100644 experiments/prototype_omip_simulation/omip_sea_ice_component.jl delete mode 100644 experiments/prototype_omip_simulation/omip_simulation.jl delete mode 100644 experiments/prototype_omip_simulation/surface_fluxes.jl delete mode 100644 experiments/prototype_omip_simulation/test_field_time_series.jl delete mode 100644 experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl delete mode 100644 experiments/prototype_omip_simulation/updated_Manifest.toml diff --git a/experiments/prototype_omip_simulation/CATKE_column_simulations/Manifest.toml b/experiments/prototype_omip_simulation/CATKE_column_simulations/Manifest.toml deleted file mode 100644 index f8d4c94f..00000000 --- a/experiments/prototype_omip_simulation/CATKE_column_simulations/Manifest.toml +++ /dev/null @@ -1,1696 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.0-beta3" -manifest_format = "2.0" -project_hash = "0729067587159d7fc93e6bd472f23cbb03ba5b95" - -[[deps.AbstractFFTs]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.5.0" -weakdeps = ["ChainRulesCore", "Test"] - - [deps.AbstractFFTs.extensions] - AbstractFFTsChainRulesCoreExt = "ChainRulesCore" - AbstractFFTsTestExt = "Test" - -[[deps.AbstractLattices]] -git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" -uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" -version = "0.3.0" - -[[deps.AbstractTrees]] -git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" -uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" -version = "0.4.4" - -[[deps.Adapt]] -deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.7.2" -weakdeps = ["StaticArrays"] - - [deps.Adapt.extensions] - AdaptStaticArraysExt = "StaticArrays" - -[[deps.Animations]] -deps = ["Colors"] -git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" -uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" -version = "0.4.1" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "bbec08a37f8722786d87bedf84eae19c020c4efa" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.7.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - 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" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" - -[[deps.Automa]] -deps = ["PrecompileTools", "TranscodingStreams"] -git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" -uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "1.0.3" - -[[deps.AxisAlgorithms]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] -git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "1.1.0" - -[[deps.AxisArrays]] -deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] -git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" -uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.4.7" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[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 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" -uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.1.2" - -[[deps.CRC32c]] -uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" - -[[deps.CRlibm]] -deps = ["CRlibm_jll"] -git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" -uuid = "96374032-68de-5a5b-8d9e-752f78720389" -version = "1.0.1" - -[[deps.CRlibm_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" -uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" -version = "1.0.1+0" - -[[deps.Cairo_jll]] -deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" -uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.16.1+1" - -[[deps.Calculus]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.5.1" - -[[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "c1deebd76f7a443d527fc0430d5758b8b2112ed8" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.19.1" -weakdeps = ["SparseArrays"] - - [deps.ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[deps.ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - -[[deps.ColorSchemes]] -deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" -uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.24.0" - -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.4" - -[[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.10.0" -weakdeps = ["SpecialFunctions"] - - [deps.ColorVectorSpace.extensions] - SpecialFunctionsExt = "SpecialFunctions" - -[[deps.Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.10" - -[[deps.Combinatorics]] -git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "1.0.2" - -[[deps.CommonDataModel]] -deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "349d9b36250ec19a7da18f838434db7d76c2f131" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.2" - -[[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 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.12.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.5+1" - -[[deps.ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.4" -weakdeps = ["IntervalSets", "StaticArrays"] - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseStaticArraysExt = "StaticArrays" - -[[deps.Contour]] -git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.6.2" - -[[deps.DataAPI]] -git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.15.0" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "ac67408d9ddf207de5cfa9a97e114352430f01ed" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.16" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.DelaunayTriangulation]] -deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] -git-tree-sha1 = "26eb8e2331b55735c3d305d949aabd7363f07ba7" -uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "0.8.11" - -[[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 = ["OffsetArrays"] -git-tree-sha1 = "1bfa9de80f35ac63c6c381b2d43c590875896a1f" -uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.3.22" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[deps.Distributions]] -deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.107" - - [deps.Distributions.extensions] - DistributionsChainRulesCoreExt = "ChainRulesCore" - DistributionsDensityInterfaceExt = "DensityInterface" - DistributionsTestExt = "Test" - - [deps.Distributions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.DocStringExtensions]] -deps = ["LibGit2"] -git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.3" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.DualNumbers]] -deps = ["Calculus", "NaNMath", "SpecialFunctions"] -git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" -uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" -version = "0.6.8" - -[[deps.EarCut_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" -uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" -version = "2.2.4+0" - -[[deps.EnumX]] -git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" -uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" -version = "1.0.4" - -[[deps.ExactPredicates]] -deps = ["IntervalArithmetic", "Random", "StaticArrays"] -git-tree-sha1 = "e8b8c949551f417e040f16e5c431b6e83e306e54" -uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" -version = "2.2.7" - -[[deps.Expat_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" -uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.5.0+0" - -[[deps.Extents]] -git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" -uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.2" - -[[deps.FFMPEG_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" -uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "4.4.4+1" - -[[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "ec22cbbcd01cba8f41eecd7d44aac1f23ee985e3" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.7.2" - -[[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 = "c5c28c245101bd59154f649e19b038d15901b5dc" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.2" - -[[deps.FilePaths]] -deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] -git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" -uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" -version = "0.8.3" - -[[deps.FilePathsBase]] -deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] -git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" -uuid = "48062228-2e41-5def-b9a4-89aafe57970f" -version = "0.9.21" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[deps.FillArrays]] -deps = ["LinearAlgebra", "Random"] -git-tree-sha1 = "5b93957f6dcd33fc343044af3d48c215be2562f1" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.9.3" -weakdeps = ["PDMats", "SparseArrays", "Statistics"] - - [deps.FillArrays.extensions] - FillArraysPDMatsExt = "PDMats" - FillArraysSparseArraysExt = "SparseArrays" - FillArraysStatisticsExt = "Statistics" - -[[deps.FiniteDiff]] -deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "73d1214fec245096717847c62d389a5d2ac86504" -uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.22.0" - - [deps.FiniteDiff.extensions] - FiniteDiffBandedMatricesExt = "BandedMatrices" - FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" - FiniteDiffStaticArraysExt = "StaticArrays" - - [deps.FiniteDiff.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" - -[[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" -uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.93+0" - -[[deps.Formatting]] -deps = ["Printf"] -git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8" -uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" -version = "0.4.2" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.36" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.FreeType]] -deps = ["CEnum", "FreeType2_jll"] -git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "4.1.1" - -[[deps.FreeType2_jll]] -deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" -uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.1+0" - -[[deps.FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] -git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.1" - -[[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" -uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.10+0" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[deps.GLFW]] -deps = ["GLFW_jll"] -git-tree-sha1 = "35dbc482f0967d8dceaa7ce007d16f9064072166" -uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -version = "3.4.1" - -[[deps.GLFW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] -git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" -uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" -version = "3.3.9+0" - -[[deps.GLMakie]] -deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "e53267e2fc64f81b939849ca7bd70d8f879b5293" -uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.9.5" - -[[deps.GPUArraysCore]] -deps = ["Adapt"] -git-tree-sha1 = "2d6ca471a6c7b536127afccfa7564b5b39227fe0" -uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.1.5" - -[[deps.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.3" - -[[deps.GeometryBasics]] -deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "424a5a6ce7c5d97cca7bcc4eac551b97294c54af" -uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.4.9" - -[[deps.Gettext_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] -git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" -uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" -version = "0.21.0+0" - -[[deps.Glib_jll]] -deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "e94c92c7bf4819685eb80186d51c43e71d4afa17" -uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.76.5+0" - -[[deps.Graphite2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" -uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" -version = "1.3.14+0" - -[[deps.GridLayoutBase]] -deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "af13a277efd8a6e716d79ef635d5342ccb75be61" -uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.10.0" - -[[deps.Grisu]] -git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" -uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" -version = "1.0.2" - -[[deps.HDF5_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] -git-tree-sha1 = "8156325170d6763b5494c072ac4754214db3e669" -uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" -version = "1.14.3+0" - -[[deps.HarfBuzz_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] -git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" -uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" -version = "2.8.1+1" - -[[deps.HypergeometricFunctions]] -deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" -uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.23" - -[[deps.ImageAxes]] -deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] -git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" -uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -version = "0.6.11" - -[[deps.ImageBase]] -deps = ["ImageCore", "Reexport"] -git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" -uuid = "c817782e-172a-44cc-b673-b171935fbb9e" -version = "0.1.7" - -[[deps.ImageCore]] -deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] -git-tree-sha1 = "fc5d1d3443a124fde6e92d0260cd9e064eba69f8" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.10.1" - -[[deps.ImageIO]] -deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] -git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" -uuid = "82e4d734-157c-48bb-816b-45c225c6df19" -version = "0.6.7" - -[[deps.ImageMetadata]] -deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] -git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" -uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" -version = "0.9.9" - -[[deps.Imath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" -uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" -version = "3.1.7+0" - -[[deps.IndirectArrays]] -git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" -uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" -version = "1.0.0" - -[[deps.Inflate]] -git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.4" - -[[deps.IntegerMathUtils]] -git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" -uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" -version = "0.1.2" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.0.2+0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[deps.Interpolations]] -deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.15.1" - - [deps.Interpolations.extensions] - InterpolationsUnitfulExt = "Unitful" - - [deps.Interpolations.weakdeps] - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - -[[deps.IntervalArithmetic]] -deps = ["CRlibm", "RoundingEmulator"] -git-tree-sha1 = "c274ec586ea58eb7b42afd0c5d67e50ff50229b5" -uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.5" -weakdeps = ["DiffRules", "RecipesBase"] - - [deps.IntervalArithmetic.extensions] - IntervalArithmeticDiffRulesExt = "DiffRules" - IntervalArithmeticRecipesBaseExt = "RecipesBase" - -[[deps.IntervalSets]] -deps = ["Dates", "Random"] -git-tree-sha1 = "3d8866c029dd6b16e69e0d4a939c4dfcb98fac47" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.8" -weakdeps = ["Statistics"] - - [deps.IntervalSets.extensions] - IntervalSetsStatisticsExt = "Statistics" - -[[deps.IrrationalConstants]] -git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.2" - -[[deps.Isoband]] -deps = ["isoband_jll"] -git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" -uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" -version = "0.1.1" - -[[deps.IterTools]] -git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.10.0" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[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.JpegTurbo]] -deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] -git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" -uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" -version = "0.1.5" - -[[deps.JpegTurbo_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "60b1194df0a3298f460063de985eae7b01bc011a" -uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.0.1+0" - -[[deps.KernelDensity]] -deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.8" - -[[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" -uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.1+0" - -[[deps.LLVMOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" -uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "15.0.7+0" - -[[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" -uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.1+0" - -[[deps.LaTeXStrings]] -git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" -uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.3.1" - -[[deps.LazyArtifacts]] -deps = ["Artifacts", "Pkg"] -uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" - -[[deps.LazyModules]] -git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" -uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" -version = "0.3.1" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.0.1+1" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.6.4+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[deps.Libffi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" -uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" -version = "3.2.2+1" - -[[deps.Libgcrypt_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] -git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" -uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.7+0" - -[[deps.Libglvnd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] -git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" -uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" -version = "1.6.0+0" - -[[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" -uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.42.0+0" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.17.0+0" - -[[deps.Libmount_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73" -uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.35.0+0" - -[[deps.Libuuid_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066" -uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.36.0+0" - -[[deps.LightXML]] -deps = ["Libdl", "XML2_jll"] -git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" -uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" -version = "0.9.1" - -[[deps.LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.2.0" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[deps.LinearAlgebraX]] -deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] -git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" -uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" -version = "0.2.7" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.26" - - [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.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.0.0+0" - -[[deps.MPICH_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "2ee75365ca243c1a39d467e35ffd3d4d32eef11e" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.1.2+1" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.10" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "8eeb3c73bbc0ca203d0dc8dad4008350bbe5797b" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.3.1+1" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.13" - -[[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "a37c6610dd20425b131caf65d52abdf859da5ab1" -uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.20.4" - -[[deps.MakieCore]] -deps = ["Observables", "REPL"] -git-tree-sha1 = "ec5db7bb2dc9b85072658dcb2d3ad09569b09ac9" -uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.7.2" - -[[deps.MappedArrays]] -git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.2" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[deps.MathTeXEngine]] -deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] -git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" -uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.5.7" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+1" - -[[deps.MeshIO]] -deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] -git-tree-sha1 = "8be09d84a2d597c7c0c34d7d604c039c9763e48c" -uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" -version = "0.4.10" - -[[deps.MicrosoftMPI_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "b01beb91d20b0d1312a9471a36017b5b339d26de" -uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" -version = "10.1.4+1" - -[[deps.Missings]] -deps = ["DataAPI"] -git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.1.0" - -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[deps.ModernGL]] -deps = ["Libdl"] -git-tree-sha1 = "b76ea40b5c0f45790ae09492712dd326208c28b2" -uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -version = "1.1.7" - -[[deps.Mods]] -git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" -uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" -version = "2.2.4" - -[[deps.MosaicViews]] -deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] -git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" -uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" -version = "0.3.4" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.1.10" - -[[deps.Multisets]] -git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" -uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" -version = "0.4.4" - -[[deps.NCDatasets]] -deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "4704758e7dd9c843f0a99b18a26aa2d88dd8b8e6" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.0" - -[[deps.NLSolversBase]] -deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] -git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.8.3" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.0.2" - -[[deps.NetCDF_jll]] -deps = ["Artifacts", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "XML2_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "10c612c81eaffdd6b7c28a45a554cdd9d2f40ff1" -uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" -version = "400.902.208+0" - -[[deps.Netpbm]] -deps = ["FileIO", "ImageCore", "ImageMetadata"] -git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" -uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" -version = "1.1.1" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.Observables]] -git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.5.5" - -[[deps.OffsetArrays]] -git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.13.0" -weakdeps = ["Adapt"] - - [deps.OffsetArrays.extensions] - OffsetArraysAdaptExt = "Adapt" - -[[deps.Ogg_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" -uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" -version = "1.3.5+1" - -[[deps.OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.23+2" - -[[deps.OpenEXR]] -deps = ["Colors", "FileIO", "OpenEXR_jll"] -git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" -uuid = "52e1d378-f018-4a11-a4be-720524705ac7" -version = "0.3.2" - -[[deps.OpenEXR_jll]] -deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" -uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.1.4+0" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+2" - -[[deps.OpenMPI_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "e25c1778a98e34219a00455d6e4384e017ea9762" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "4.1.6+0" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.12+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.Optim]] -deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.7.8" - -[[deps.Opus_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" -uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.3.2+0" - -[[deps.OrderedCollections]] -git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.3" - -[[deps.PCRE2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.42.0+1" - -[[deps.PDMats]] -deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.31" - -[[deps.PNGFiles]] -deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] -git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" -uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" -version = "0.4.3" - -[[deps.Packing]] -deps = ["GeometryBasics"] -git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.5.0" - -[[deps.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[deps.Parameters]] -deps = ["OrderedCollections", "UnPack"] -git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.12.3" - -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.1" - -[[deps.Permutations]] -deps = ["Combinatorics", "LinearAlgebra", "Random"] -git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" -uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" -version = "0.4.20" - -[[deps.PikaParser]] -deps = ["DocStringExtensions"] -git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" -uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" -version = "0.6.1" - -[[deps.Pixman_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" -uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.42.2+0" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.10.0" - -[[deps.PkgVersion]] -deps = ["Pkg"] -git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" -uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.3" - -[[deps.PlotUtils]] -deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] -git-tree-sha1 = "862942baf5663da528f66d24996eb6da85218e76" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.4.0" - -[[deps.PolygonOps]] -git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" -uuid = "647866c9-e3ac-4575-94e7-e3d426903924" -version = "0.1.2" - -[[deps.Polynomials]] -deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "4.0.6" - - [deps.Polynomials.extensions] - PolynomialsChainRulesCoreExt = "ChainRulesCore" - PolynomialsFFTWExt = "FFTW" - PolynomialsMakieCoreExt = "MakieCore" - PolynomialsMutableArithmeticsExt = "MutableArithmetics" - - [deps.Polynomials.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" - MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" - MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" - -[[deps.PositiveFactorizations]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.4" - -[[deps.PrecompileTools]] -deps = ["Preferences"] -git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.0" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.1" - -[[deps.Primes]] -deps = ["IntegerMathUtils"] -git-tree-sha1 = "1d05623b5952aed1307bf8b43bec8b8d1ef94b6e" -uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.5.5" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[deps.ProgressMeter]] -deps = ["Distributed", "Printf"] -git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" -uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.9.0" - -[[deps.QOI]] -deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] -git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" -uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" -version = "1.0.0" - -[[deps.QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.9.4" - -[[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[deps.RangeArrays]] -git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" -uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" -version = "0.3.2" - -[[deps.Ratios]] -deps = ["Requires"] -git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.4.5" -weakdeps = ["FixedPointNumbers"] - - [deps.Ratios.extensions] - RatiosFixedPointNumbersExt = "FixedPointNumbers" - -[[deps.RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.RelocatableFolders]] -deps = ["SHA", "Scratch"] -git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" -uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.1" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.0" - -[[deps.RingLists]] -deps = ["Random"] -git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" -uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" -version = "0.2.8" - -[[deps.Rmath]] -deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.7.1" - -[[deps.Rmath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.0+0" - -[[deps.RoundingEmulator]] -git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" -uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" -version = "0.2.1" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.Scratch]] -deps = ["Dates"] -git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" -uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.2.1" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.1" - -[[deps.ShaderAbstractions]] -deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "db0219befe4507878b1a90e07820fed3e62c289d" -uuid = "65257c39-d410-5151-9873-9b3e5be5013e" -version = "0.4.0" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[deps.Showoff]] -deps = ["Dates", "Grisu"] -git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "1.0.3" - -[[deps.SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - -[[deps.SimpleGraphs]] -deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] -git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" -uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" -version = "0.8.6" - -[[deps.SimplePartitions]] -deps = ["AbstractLattices", "DataStructures", "Permutations"] -git-tree-sha1 = "e9330391d04241eafdc358713b48396619c83bcb" -uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" -version = "0.3.1" - -[[deps.SimplePolynomials]] -deps = ["Mods", "Multisets", "Polynomials", "Primes"] -git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" -uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" -version = "0.2.17" - -[[deps.SimpleRandom]] -deps = ["Distributions", "LinearAlgebra", "Random"] -git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" -uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" -version = "0.3.1" - -[[deps.SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" - -[[deps.Sixel]] -deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] -git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" -uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" -version = "0.1.3" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[deps.SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.10.0" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.1" -weakdeps = ["ChainRulesCore"] - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - -[[deps.StableHashTraits]] -deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] -git-tree-sha1 = "008ca4718b5b55983dd0ffc63ce1f029c4a88f35" -uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" -version = "1.1.5" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.1" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "f68dd04d131d9a8a8eb836173ee8f105c360b0c5" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.1" -weakdeps = ["ChainRulesCore", "Statistics"] - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.2" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.0" - -[[deps.StatsBase]] -deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.2" - -[[deps.StatsFuns]] -deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.3.0" - - [deps.StatsFuns.extensions] - StatsFunsChainRulesCoreExt = "ChainRulesCore" - StatsFunsInverseFunctionsExt = "InverseFunctions" - - [deps.StatsFuns.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - -[[deps.StructArrays]] -deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.16" - -[[deps.SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.0+1" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.1" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[deps.TensorCore]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" -uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" -version = "0.1.1" - -[[deps.Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.TiffImages]] -deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] -git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" -uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.6.8" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.2" -weakdeps = ["Random", "Test"] - - [deps.TranscodingStreams.extensions] - TestExt = ["Test", "Random"] - -[[deps.TriplotBase]] -git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" -uuid = "981d1d27-644d-49a2-9326-4793e63143c3" -version = "0.1.0" - -[[deps.TupleTools]] -git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" -uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" -version = "1.4.3" - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[deps.UnicodeFun]] -deps = ["REPL"] -git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.1" - -[[deps.WoodburyMatrices]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "1.0.0" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.2+0" - -[[deps.XSLT_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] -git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" -uuid = "aed1982a-8fda-507f-9586-7b0439959a61" -version = "1.1.34+0" - -[[deps.Xorg_libX11_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] -git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" -uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" -version = "1.8.6+0" - -[[deps.Xorg_libXau_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" -uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" -version = "1.0.11+0" - -[[deps.Xorg_libXcursor_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] -git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" -uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" -version = "1.2.0+4" - -[[deps.Xorg_libXdmcp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" -uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" -version = "1.1.4+0" - -[[deps.Xorg_libXext_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" -uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.4+4" - -[[deps.Xorg_libXfixes_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" -uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" -version = "5.0.3+4" - -[[deps.Xorg_libXi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] -git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" -uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" -version = "1.7.10+4" - -[[deps.Xorg_libXinerama_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] -git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" -uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" -version = "1.1.4+4" - -[[deps.Xorg_libXrandr_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] -git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" -uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" -version = "1.5.2+4" - -[[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" -uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.10+4" - -[[deps.Xorg_libpthread_stubs_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" -uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" -version = "0.1.1+0" - -[[deps.Xorg_libxcb_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] -git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" -uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.15.0+0" - -[[deps.Xorg_xtrans_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" -uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" -version = "1.5.0+0" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+1" - -[[deps.Zstd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.5+0" - -[[deps.isoband_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" -uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" -version = "0.2.3+0" - -[[deps.libaec_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "eddd19a8dea6b139ea97bdc8a0e2667d4b661720" -uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.0.6+1" - -[[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" -uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.4.0+0" - -[[deps.libass_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" -uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" -version = "0.15.1+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+1" - -[[deps.libfdk_aac_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" -uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" -version = "2.0.2+0" - -[[deps.libpng_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "93284c28274d9e75218a416c65ec49d0e0fcdf3d" -uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.40+0" - -[[deps.libsixel_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] -git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" -uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" -version = "1.10.3+0" - -[[deps.libvorbis_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] -git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" -uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.7+1" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" - -[[deps.x264_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" -uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" -version = "2021.5.5+0" - -[[deps.x265_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" -uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" -version = "3.5.0+0" diff --git a/experiments/prototype_omip_simulation/CATKE_column_simulations/Project.toml b/experiments/prototype_omip_simulation/CATKE_column_simulations/Project.toml deleted file mode 100644 index 3ad59e5e..00000000 --- a/experiments/prototype_omip_simulation/CATKE_column_simulations/Project.toml +++ /dev/null @@ -1,3 +0,0 @@ -[deps] -GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" diff --git a/experiments/prototype_omip_simulation/CATKE_column_simulations/take_a_look.jl b/experiments/prototype_omip_simulation/CATKE_column_simulations/take_a_look.jl deleted file mode 100644 index d642f737..00000000 --- a/experiments/prototype_omip_simulation/CATKE_column_simulations/take_a_look.jl +++ /dev/null @@ -1,14 +0,0 @@ -using NCDatasets -using GLMakie - -filename = "single_column_omip_ocean_station_papa.nc" - -ds = Dataset(filename) -K = ds["κᶜ"][1, 1, :, :] -zf = ds["zF"][:] -t = ds["time"][:] - -# close(ds) - -heatmap(t, zf, K') - diff --git a/experiments/prototype_omip_simulation/omip_sea_ice_component.jl b/experiments/prototype_omip_simulation/omip_sea_ice_component.jl deleted file mode 100644 index e69de29b..00000000 diff --git a/experiments/prototype_omip_simulation/omip_simulation.jl b/experiments/prototype_omip_simulation/omip_simulation.jl deleted file mode 100644 index 2070f470..00000000 --- a/experiments/prototype_omip_simulation/omip_simulation.jl +++ /dev/null @@ -1,311 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.TurbulenceClosures: CATKEVerticalDiffusivity -using Oceananigans.Fields: ConstantField, ZeroField, interpolate! - -using ClimaOcean -using ClimaOcean.OceanSeaIceModels: - adjust_ice_covered_ocean_temperature!, - TwoStreamDownwellingRadiation, - PrescribedAtmosphere, - SurfaceRadiation - -using ClimaSeaIce -using ClimaSeaIce: IceWaterThermalEquilibrium - -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState - -using NCDatasets -using GLMakie -using Printf - -using Downloads: download - -start_time = time_ns() - -temperature_filename = "THETA.1440x720x50.19920102.nc" -salinity_filename = "SALT.1440x720x50.19920102.nc" -ice_thickness_filename = "SIheff.1440x720.19920102.nc" -#= - -# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N - -temperature_url = "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/" * - "THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs&dl=0" - -salinity_url = "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/" * - "SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw&dl=0" - -ice_thickness_url = "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/" * - "SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am&dl=0" - -isfile(temperature_filename) || download(temperature_url, temperature_filename) -isfile(salinity_filename) || download(salinity_url, salinity_filename) -isfile(ice_thickness_filename) || download(ice_thickness_url, ice_thickness_filename) - -temperature_ds = Dataset(temperature_filename) -salinity_ds = Dataset(salinity_filename) -ice_thickness_ds = Dataset(ice_thickness_filename) - -# Construct vertical coordinate -depth = temperature_ds["DEPTH_T"][:] -zc = -reverse(depth) - -# Interface depths from cell center depths -zf = (zc[1:end-1] .+ zc[2:end]) ./ 2 -push!(zf, 0) - -Δz = zc[2] - zc[1] -pushfirst!(zf, zf[1] - Δz) - -Tᵢ = temperature_ds["THETA"][:, :, :, 1] -Sᵢ = salinity_ds["SALT"][:, :, :, 1] -ℋᵢ = ice_thickness_ds["SIheff"][:, :, 1] - -Nx, Ny′, Nz = size(Tᵢ) - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### - -arch = CPU() -southern_limit = -79 -northern_limit = -30 -j₁ = 4 * (90 + southern_limit) -j₂ = 720 - 4 * (90 - northern_limit) + 1 -Ny = j₂ - j₁ + 1 - -Tᵢ = Tᵢ[:, j₁:j₂, :] -Sᵢ = Sᵢ[:, j₁:j₂, :] -ℋᵢ = ℋᵢ[:, j₁:j₂] - -Tᵢ = convert(Array{Float32, 3}, Tᵢ) -Sᵢ = convert(Array{Float32, 3}, Sᵢ) -ℋᵢ = convert(Array{Float32, 2}, ℋᵢ) - -Tᵢ = reverse(Tᵢ, dims=3) -Sᵢ = reverse(Sᵢ, dims=3) - -missing_value = Float32(-9.9e22) - -# Construct bottom_height depth by analyzing T -Nx, Ny, Nz = size(Tᵢ) -bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) - -for i = 1:Nx, j = 1:Ny - @inbounds for k = Nz:-1:1 - if Tᵢ[i, j, k] < -10 - bottom_height[i, j] = zf[k+1] - break - end - end -end - -grid = LatitudeLongitudeGrid(arch, - size = (Nx, Ny, Nz), - longitude = (0, 360), - halo = (7, 7, 7), - latitude = (southern_limit, northern_limit), - z = zf, - topology = (Periodic, Bounded, Bounded)) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - -elapsed = time_ns() - start_time -@info "Grid constructed including evaluation of bottom height from initial condition data. " * - prettytime(elapsed * 1e-9) -start_time = time_ns() - -# Defines `ocean`, an `Oceananigans.Simulation` -include("omip_ocean_component.jl") - -elapsed = time_ns() - start_time -@info "Ocean component built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -ocean_model.clock.time = 0 -ocean_model.clock.iteration = 0 -set!(ocean_model, T=Tᵢ, S=Sᵢ, e=1e-6) - -# Defines `sea_ice`, an `Oceananigans.Simulation` -include("omip_sea_ice_component.jl") - -elapsed = time_ns() - start_time -@info "Sea ice component built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -# Defines `atmosphere`, a `ClimaOcean.OceanSeaIceModels.PrescribedAtmosphere` -# also defines `radiation`, a `ClimaOcean.OceanSeaIceModels.Radiation` -include("omip_atmosphere.jl") - -elapsed = time_ns() - start_time -@info "Atmosphere built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -surface_radiation = SurfaceRadiation() -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, surface_radiation) -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_iteration=2) - -elapsed = time_ns() - start_time -@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -adjust_ice_covered_ocean_temperature!(coupled_model) - -wall_clock = Ref(time_ns()) - -function progress(sim) - - msg1 = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg2 = string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg3 = @sprintf(", max|u|: (%.2e, %.2e, %.2e)", - maximum(abs, u), - maximum(abs, v), - maximum(abs, w)) - - @info msg1 * msg2 * msg3 -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) - -using Oceananigans.Operators: ζ₃ᶠᶠᶜ -u, v, w = ocean_model.velocities -ζ = KernelFunctionOperation{Face, Face, Center}(ζ₃ᶠᶠᶜ, grid, u, v) -a = @at (Center, Center, Center) (u^2 + v^2) / 2 -ℋ = sea_ice_model.ice_thickness - -# Build flux outputs -Jᵘ = coupled_model.surfaces.ocean.momentum.u -Jᵛ = coupled_model.surfaces.ocean.momentum.v -Jᵀ = coupled_model.surfaces.ocean.tracers.T -F = coupled_model.surfaces.ocean.tracers.S -ρₒ = coupled_model.ocean_reference_density -cₚ = coupled_model.ocean_heat_capacity - -Q = ρₒ * cₚ * Jᵀ -τˣ = ρₒ * Jᵘ -τʸ = ρₒ * Jᵛ - -fluxes = (; τˣ, τʸ, Q, F) - -fields = merge(ocean_model.velocities, ocean_model.tracers, - (; ζ = Field(ζ), ℋ )) - -# Slice fields at the surface -#fields = NamedTuple(name => view(fields[name], :, :, Nz) for name in keys(fields)) -outputs = merge(fields, fluxes) - -filename = "omip_surface_fields.jld2" - -coupled_simulation.output_writers[:surface] = JLD2OutputWriter(ocean_model, outputs; filename, - #schedule = TimeInterval(1day), - schedule = IterationInterval(1), - indices = (:, :, Nz), - overwrite_existing = true) - -run!(coupled_simulation) -=# - -filename = "omip_surface_fields.jld2" - -τˣt = FieldTimeSeries(filename, "τˣ") -τʸt = FieldTimeSeries(filename, "τʸ") -Qt = FieldTimeSeries(filename, "Q") -Ft = FieldTimeSeries(filename, "F") - -Tt = FieldTimeSeries(filename, "T") -St = FieldTimeSeries(filename, "S") -et = FieldTimeSeries(filename, "e") -ζt = FieldTimeSeries(filename, "ζ") - -function nan_land!(ψt) - Nt = length(ψt.times) - land = interior(ψt[1], :, :, 1) .== 0 - for n = 2:Nt - ψn = interior(ψt[n], :, :, 1) - ψn[land] .= NaN - end - return nothing -end - -for ψt in (τˣt, τʸt, Qt, Ft, Tt, St, et, ζt) - nan_land!(ψt) -end - -λf, φc, zc = nodes(τˣt) -λc, φf, zc = nodes(τʸt) -λc, φc, zc = nodes(Qt) -λf, φf, zc = nodes(ζt) - -fig = Figure(size=(2400, 1200)) - -Nt = length(Tt.times) -slider = Slider(fig[5, 2:3], range=1:Nt, startvalue=1) -n = slider.value #Observable(1) - -τˣn = @lift interior(τˣt[$n], :, :, 1) -τʸn = @lift interior(τʸt[$n], :, :, 1) -Qn = @lift interior(Qt[$n], :, :, 1) -Fn = @lift interior(Ft[$n], :, :, 1) - -Tn = @lift interior(Tt[$n], :, :, 1) -Sn = @lift interior(St[$n], :, :, 1) -en = @lift interior(et[$n], :, :, 1) -ζn = @lift interior(ζt[$n], :, :, 1) - -Qmax = 1000 -τmax = 1.0 -Fmax = 1e-4 - -Tmax = 32 -Tmin = -2 -Smax = 35 -Smin = 20 -elim = 1e-2 -ζlim = 1e-4 - -τlim = 3τmax / 4 -Qlim = 3Qmax / 4 -Flim = 3Fmax / 4 - -axx = Axis(fig[1, 2]) -axy = Axis(fig[2, 2]) -axQ = Axis(fig[3, 2]) -axF = Axis(fig[4, 2]) - -axT = Axis(fig[1, 3]) -axS = Axis(fig[2, 3]) -axe = Axis(fig[3, 3]) -axz = Axis(fig[4, 3]) - -hmx = heatmap!(axx, λf, φc, τˣn, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) -hmy = heatmap!(axy, λc, φf, τʸn, colorrange=(-τlim, τlim), colormap=:balance, nan_color=:gray) -hmQ = heatmap!(axQ, λc, φc, Qn, colorrange=(-Qlim, Qlim), colormap=:balance, nan_color=:gray) -hmF = heatmap!(axF, λc, φc, Fn, colorrange=(-Flim, Flim), colormap=:balance, nan_color=:gray) - -Colorbar(fig[1, 1], hmx, flipaxis=false, label="Eastward momentum flux (N m⁻²)") -Colorbar(fig[2, 1], hmy, flipaxis=false, label="Northward momentum flux (N m⁻²)") -Colorbar(fig[3, 1], hmQ, flipaxis=false, label="Heat flux (W m⁻²)") -Colorbar(fig[4, 1], hmF, flipaxis=false, label="Salt flux (m s⁻¹ psu)") - -hmT = heatmap!(axT, λf, φc, Tn, colorrange=(Tmin, Tmax), colormap=:thermal, nan_color=:gray) -hmS = heatmap!(axS, λc, φf, Sn, colorrange=(Smin, Smax), colormap=:haline, nan_color=:gray) -hme = heatmap!(axe, λc, φc, en, colorrange=(0, elim), colormap=:solar, nan_color=:gray) -hmz = heatmap!(axz, λf, φf, ζn, colorrange=(-ζlim, ζlim), colormap=:balance, nan_color=:gray) - -Colorbar(fig[1, 4], hmx, label="Temperature (ᵒC)") -Colorbar(fig[2, 4], hmy, label="Salinity (psu)") -Colorbar(fig[3, 4], hmQ, label="Turbulent kinetic energy (m² s⁻²)") -Colorbar(fig[4, 4], hmF, label="Vorticity (s⁻¹)") - -display(fig) - diff --git a/experiments/prototype_omip_simulation/surface_fluxes.jl b/experiments/prototype_omip_simulation/surface_fluxes.jl deleted file mode 100644 index c198c102..00000000 --- a/experiments/prototype_omip_simulation/surface_fluxes.jl +++ /dev/null @@ -1,209 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.BuoyancyModels: buoyancy_frequency -using Oceananigans.Units: Time - -using ClimaOcean -using ClimaOcean.OceanSeaIceModels: Radiation -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere -using ClimaOcean.DataWrangling.ECCO2: ecco2_field - -using GLMakie -using Printf -using Dates - -start_time = time_ns() - -include("omip_components.jl") - -arch = CPU() -epoch = Date(1992, 1, 1) -date = Date(1992, 10, 1) -start_seconds = Second(date - epoch).value -ue = ecco2_field(:u_velocity, date) -ve = ecco2_field(:v_velocity, date) -Te = ecco2_field(:temperature, date) -Se = ecco2_field(:salinity, date) - -land = interior(Te) .< -10 -interior(Te)[land] .= NaN -interior(Se)[land] .= NaN - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### - -latitude = (-75, +65) -longitude = (0, 360) - -i₁ = 4 * first(longitude) + 1 -i₂ = 1440 - 4 * (360 - last(longitude)) -Nx = i₂ - i₁ + 1 - -j₁ = 4 * (90 + first(latitude)) + 1 -j₂ = 720 - 4 * (90 - last(latitude)) -Ny = j₂ - j₁ + 1 - -Nz = size(Te, 3) - -Tᵢ = Te[i₁:i₂, j₁:j₂, Nz:Nz] -Sᵢ = Se[i₁:i₂, j₁:j₂, Nz:Nz] -uᵢ = ue[i₁:i₂, j₁:j₂, Nz:Nz] -vᵢ = ve[i₁:i₂, j₁:j₂+1, Nz:Nz] - -# Construct bottom_height depth by analyzing T -Nx, Ny, Nz = size(Tᵢ) -bottom_height = zeros(Nx, Ny) - -for i = 1:Nx, j = 1:Ny - @inbounds bottom_height[i, j] = ifelse(isnan(Tᵢ[i, j, 1]), Inf, -Inf) -end - -grid = LatitudeLongitudeGrid(arch; latitude, longitude, - size = (Nx, Ny, 1), - halo = (7, 7, 7), - z = (-10, 0), - topology = (Periodic, Bounded, Bounded)) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - -elapsed = time_ns() - start_time -@info "Grid constructed. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -ocean = omip_ocean_component(grid) -elapsed = time_ns() - start_time -@info "Ocean component built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -atmosphere = JRA55_prescribed_atmosphere(1:2, backend=InMemory(), architecture=arch) -elapsed = time_ns() - start_time -@info "Atmosphere built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -#= -fig = Figure() -axu = Axis(fig[1, 1]) -axv = Axis(fig[1, 2]) -axT = Axis(fig[1, 3]) -axq = Axis(fig[1, 4]) - -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q - -heatmap!(axu, interior(ua, :, :, 1, 1)) -heatmap!(axv, interior(va, :, :, 1, 1)) -heatmap!(axT, interior(Ta, :, :, 1, 1)) -heatmap!(axq, interior(qa, :, :, 1, 1)) - -display(fig) - -ocean.model.clock.time = start_seconds -ocean.model.clock.iteration = 0 -set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) - -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -times = ua.times -=# - -sea_ice = nothing -radiation = Radiation() -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -elapsed = time_ns() - start_time -@info "Coupled model built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -# Build flux outputs -Jᵘ = coupled_model.fluxes.total.ocean.momentum.u -Jᵛ = coupled_model.fluxes.total.ocean.momentum.v -Jᵀ = coupled_model.fluxes.total.ocean.tracers.T -Jˢ = coupled_model.fluxes.total.ocean.tracers.S - -E = coupled_model.fluxes.turbulent.fields.water_vapor -Fʳ = atmosphere.freshwater_flux.rain -Fˢ = atmosphere.freshwater_flux.snow - -Qᶜ = coupled_model.fluxes.turbulent.fields.sensible_heat -Qᵉ = coupled_model.fluxes.turbulent.fields.latent_heat -Qˡ = atmosphere.downwelling_radiation.longwave -Qˢ = atmosphere.downwelling_radiation.shortwave - -ρₒ = coupled_model.fluxes.ocean_reference_density -cₚ = coupled_model.fluxes.ocean_heat_capacity - -P = Field(- Fʳ[1] - Fˢ[1]) -ΣQ = Field(ρₒ * cₚ * Jᵀ) -u★ = Field(sqrt(sqrt(Jᵘ^2 + Jᵛ^2))) - -N² = buoyancy_frequency(ocean.model) -κᶜ = ocean.model.diffusivity_fields.κᶜ -To = ocean.model.tracers.T -qa = atmosphere.tracers.q - -compute!(ΣQ) -compute!(P) -compute!(u★) - -fig = Figure(size=(1200, 1800)) - -axτ = Axis(fig[1, 1], title="u★") -axT = Axis(fig[2, 1], title="T") -axq = Axis(fig[3, 1], title="q") -axE = Axis(fig[4, 1], title="E") -axP = Axis(fig[5, 1], title="P") - -axQt = Axis(fig[1, 2], title="Net heat flux") -axQl = Axis(fig[2, 2], title="Incoming longwave heat flux") -axQs = Axis(fig[3, 2], title="Shortwave / solar heat flux") -axQe = Axis(fig[4, 2], title="Evaporative heat flux") -axQc = Axis(fig[5, 2], title="Conductive / sensible heat flux") - -u★i = interior(u★, :, :, 1) -Toi = interior(To, :, :, 1) -qai = interior(qa, :, :, 1, 1) -Ei = interior(E, :, :, 1) -Pi = interior(P, :, :, 1) - -Flim = 1e-6 -hmτ = heatmap!(axτ, u★i, colormap=:solar, colorrange=(0, 1e-1)) -hmT = heatmap!(axT, Toi, colormap=:thermal, colorrange=(0, 10)) -hmq = heatmap!(axq, qai, colormap=:grays) -hmE = heatmap!(axE, Ei, colormap=:balance, colorrange=(-Flim, Flim)) -hmP = heatmap!(axP, Pi, colormap=:balance, colorrange=(-Flim, Flim)) - -Colorbar(fig[1, 0], hmτ, label="Friction velocity (m s⁻¹)") -Colorbar(fig[2, 0], hmT, label="Ocean surface temperature (ᵒC)") -Colorbar(fig[3, 0], hmq, label="Atmosphere specific humidity") -Colorbar(fig[4, 0], hmE, label="Evaporation freshwater flux (m s⁻¹)") -Colorbar(fig[5, 0], hmP, label="Precipitation freshwater flux (m s⁻¹)") - -ΣQi = interior(ΣQ, :, :, 1) -Qˢi = - interior(Qˢ, :, :, 1, 1) -Qˡi = - interior(Qˡ, :, :, 1, 1) -Qᵉi = interior(Qᵉ, :, :, 1) -Qᶜi = interior(Qᶜ, :, :, 1) - -Qlim = 1000 -hmt = heatmap!(axQt, ΣQi, colormap=:balance, colorrange=(-Qlim, Qlim)) -hms = heatmap!(axQs, Qˢi, colormap=:balance, colorrange=(-Qlim, Qlim)) -hml = heatmap!(axQl, Qˡi, colormap=:balance, colorrange=(-Qlim, Qlim)) -hme = heatmap!(axQe, Qᵉi, colormap=:balance, colorrange=(-Qlim, Qlim)) -hmc = heatmap!(axQc, Qᶜi, colormap=:balance, colorrange=(-Qlim, Qlim)) - -Colorbar(fig[1, 3], hmt, label="Net heat flux") -Colorbar(fig[2, 3], hml, label="Incoming longwave heat flux") -Colorbar(fig[3, 3], hms, label="Shortwave / solar heat flux") -Colorbar(fig[4, 3], hme, label="Evaporative heat flux") -Colorbar(fig[5, 3], hmc, label="Conductive / sensible heat flux") - -display(fig) - diff --git a/experiments/prototype_omip_simulation/test_field_time_series.jl b/experiments/prototype_omip_simulation/test_field_time_series.jl deleted file mode 100644 index 68d42fca..00000000 --- a/experiments/prototype_omip_simulation/test_field_time_series.jl +++ /dev/null @@ -1,37 +0,0 @@ -using Oceananigans -using Oceananigans.OutputReaders: Cyclical, update_field_time_series! -using Oceananigans.Utils: Time -using GLMakie - -grid = RectilinearGrid(size=(1, 1, 1), extent=(1, 1, 1)) -times = 0:6 -path = "test_field_time_series.jld2" -rm(path, force=true) -name = "c" -c = CenterField(grid) -odct = FieldTimeSeries{Center, Center, Center}(grid; backend=OnDisk(), path, name) -for n in times - set!(c, n) - set!(odct, c, n, n) -end - -timct = FieldTimeSeries(path, name; backend=InMemory(), time_indexing=Cyclical()) -pimct = FieldTimeSeries(path, name; backend=InMemory(3), time_indexing=Cyclical()) - -ts = -2.1:0.1:17.1 -Nt = length(ts) -pci = zeros(Nt) - -for (n, t) in enumerate(ts) - update_field_time_series!(pimct, Time(t)) - pci[n] = pimct[1, 1, 1, Time(t)] -end - -tci = [timct[1, 1, 1, Time(t)] for t in ts] - -fig = Figure() -ax = Axis(fig[1, 1]) -scatterlines!(ax, ts, tci, marker='s', color=:blue) -scatterlines!(ax, ts, pci, marker=:square, color=:pink) -scatter!(ax, timct.times, timct[1, 1, 1, :], marker='o', markersize=20) -display(fig) diff --git a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl deleted file mode 100644 index 2c4995ee..00000000 --- a/experiments/prototype_omip_simulation/test_single_column_omip_simulation.jl +++ /dev/null @@ -1,166 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.Grids: node -using Oceananigans.BuoyancyModels: buoyancy_frequency -using Oceananigans.Units: Time - -using ClimaOcean -using ClimaOcean.OceanSeaIceModels: Radiation -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: interp_atmos_time_series -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere -using ClimaOcean.DataWrangling.ECCO2: ecco2_field - -using Printf -using Dates - -include("omip_components.jl") - -locations = ( - #eastern_mediterranean = (λ = 30, φ = 32), - ocean_station_papa = (λ = 215, φ = 50), - north_atlantic = (λ = 325, φ = 50), - drake_passage = (λ = 300, φ = -60), - weddell_sea = (λ = 325, φ = -70), - tasman_southern_ocean = (λ = 145, φ = -55), -) - -arch = GPU() -location = :ocean_station_papa - -start_time = time_ns() - -epoch = Date(1992, 1, 1) -date = Date(1992, 10, 1) -start_seconds = Second(date - epoch).value -Tᵢ = ecco2_field(:temperature, date) -Sᵢ = ecco2_field(:salinity, date) - -land = interior(Tᵢ) .< -10 -interior(Tᵢ)[land] .= NaN -interior(Sᵢ)[land] .= NaN - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### - -Δ = 1/4 # resolution in degrees -φ₁ = -90 + Δ/2 -φ₂ = +90 - Δ/2 -λ₁ = 0 + Δ/2 -λ₂ = 360 - Δ/2 -φe = φ₁:Δ:φ₂ -λe = λ₁:Δ:λ₂ - -λ★, φ★ = locations[location] - -i★ = searchsortedfirst(λe, λ★) -j★ = searchsortedfirst(φe, φ★) - -longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) -latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) - -# Column -Tc = interior(Tᵢ, i★:i★, j★:j★, :) -Sc = interior(Sᵢ, i★:i★, j★:j★, :) - -# Find bottom -zm = -400 -zf = znodes(Tᵢ.grid, Face()) -kb = findlast(T -> T < -20, Tc[1, 1, :]) -km = findlast(z -> z < zm, zf) -k★ = isnothing(kb) ? km : max(kb + 1, km) - -Nz = size(Tc, 3) -kf = k★:Nz+1 -kc = k★:Nz -zf = zf[kf] -Tc = Tc[:, :, kc] -Sc = Sc[:, :, kc] -Nz′ = length(kc) - -grid = LatitudeLongitudeGrid(arch; longitude, latitude, - size = (1, 1, Nz′), - z = zf, - topology = (Periodic, Periodic, Bounded)) - -ocean = omip_ocean_component(grid) -set!(ocean.model, T=Tc, S=Sc, e=1e-6) - -start_time = time_ns() -Ndays = 2 -Nt = 8 * Ndays -# atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(8), architecture=GPU()) #, 1:21) -atmosphere = JRA55_prescribed_atmosphere(1:Nt, backend=InMemory(8), architecture=arch) -@info "Atmosphere built. " * prettytime((time_ns() - start_time) * 1e-9) - -# Build coupled simulation -start_time = time_ns() -sea_ice = nothing -radiation = Radiation() -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=14days) -@info "Coupled simulation built. " * prettytime((time_ns() - start_time) * 1e-9) - -wall_clock = Ref(time_ns()) - -atmos_grid = atmosphere.grid -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -times = ua.times - -const c = Center() - -function progress(sim) - msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg *= string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - #= - t = time(sim) - X = node(1, 1, 1, sim.model.ocean.model.grid, c, c, c) - uai = interp_atmos_time_series(ua, X, Time(t), atmos_grid) - vai = interp_atmos_time_series(va, X, Time(t), atmos_grid) - Tai = interp_atmos_time_series(Ta, X, Time(t), atmos_grid) - qai = interp_atmos_time_series(qa, X, Time(t), atmos_grid) - - msg *= @sprintf(", ua: %.2e, va: %.2e, Ta: %.2f, qa: %.2e", uai, vai, Tai, qai) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - e = sim.model.ocean.model.tracers.e - - τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) - τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) - u★ = (τˣ^2 + τʸ^2)^(1/4) - msg *= @sprintf(", τˣ: %.2f m² s⁻²", τˣ) - msg *= @sprintf(", τʸ: %.2f m² s⁻²", τʸ) - msg *= @sprintf(", u★: %.2f m s⁻¹", u★) - - Q = first(sim.model.fluxes.total.ocean.heat) - msg *= @sprintf(", Q: %.2f W m⁻²", Q) - - Nz = size(T, 3) - msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) - msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) - msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) - =# - - @info msg -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1)) - -run!(coupled_simulation) - diff --git a/experiments/prototype_omip_simulation/updated_Manifest.toml b/experiments/prototype_omip_simulation/updated_Manifest.toml deleted file mode 100644 index 7aa5a0b8..00000000 --- a/experiments/prototype_omip_simulation/updated_Manifest.toml +++ /dev/null @@ -1,2290 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.0-beta3" -manifest_format = "2.0" -project_hash = "0892c27a537f93187841c13e787e804f45c1eef4" - -[[deps.AbstractFFTs]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.5.0" -weakdeps = ["ChainRulesCore", "Test"] - - [deps.AbstractFFTs.extensions] - AbstractFFTsChainRulesCoreExt = "ChainRulesCore" - AbstractFFTsTestExt = "Test" - -[[deps.AbstractLattices]] -git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" -uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" -version = "0.3.0" - -[[deps.AbstractTrees]] -git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" -uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" -version = "0.4.4" - -[[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Test"] -git-tree-sha1 = "cb96992f1bec110ad211b7e410e57ddf7944c16f" -uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.35" - - [deps.Accessors.extensions] - AccessorsAxisKeysExt = "AxisKeys" - AccessorsIntervalSetsExt = "IntervalSets" - AccessorsStaticArraysExt = "StaticArrays" - AccessorsStructArraysExt = "StructArrays" - - [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" - -[[deps.Adapt]] -deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.7.2" -weakdeps = ["StaticArrays"] - - [deps.Adapt.extensions] - AdaptStaticArraysExt = "StaticArrays" - -[[deps.Animations]] -deps = ["Colors"] -git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" -uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" -version = "0.4.1" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "bbec08a37f8722786d87bedf84eae19c020c4efa" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.7.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - 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" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" - -[[deps.Atomix]] -deps = ["UnsafeAtomics"] -git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" -uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" -version = "0.1.0" - -[[deps.Automa]] -deps = ["PrecompileTools", "TranscodingStreams"] -git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" -uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "1.0.3" - -[[deps.AxisAlgorithms]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] -git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "1.1.0" - -[[deps.AxisArrays]] -deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] -git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" -uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.4.7" - -[[deps.BFloat16s]] -deps = ["LinearAlgebra", "Printf", "Random", "Test"] -git-tree-sha1 = "dbf84058d0a8cbbadee18d25cf606934b22d7c66" -uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" -version = "0.4.2" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[deps.BitFlags]] -git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.8" - -[[deps.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 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" -uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.1.2" - -[[deps.CRC32c]] -uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" - -[[deps.CRlibm]] -deps = ["CRlibm_jll"] -git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" -uuid = "96374032-68de-5a5b-8d9e-752f78720389" -version = "1.0.1" - -[[deps.CRlibm_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" -uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" -version = "1.0.1+0" - -[[deps.CUDA]] -deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "Statistics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "95ac638373ac40e29c1b6d086a3698f5026ff6a6" -uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.1.2" -weakdeps = ["ChainRulesCore", "SpecialFunctions"] - - [deps.CUDA.extensions] - ChainRulesCoreExt = "ChainRulesCore" - SpecialFunctionsExt = "SpecialFunctions" - -[[deps.CUDA_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" -uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.7.0+1" - -[[deps.CUDA_Runtime_Discovery]] -deps = ["Libdl"] -git-tree-sha1 = "bcc4a23cbbd99c8535a5318455dcf0f2546ec536" -uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.2.2" - -[[deps.CUDA_Runtime_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "9704e50c9158cf8896c2776b8dbc5edd136caf80" -uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.10.1+0" - -[[deps.Cairo_jll]] -deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" -uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.16.1+1" - -[[deps.Calculus]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.5.1" - -[[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "c1deebd76f7a443d527fc0430d5758b8b2112ed8" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.19.1" -weakdeps = ["SparseArrays"] - - [deps.ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[deps.ClimaOcean]] -deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] -path = "../.." -uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -version = "0.1.0" - -[[deps.ClimaSeaIce]] -deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" -repo-rev = "main" -repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" -uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.1.0" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.3" - -[[deps.ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - -[[deps.ColorSchemes]] -deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" -uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.24.0" - -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.4" - -[[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.10.0" -weakdeps = ["SpecialFunctions"] - - [deps.ColorVectorSpace.extensions] - SpecialFunctionsExt = "SpecialFunctions" - -[[deps.Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.10" - -[[deps.Combinatorics]] -git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "1.0.2" - -[[deps.CommonDataModel]] -deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf"] -git-tree-sha1 = "7f5717cbb2c1ce650cfd454451f282df33103596" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.2.5" - -[[deps.CommonSolve]] -git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" -uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.4" - -[[deps.CommonSubexpressions]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.0" - -[[deps.Compat]] -deps = ["TOML", "UUIDs"] -git-tree-sha1 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.12.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.5+1" - -[[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 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.3.0" - -[[deps.ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.4" -weakdeps = ["IntervalSets", "StaticArrays"] - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseStaticArraysExt = "StaticArrays" - -[[deps.Contour]] -git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.6.2" - -[[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 = "253193dfb0384646936c5ff3230b27a20d91261e" -uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.2.4" - -[[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 = "d481f6419c262edcb7294179bd63249d123eb081" -uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.12" - -[[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 = "ac67408d9ddf207de5cfa9a97e114352430f01ed" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.16" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.DelaunayTriangulation]] -deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] -git-tree-sha1 = "26eb8e2331b55735c3d305d949aabd7363f07ba7" -uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "0.8.11" - -[[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 = ["OffsetArrays"] -git-tree-sha1 = "1bfa9de80f35ac63c6c381b2d43c590875896a1f" -uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.3.22" - -[[deps.Distances]] -deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.11" -weakdeps = ["ChainRulesCore", "SparseArrays"] - - [deps.Distances.extensions] - DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesSparseArraysExt = "SparseArrays" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[deps.Distributions]] -deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.107" - - [deps.Distributions.extensions] - DistributionsChainRulesCoreExt = "ChainRulesCore" - DistributionsDensityInterfaceExt = "DensityInterface" - DistributionsTestExt = "Test" - - [deps.Distributions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.DocStringExtensions]] -deps = ["LibGit2"] -git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.3" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.DualNumbers]] -deps = ["Calculus", "NaNMath", "SpecialFunctions"] -git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" -uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" -version = "0.6.8" - -[[deps.EarCut_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" -uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" -version = "2.2.4+0" - -[[deps.Elliptic]] -git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" -uuid = "b305315f-e792-5b7a-8f41-49f472929428" -version = "1.0.1" - -[[deps.EnumX]] -git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" -uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" -version = "1.0.4" - -[[deps.ErrorfreeArithmetic]] -git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" -uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" -version = "0.5.2" - -[[deps.ExactPredicates]] -deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] -git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" -uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" -version = "2.2.5" - -[[deps.ExceptionUnwrapping]] -deps = ["Test"] -git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" -uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" -version = "0.1.10" - -[[deps.Expat_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" -uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.5.0+0" - -[[deps.ExprTools]] -git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" -uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.10" - -[[deps.Extents]] -git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" -uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.2" - -[[deps.FFMPEG_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" -uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "4.4.4+1" - -[[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.8.0" - -[[deps.FFTW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" -uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.10+0" - -[[deps.FastRounding]] -deps = ["ErrorfreeArithmetic", "LinearAlgebra"] -git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" -uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" -version = "0.3.1" - -[[deps.FileIO]] -deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.2" - -[[deps.FilePaths]] -deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] -git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" -uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" -version = "0.8.3" - -[[deps.FilePathsBase]] -deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] -git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" -uuid = "48062228-2e41-5def-b9a4-89aafe57970f" -version = "0.9.21" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[deps.FillArrays]] -deps = ["LinearAlgebra", "Random"] -git-tree-sha1 = "5b93957f6dcd33fc343044af3d48c215be2562f1" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.9.3" -weakdeps = ["PDMats", "SparseArrays", "Statistics"] - - [deps.FillArrays.extensions] - FillArraysPDMatsExt = "PDMats" - FillArraysSparseArraysExt = "SparseArrays" - FillArraysStatisticsExt = "Statistics" - -[[deps.FiniteDiff]] -deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "73d1214fec245096717847c62d389a5d2ac86504" -uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.22.0" - - [deps.FiniteDiff.extensions] - FiniteDiffBandedMatricesExt = "BandedMatrices" - FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" - FiniteDiffStaticArraysExt = "StaticArrays" - - [deps.FiniteDiff.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" - -[[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" -uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.93+0" - -[[deps.Formatting]] -deps = ["Printf"] -git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8" -uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" -version = "0.4.2" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.36" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.FreeType]] -deps = ["CEnum", "FreeType2_jll"] -git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "4.1.1" - -[[deps.FreeType2_jll]] -deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" -uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.1+0" - -[[deps.FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] -git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.1" - -[[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" -uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.10+0" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[deps.GLFW]] -deps = ["GLFW_jll"] -git-tree-sha1 = "35dbc482f0967d8dceaa7ce007d16f9064072166" -uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" -version = "3.4.1" - -[[deps.GLFW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] -git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" -uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" -version = "3.3.9+0" - -[[deps.GLMakie]] -deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] -git-tree-sha1 = "e53267e2fc64f81b939849ca7bd70d8f879b5293" -uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -version = "0.9.5" - -[[deps.GPUArrays]] -deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "85d7fb51afb3def5dcb85ad31c3707795c8bccc1" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "9.1.0" - -[[deps.GPUArraysCore]] -deps = ["Adapt"] -git-tree-sha1 = "2d6ca471a6c7b536127afccfa7564b5b39227fe0" -uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.1.5" - -[[deps.GPUCompiler]] -deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] -git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" -uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.25.0" - -[[deps.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.3" - -[[deps.GeometryBasics]] -deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "424a5a6ce7c5d97cca7bcc4eac551b97294c54af" -uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.4.9" - -[[deps.Gettext_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] -git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" -uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" -version = "0.21.0+0" - -[[deps.Glib_jll]] -deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "e94c92c7bf4819685eb80186d51c43e71d4afa17" -uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.76.5+0" - -[[deps.Glob]] -git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" -uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" -version = "1.3.1" - -[[deps.Graphite2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" -uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" -version = "1.3.14+0" - -[[deps.GridLayoutBase]] -deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "af13a277efd8a6e716d79ef635d5342ccb75be61" -uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.10.0" - -[[deps.Grisu]] -git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" -uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" -version = "1.0.2" - -[[deps.HDF5_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] -git-tree-sha1 = "38c8874692d48d5440d5752d6c74b0c6b0b60739" -uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" -version = "1.14.2+1" - -[[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "abbbb9ec3afd783a7cbd82ef01dcd088ea051398" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.1" - -[[deps.HarfBuzz_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] -git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" -uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" -version = "2.8.1+1" - -[[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.10.0+0" - -[[deps.HypergeometricFunctions]] -deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" -uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.23" - -[[deps.IfElse]] -git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" -uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" -version = "0.1.1" - -[[deps.ImageAxes]] -deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] -git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" -uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -version = "0.6.11" - -[[deps.ImageBase]] -deps = ["ImageCore", "Reexport"] -git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" -uuid = "c817782e-172a-44cc-b673-b171935fbb9e" -version = "0.1.7" - -[[deps.ImageCore]] -deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] -git-tree-sha1 = "fc5d1d3443a124fde6e92d0260cd9e064eba69f8" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.10.1" - -[[deps.ImageIO]] -deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] -git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" -uuid = "82e4d734-157c-48bb-816b-45c225c6df19" -version = "0.6.7" - -[[deps.ImageMetadata]] -deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] -git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" -uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" -version = "0.9.9" - -[[deps.Imath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" -uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" -version = "3.1.7+0" - -[[deps.IncompleteLU]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" -uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" -version = "0.2.1" - -[[deps.IndirectArrays]] -git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" -uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" -version = "1.0.0" - -[[deps.Inflate]] -git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.4" - -[[deps.InlineStrings]] -deps = ["Parsers"] -git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.0" - -[[deps.IntegerMathUtils]] -git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" -uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" -version = "0.1.2" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.0.2+0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[deps.Interpolations]] -deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.15.1" - - [deps.Interpolations.extensions] - InterpolationsUnitfulExt = "Unitful" - - [deps.Interpolations.weakdeps] - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - -[[deps.IntervalArithmetic]] -deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] -git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" -uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.20.9" - -[[deps.IntervalSets]] -deps = ["Dates", "Random"] -git-tree-sha1 = "3d8866c029dd6b16e69e0d4a939c4dfcb98fac47" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.8" -weakdeps = ["Statistics"] - - [deps.IntervalSets.extensions] - IntervalSetsStatisticsExt = "Statistics" - -[[deps.InverseFunctions]] -deps = ["Test"] -git-tree-sha1 = "68772f49f54b479fa88ace904f6127f0a3bb2e46" -uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.12" - -[[deps.InvertedIndices]] -git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" -uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" -version = "1.3.0" - -[[deps.IrrationalConstants]] -git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.2" - -[[deps.Isoband]] -deps = ["isoband_jll"] -git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" -uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" -version = "0.1.1" - -[[deps.IterTools]] -git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.10.0" - -[[deps.IterativeSolvers]] -deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] -git-tree-sha1 = "b435d190ef8369cf4d79cc9dd5fba88ba0165307" -uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" -version = "0.9.3" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "7c0008f0b7622c6c0ee5c65cbc667b69f8a65672" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.45" - -[[deps.JLLWrappers]] -deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.5.0" - -[[deps.JSON]] -deps = ["Dates", "Mmap", "Parsers", "Unicode"] -git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.21.4" - -[[deps.JSON3]] -deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] -git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" -uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -version = "1.14.0" - - [deps.JSON3.extensions] - JSON3ArrowExt = ["ArrowTypes"] - - [deps.JSON3.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - -[[deps.JpegTurbo]] -deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] -git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" -uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" -version = "0.1.5" - -[[deps.JpegTurbo_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "60b1194df0a3298f460063de985eae7b01bc011a" -uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.0.1+0" - -[[deps.JuliaNVTXCallbacks_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" -uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" -version = "0.2.1+0" - -[[deps.KernelAbstractions]] -deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "4e0cb2f5aad44dcfdc91088e85dee4ecb22c791c" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.16" - - [deps.KernelAbstractions.extensions] - EnzymeExt = "EnzymeCore" - - [deps.KernelAbstractions.weakdeps] - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - -[[deps.KernelDensity]] -deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.8" - -[[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" -uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.1+0" - -[[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "cb4619f7353fc62a1a22ffa3d7ed9791cfb47ad8" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.4.2" -weakdeps = ["BFloat16s"] - - [deps.LLVM.extensions] - BFloat16sExt = "BFloat16s" - -[[deps.LLVMExtra_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "98eaee04d96d973e79c25d49167668c5c8fb50e2" -uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.27+1" - -[[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.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" -uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.1+0" - -[[deps.LaTeXStrings]] -git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" -uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.3.1" - -[[deps.LazyArtifacts]] -deps = ["Artifacts", "Pkg"] -uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" - -[[deps.LazyModules]] -git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" -uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" -version = "0.3.1" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.0.1+1" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.6.4+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[deps.Libffi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" -uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" -version = "3.2.2+1" - -[[deps.Libgcrypt_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] -git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" -uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.7+0" - -[[deps.Libglvnd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] -git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" -uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" -version = "1.6.0+0" - -[[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" -uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.42.0+0" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.17.0+0" - -[[deps.Libmount_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73" -uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.35.0+0" - -[[deps.Libuuid_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066" -uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.36.0+0" - -[[deps.LightXML]] -deps = ["Libdl", "XML2_jll"] -git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" -uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" -version = "0.9.1" - -[[deps.LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.2.0" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[deps.LinearAlgebraX]] -deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] -git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" -uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" -version = "0.2.7" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.26" - - [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.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.0.0+0" - -[[deps.MPI]] -deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] -git-tree-sha1 = "b4d8707e42b693720b54f0b3434abee6dd4d947a" -uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" -version = "0.20.16" - - [deps.MPI.extensions] - AMDGPUExt = "AMDGPU" - CUDAExt = "CUDA" - - [deps.MPI.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - -[[deps.MPICH_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "2ee75365ca243c1a39d467e35ffd3d4d32eef11e" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.1.2+1" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.10" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "8eeb3c73bbc0ca203d0dc8dad4008350bbe5797b" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.3.1+1" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.13" - -[[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "a37c6610dd20425b131caf65d52abdf859da5ab1" -uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.20.4" - -[[deps.MakieCore]] -deps = ["Observables", "REPL"] -git-tree-sha1 = "ec5db7bb2dc9b85072658dcb2d3ad09569b09ac9" -uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.7.2" - -[[deps.MappedArrays]] -git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.2" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[deps.MathTeXEngine]] -deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] -git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" -uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.5.7" - -[[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.9" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+1" - -[[deps.MeshIO]] -deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] -git-tree-sha1 = "8be09d84a2d597c7c0c34d7d604c039c9763e48c" -uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" -version = "0.4.10" - -[[deps.MicrosoftMPI_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "b01beb91d20b0d1312a9471a36017b5b339d26de" -uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" -version = "10.1.4+1" - -[[deps.Missings]] -deps = ["DataAPI"] -git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.1.0" - -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[deps.ModernGL]] -deps = ["Libdl"] -git-tree-sha1 = "b76ea40b5c0f45790ae09492712dd326208c28b2" -uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" -version = "1.1.7" - -[[deps.Mods]] -git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" -uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" -version = "2.2.4" - -[[deps.MosaicViews]] -deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] -git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" -uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" -version = "0.3.4" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.1.10" - -[[deps.Multisets]] -git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" -uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" -version = "0.4.4" - -[[deps.NCDatasets]] -deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "173a378f357e9bb24b22019efb5e4778223ce8cf" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.13.2" - -[[deps.NLSolversBase]] -deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] -git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.8.3" - -[[deps.NVTX]] -deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] -git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" -uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" -version = "0.3.4" - -[[deps.NVTX_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" -uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" -version = "3.1.0+2" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.0.2" - -[[deps.NetCDF_jll]] -deps = ["Artifacts", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "XML2_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "10c612c81eaffdd6b7c28a45a554cdd9d2f40ff1" -uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" -version = "400.902.208+0" - -[[deps.Netpbm]] -deps = ["FileIO", "ImageCore", "ImageMetadata"] -git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" -uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" -version = "1.1.1" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.Observables]] -git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.5.5" - -[[deps.Oceananigans]] -deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "6e05bd0bf05a8f9fc09c8cc387d0160d0724e014" -repo-rev = "ss-glw/time-bcs" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" -uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.7" - - [deps.Oceananigans.extensions] - OceananigansEnzymeExt = "Enzyme" - - [deps.Oceananigans.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - -[[deps.OffsetArrays]] -git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.13.0" -weakdeps = ["Adapt"] - - [deps.OffsetArrays.extensions] - OffsetArraysAdaptExt = "Adapt" - -[[deps.Ogg_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" -uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" -version = "1.3.5+1" - -[[deps.OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.23+2" - -[[deps.OpenEXR]] -deps = ["Colors", "FileIO", "OpenEXR_jll"] -git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" -uuid = "52e1d378-f018-4a11-a4be-720524705ac7" -version = "0.3.2" - -[[deps.OpenEXR_jll]] -deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" -uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.1.4+0" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+2" - -[[deps.OpenMPI_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] -git-tree-sha1 = "1d1421618bab0e820bdc7ae1a2b46ce576981273" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.1+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.1" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.12+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.Optim]] -deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.7.8" - -[[deps.Opus_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" -uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.3.2+0" - -[[deps.OrderedCollections]] -git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.3" - -[[deps.PCRE2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.42.0+1" - -[[deps.PDMats]] -deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.31" - -[[deps.PMIx_jll]] -deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] -git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" -uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" -version = "4.2.7+0" - -[[deps.PNGFiles]] -deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] -git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" -uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" -version = "0.4.3" - -[[deps.PackageExtensionCompat]] -git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" -uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" -version = "1.0.2" -weakdeps = ["Requires", "TOML"] - -[[deps.Packing]] -deps = ["GeometryBasics"] -git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.5.0" - -[[deps.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[deps.Parameters]] -deps = ["OrderedCollections", "UnPack"] -git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.12.3" - -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.1" - -[[deps.PencilArrays]] -deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] -git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" -uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.3" - - [deps.PencilArrays.extensions] - PencilArraysDiffEqExt = ["DiffEqBase"] - PencilArraysHDF5Ext = ["HDF5"] - - [deps.PencilArrays.weakdeps] - DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" - HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" - -[[deps.PencilFFTs]] -deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] -git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" -uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" -version = "0.15.1" - -[[deps.Permutations]] -deps = ["Combinatorics", "LinearAlgebra", "Random"] -git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" -uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" -version = "0.4.20" - -[[deps.PikaParser]] -deps = ["DocStringExtensions"] -git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" -uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" -version = "0.6.1" - -[[deps.Pixman_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" -uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.42.2+0" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.10.0" - -[[deps.PkgVersion]] -deps = ["Pkg"] -git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" -uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.3" - -[[deps.PlotUtils]] -deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] -git-tree-sha1 = "862942baf5663da528f66d24996eb6da85218e76" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.4.0" - -[[deps.PolygonOps]] -git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" -uuid = "647866c9-e3ac-4575-94e7-e3d426903924" -version = "0.1.2" - -[[deps.Polynomials]] -deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "4.0.6" - - [deps.Polynomials.extensions] - PolynomialsChainRulesCoreExt = "ChainRulesCore" - PolynomialsFFTWExt = "FFTW" - PolynomialsMakieCoreExt = "MakieCore" - PolynomialsMutableArithmeticsExt = "MutableArithmetics" - - [deps.Polynomials.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" - MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" - MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" - -[[deps.PooledArrays]] -deps = ["DataAPI", "Future"] -git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" -uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "1.4.3" - -[[deps.PositiveFactorizations]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.4" - -[[deps.PrecompileTools]] -deps = ["Preferences"] -git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.0" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.1" - -[[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" -uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.3.1" - -[[deps.Primes]] -deps = ["IntegerMathUtils"] -git-tree-sha1 = "1d05623b5952aed1307bf8b43bec8b8d1ef94b6e" -uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.5.5" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[deps.ProgressBars]] -deps = ["Printf"] -git-tree-sha1 = "b437cdb0385ed38312d91d9c00c20f3798b30256" -uuid = "49802e3a-d2f1-5c88-81d8-b72133a6f568" -version = "1.5.1" - -[[deps.ProgressMeter]] -deps = ["Distributed", "Printf"] -git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" -uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.9.0" - -[[deps.QOI]] -deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] -git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" -uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" -version = "1.0.0" - -[[deps.QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.9.4" - -[[deps.Quaternions]] -deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "9a46862d248ea548e340e30e2894118749dc7f51" -uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.5" - -[[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 = "c860e84651f58ce240dd79e5d9e055d55234c35a" -uuid = "74087812-796a-5b5d-8853-05524746bad3" -version = "1.6.2" - -[[deps.RandomNumbers]] -deps = ["Random", "Requires"] -git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111" -uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" -version = "1.5.3" - -[[deps.RangeArrays]] -git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" -uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" -version = "0.3.2" - -[[deps.Ratios]] -deps = ["Requires"] -git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.4.5" -weakdeps = ["FixedPointNumbers"] - - [deps.Ratios.extensions] - RatiosFixedPointNumbersExt = "FixedPointNumbers" - -[[deps.RealDot]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" -uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" -version = "0.1.0" - -[[deps.RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.RelocatableFolders]] -deps = ["SHA", "Scratch"] -git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" -uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.1" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.0" - -[[deps.RingLists]] -deps = ["Random"] -git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" -uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" -version = "0.2.8" - -[[deps.Rmath]] -deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.7.1" - -[[deps.Rmath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.0+0" - -[[deps.RootSolvers]] -deps = ["ForwardDiff"] -git-tree-sha1 = "833d9914e748ca9329b762a82ec912897975f8d8" -uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" -version = "0.4.1" - -[[deps.Roots]] -deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] -git-tree-sha1 = "af540898b1e6ca7aa6ba7213c05052809c6c522a" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.1.0" - - [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 = "792d8fd4ad770b6d517a13ebb8dadfcac79405b8" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.6.1" - -[[deps.RoundingEmulator]] -git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" -uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" -version = "0.2.1" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.Scratch]] -deps = ["Dates"] -git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" -uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.2.1" - -[[deps.SeawaterPolynomials]] -git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" -repo-rev = "glw/heat-capacity" -repo-url = "https://github.com/CliMA/SeawaterPolynomials.jl.git" -uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" -version = "0.3.4" - -[[deps.SentinelArrays]] -deps = ["Dates", "Random"] -git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" -uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.1" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.SetRounding]] -git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" -uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" -version = "0.2.1" - -[[deps.Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.1" - -[[deps.ShaderAbstractions]] -deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "db0219befe4507878b1a90e07820fed3e62c289d" -uuid = "65257c39-d410-5151-9873-9b3e5be5013e" -version = "0.4.0" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[deps.Showoff]] -deps = ["Dates", "Grisu"] -git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "1.0.3" - -[[deps.SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - -[[deps.SimpleBufferStream]] -git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.1.0" - -[[deps.SimpleGraphs]] -deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] -git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" -uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" -version = "0.8.6" - -[[deps.SimplePartitions]] -deps = ["AbstractLattices", "DataStructures", "Permutations"] -git-tree-sha1 = "e9330391d04241eafdc358713b48396619c83bcb" -uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" -version = "0.3.1" - -[[deps.SimplePolynomials]] -deps = ["Mods", "Multisets", "Polynomials", "Primes"] -git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" -uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" -version = "0.2.17" - -[[deps.SimpleRandom]] -deps = ["Distributions", "LinearAlgebra", "Random"] -git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" -uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" -version = "0.3.1" - -[[deps.SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" - -[[deps.Sixel]] -deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] -git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" -uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" -version = "0.1.3" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[deps.SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.10.0" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.1" -weakdeps = ["ChainRulesCore"] - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - -[[deps.StableHashTraits]] -deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] -git-tree-sha1 = "662f56ffe22b3985f3be7474f0aecbaf214ecf0f" -uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" -version = "1.1.6" - -[[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 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" -uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "0.8.8" - -[[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 = "f68dd04d131d9a8a8eb836173ee8f105c360b0c5" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.1" -weakdeps = ["ChainRulesCore", "Statistics"] - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.2" - -[[deps.StaticPermutations]] -git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" -uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" -version = "0.3.0" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.0" - -[[deps.StatsBase]] -deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.2" - -[[deps.StatsFuns]] -deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.3.0" -weakdeps = ["ChainRulesCore", "InverseFunctions"] - - [deps.StatsFuns.extensions] - StatsFunsChainRulesCoreExt = "ChainRulesCore" - StatsFunsInverseFunctionsExt = "InverseFunctions" - -[[deps.Strided]] -deps = ["LinearAlgebra", "StridedViews", "TupleTools"] -git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" -uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" -version = "2.0.4" - -[[deps.StridedViews]] -deps = ["LinearAlgebra", "PackageExtensionCompat"] -git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" -uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" -version = "0.2.2" -weakdeps = ["CUDA"] - - [deps.StridedViews.extensions] - StridedViewsCUDAExt = "CUDA" - -[[deps.StringManipulation]] -deps = ["PrecompileTools"] -git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" -uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.3.4" - -[[deps.StructArrays]] -deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "1b0b1205a56dc288b71b1961d48e351520702e24" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.17" - -[[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", "Pkg", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.0+1" - -[[deps.SurfaceFluxes]] -deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "6431256ee7c06ed2900fd46688f355e5a43e90eb" -uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.9.1" - - [deps.SurfaceFluxes.extensions] - CreateParametersExt = "CLIMAParameters" - - [deps.SurfaceFluxes.weakdeps] - CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.1" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[deps.TaylorSeries]] -deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] -git-tree-sha1 = "9138fdc8ee4e3b8839eca696a76d15e16c9c7af0" -uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.15.4" -weakdeps = ["IntervalArithmetic"] - - [deps.TaylorSeries.extensions] - TaylorSeriesIAExt = "IntervalArithmetic" - -[[deps.TensorCore]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" -uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" -version = "0.1.1" - -[[deps.Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.Thermodynamics]] -deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "f4555e1302df12011b836fbdcdd3e10e5df7329a" -repo-rev = "glw/density-example" -repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" -uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.11.5" - - [deps.Thermodynamics.extensions] - CreateParametersExt = "CLIMAParameters" - - [deps.Thermodynamics.weakdeps] - CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" - -[[deps.TiffImages]] -deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] -git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" -uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.6.8" - -[[deps.TimerOutputs]] -deps = ["ExprTools", "Printf"] -git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" -uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" -version = "0.5.23" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.2" -weakdeps = ["Random", "Test"] - - [deps.TranscodingStreams.extensions] - TestExt = ["Test", "Random"] - -[[deps.TriplotBase]] -git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" -uuid = "981d1d27-644d-49a2-9326-4793e63143c3" -version = "0.1.0" - -[[deps.TupleTools]] -git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" -uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" -version = "1.4.3" - -[[deps.URIs]] -git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" -uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.5.1" - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[deps.UnicodeFun]] -deps = ["REPL"] -git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.1" - -[[deps.UnsafeAtomics]] -git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" -uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" -version = "0.2.1" - -[[deps.UnsafeAtomicsLLVM]] -deps = ["LLVM", "UnsafeAtomics"] -git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" -uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" -version = "0.1.3" - -[[deps.VersionParsing]] -git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" -uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" -version = "1.3.0" - -[[deps.WoodburyMatrices]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "1.0.0" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.2+0" - -[[deps.XSLT_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] -git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" -uuid = "aed1982a-8fda-507f-9586-7b0439959a61" -version = "1.1.34+0" - -[[deps.Xorg_libX11_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] -git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" -uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" -version = "1.8.6+0" - -[[deps.Xorg_libXau_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" -uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" -version = "1.0.11+0" - -[[deps.Xorg_libXcursor_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] -git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" -uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" -version = "1.2.0+4" - -[[deps.Xorg_libXdmcp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" -uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" -version = "1.1.4+0" - -[[deps.Xorg_libXext_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" -uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.4+4" - -[[deps.Xorg_libXfixes_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" -uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" -version = "5.0.3+4" - -[[deps.Xorg_libXi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] -git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" -uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" -version = "1.7.10+4" - -[[deps.Xorg_libXinerama_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] -git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" -uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" -version = "1.1.4+4" - -[[deps.Xorg_libXrandr_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] -git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" -uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" -version = "1.5.2+4" - -[[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" -uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.10+4" - -[[deps.Xorg_libpthread_stubs_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" -uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" -version = "0.1.1+0" - -[[deps.Xorg_libxcb_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] -git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" -uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.15.0+0" - -[[deps.Xorg_xtrans_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" -uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" -version = "1.5.0+0" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+1" - -[[deps.Zstd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.5+0" - -[[deps.isoband_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" -uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" -version = "0.2.3+0" - -[[deps.libaec_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "eddd19a8dea6b139ea97bdc8a0e2667d4b661720" -uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.0.6+1" - -[[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" -uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.4.0+0" - -[[deps.libass_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" -uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" -version = "0.15.1+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+1" - -[[deps.libevent_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll"] -git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" -uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" -version = "2.1.13+1" - -[[deps.libfdk_aac_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" -uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" -version = "2.0.2+0" - -[[deps.libpng_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "93284c28274d9e75218a416c65ec49d0e0fcdf3d" -uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.40+0" - -[[deps.libsixel_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] -git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" -uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" -version = "1.10.3+0" - -[[deps.libvorbis_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] -git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" -uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.7+1" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" - -[[deps.prrte_jll]] -deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_jll"] -git-tree-sha1 = "5adb2d7a18a30280feb66cad6f1a1dfdca2dc7b0" -uuid = "eb928a42-fffd-568d-ab9c-3f5d54fc65b9" -version = "3.0.2+0" - -[[deps.x264_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" -uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" -version = "2021.5.5+0" - -[[deps.x265_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" -uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" -version = "3.5.0+0" From 08c094deb9c79acb72bb9848a041652c8da8919f Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 28 Feb 2024 07:09:01 -0700 Subject: [PATCH 152/182] Clean up omip components --- .../omip_components.jl | 73 +------------------ 1 file changed, 3 insertions(+), 70 deletions(-) diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl index fa3f2ea9..9f354bcb 100644 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -15,39 +15,6 @@ using KernelAbstractions: @kernel, @index using SeawaterPolynomials.TEOS10: TEOS10EquationOfState -#= -Nf = length(other_fields) -ft = ntuple(Nf) do n - fe = other_fields[n] - interior(fe)[land] .= NaN -end -=# - -#= -i₁ = 4 * first(longitude) + 1 -i₂ = 1440 - 4 * (360 - last(longitude)) -i₂ > i₁ || error("longitude $longitude is invalid.") -Nx = i₂ - i₁ + 1 - -j₁ = 4 * (90 + first(latitude)) + 1 -j₂ = 720 - 4 * (90 - last(latitude)) -j₂ > j₁ || error("latitude $latitude is invalid.") -Ny = j₂ - j₁ + 1 -=# -#= -Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) -bottom_height = - Inf .* ones(Nx, Ny) -for i = 1:Nx, j = 1:Ny - for k = Nz:-1:1 - if isnan(Tᵢ[i, j, k]) - bottom_height[i, j] = znode(i, j, k+1, grid, c, c, f) - break - end - end -end -Tᵢ = arch_array(arch, Tᵢ) -=# - function regional_omip_grid(arch, ecco_2_temperature_field; latitude, longitude = (0, 360), @@ -81,16 +48,6 @@ function regional_omip_grid(arch, ecco_2_temperature_field; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - #= - Nf = length(other_fields) - ft = ntuple(Nf) do n - fe = other_fields[n] - fᵢ = interior(fe, i₁:i₂, j₁:j₂, :) - fᵢ = arch_array(arch, fᵢ) - end - all_fields = tuple(Tᵢ, ft...) - =# - elapsed = 1e-9 * (time_ns() - start_time) @info string("Grid for regional omip simulation generated in ", prettytime(elapsed), ".") @show grid @@ -134,33 +91,8 @@ function omip_ocean_component(grid; if closure == :default - CᵂwΔ = 0.42488 - Cᵂu★ = 0.77035 - CʰⁱD = 1.32927 - CˡᵒD = 1.78434 - CᶜD = 1.77713 - Cᵂϵ = 1.0 - - turbulent_kinetic_energy_equation = - TurbulentKineticEnergyEquation(; Cᵂϵ, CᵂwΔ, Cᵂu★, CˡᵒD, CʰⁱD, CᶜD) - - Cʰⁱc = 0.35506 - Cʰⁱu = 0.73705 - Cʰⁱe = 2.95645 - Cˢ = 1.51574 - Cˡᵒc = 0.70216 - Cˡᵒu = 0.41751 - Cˡᵒe = 2.12289 - CRi⁰ = 0.31406 - CRiᵟ = 0.31180 - Cᶜc = 1.42944 - Cᶜe = 0.52468 - Cᵉc = 0.84486 - Cˢᵖ = 0.46480 - Cᵇ = 0.01 - - mixing_length = MixingLength(; Cʰⁱc, Cʰⁱu, Cʰⁱe, Cˢ, Cᵇ, Cˡᵒc, - Cˡᵒu, Cˡᵒe, CRi⁰, CRiᵟ, Cᶜc, Cᶜe, Cᵉc, Cˢᵖ) + turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + mixing_length = MixingLength(Cᵇ=0.01) closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation, @@ -270,3 +202,4 @@ end T[i, j, k] = ifelse(land, NaN, Tᵢ) end end + From b19b658802d033acc95d4dad24b5d3f80d24d963 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 28 Mar 2024 09:52:54 +0200 Subject: [PATCH 153/182] nuke docs/Manifest --- docs/Manifest.toml | 1679 -------------------------------------------- 1 file changed, 1679 deletions(-) delete mode 100644 docs/Manifest.toml diff --git a/docs/Manifest.toml b/docs/Manifest.toml deleted file mode 100644 index fdaa9287..00000000 --- a/docs/Manifest.toml +++ /dev/null @@ -1,1679 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.0-rc1" -manifest_format = "2.0" -project_hash = "4e6ca4de68bac0b84c76f90007adaa3ea49cb0ea" - -[[deps.ANSIColoredPrinters]] -git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" -uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" -version = "0.0.1" - -[[deps.AbstractFFTs]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.5.0" -weakdeps = ["ChainRulesCore", "Test"] - - [deps.AbstractFFTs.extensions] - AbstractFFTsChainRulesCoreExt = "ChainRulesCore" - AbstractFFTsTestExt = "Test" - -[[deps.AbstractLattices]] -git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" -uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" -version = "0.3.0" - -[[deps.AbstractTrees]] -git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" -uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" -version = "0.4.4" - -[[deps.Adapt]] -deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "0fb305e0253fd4e833d486914367a2ee2c2e78d0" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.0.1" -weakdeps = ["StaticArrays"] - - [deps.Adapt.extensions] - AdaptStaticArraysExt = "StaticArrays" - -[[deps.Animations]] -deps = ["Colors"] -git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" -uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" -version = "0.4.1" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "bbec08a37f8722786d87bedf84eae19c020c4efa" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.7.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - 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" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" - -[[deps.Automa]] -deps = ["PrecompileTools", "TranscodingStreams"] -git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" -uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "1.0.3" - -[[deps.AxisAlgorithms]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] -git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "1.1.0" - -[[deps.AxisArrays]] -deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] -git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" -uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" -version = "0.4.7" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[deps.BitFlags]] -git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.8" - -[[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.CRC32c]] -uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" - -[[deps.CRlibm]] -deps = ["CRlibm_jll"] -git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" -uuid = "96374032-68de-5a5b-8d9e-752f78720389" -version = "1.0.1" - -[[deps.CRlibm_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" -uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" -version = "1.0.1+0" - -[[deps.Cairo]] -deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] -git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b" -uuid = "159f3aea-2a34-519c-b102-8c37f9878175" -version = "1.0.5" - -[[deps.CairoMakie]] -deps = ["Base64", "Cairo", "Colors", "FFTW", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools", "SHA"] -git-tree-sha1 = "5e21a254d82c64b1a4ed9dbdc7e87c5d9cf4a686" -uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.10.12" - -[[deps.Cairo_jll]] -deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" -uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.16.1+1" - -[[deps.Calculus]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.5.1" - -[[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "c1deebd76f7a443d527fc0430d5758b8b2112ed8" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.19.1" -weakdeps = ["SparseArrays"] - - [deps.ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.3" - -[[deps.ColorBrewer]] -deps = ["Colors", "JSON", "Test"] -git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" -uuid = "a2cac450-b92f-5266-8821-25eda20663c8" -version = "0.4.0" - -[[deps.ColorSchemes]] -deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" -uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.24.0" - -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.4" - -[[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.10.0" -weakdeps = ["SpecialFunctions"] - - [deps.ColorVectorSpace.extensions] - SpecialFunctionsExt = "SpecialFunctions" - -[[deps.Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.10" - -[[deps.Combinatorics]] -git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "1.0.2" - -[[deps.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 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.12.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.5+1" - -[[deps.ConcurrentUtilities]] -deps = ["Serialization", "Sockets"] -git-tree-sha1 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.3.0" - -[[deps.ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.4" -weakdeps = ["IntervalSets", "StaticArrays"] - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseStaticArraysExt = "StaticArrays" - -[[deps.Contour]] -git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.6.2" - -[[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 = "d481f6419c262edcb7294179bd63249d123eb081" -uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.12" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "ac67408d9ddf207de5cfa9a97e114352430f01ed" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.16" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.DelaunayTriangulation]] -deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] -git-tree-sha1 = "26eb8e2331b55735c3d305d949aabd7363f07ba7" -uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "0.8.11" - -[[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.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[deps.Distributions]] -deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.107" - - [deps.Distributions.extensions] - DistributionsChainRulesCoreExt = "ChainRulesCore" - DistributionsDensityInterfaceExt = "DensityInterface" - DistributionsTestExt = "Test" - - [deps.Distributions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.DocStringExtensions]] -deps = ["LibGit2"] -git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.3" - -[[deps.Documenter]] -deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "Test", "Unicode"] -git-tree-sha1 = "2613dbec8f4748273bbe30ba71fd5cb369966bac" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.2.1" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.DualNumbers]] -deps = ["Calculus", "NaNMath", "SpecialFunctions"] -git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" -uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" -version = "0.6.8" - -[[deps.EarCut_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" -uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" -version = "2.2.4+0" - -[[deps.EnumX]] -git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" -uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" -version = "1.0.4" - -[[deps.ExactPredicates]] -deps = ["IntervalArithmetic", "Random", "StaticArrays"] -git-tree-sha1 = "e8b8c949551f417e040f16e5c431b6e83e306e54" -uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" -version = "2.2.7" - -[[deps.ExceptionUnwrapping]] -deps = ["Test"] -git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" -uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" -version = "0.1.10" - -[[deps.Expat_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" -uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.5.0+0" - -[[deps.Extents]] -git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" -uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.2" - -[[deps.FFMPEG_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" -uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "4.4.4+1" - -[[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 = "c5c28c245101bd59154f649e19b038d15901b5dc" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.2" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[deps.FillArrays]] -deps = ["LinearAlgebra", "Random"] -git-tree-sha1 = "5b93957f6dcd33fc343044af3d48c215be2562f1" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.9.3" -weakdeps = ["PDMats", "SparseArrays", "Statistics"] - - [deps.FillArrays.extensions] - FillArraysPDMatsExt = "PDMats" - FillArraysSparseArraysExt = "SparseArrays" - FillArraysStatisticsExt = "Statistics" - -[[deps.FiniteDiff]] -deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "73d1214fec245096717847c62d389a5d2ac86504" -uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.22.0" - - [deps.FiniteDiff.extensions] - FiniteDiffBandedMatricesExt = "BandedMatrices" - FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" - FiniteDiffStaticArraysExt = "StaticArrays" - - [deps.FiniteDiff.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" - -[[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" -uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.93+0" - -[[deps.Formatting]] -deps = ["Printf"] -git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8" -uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" -version = "0.4.2" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.36" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.FreeType]] -deps = ["CEnum", "FreeType2_jll"] -git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" -uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" -version = "4.1.1" - -[[deps.FreeType2_jll]] -deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" -uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.1+0" - -[[deps.FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] -git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.1" - -[[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" -uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.10+0" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[deps.GPUArraysCore]] -deps = ["Adapt"] -git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" -uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.1.6" - -[[deps.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.3" - -[[deps.GeometryBasics]] -deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "424a5a6ce7c5d97cca7bcc4eac551b97294c54af" -uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.4.9" - -[[deps.Gettext_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] -git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" -uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" -version = "0.21.0+0" - -[[deps.Git]] -deps = ["Git_jll"] -git-tree-sha1 = "51764e6c2e84c37055e846c516e9015b4a291c7d" -uuid = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2" -version = "1.3.0" - -[[deps.Git_jll]] -deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "b30c473c97fcc1e1e44fab8f3e88fd1b89c9e9d1" -uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb" -version = "2.43.0+0" - -[[deps.Glib_jll]] -deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "e94c92c7bf4819685eb80186d51c43e71d4afa17" -uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.76.5+0" - -[[deps.Graphics]] -deps = ["Colors", "LinearAlgebra", "NaNMath"] -git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" -uuid = "a2bd30eb-e257-5431-a919-1863eab51364" -version = "1.1.2" - -[[deps.Graphite2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" -uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" -version = "1.3.14+0" - -[[deps.GridLayoutBase]] -deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" -uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.9.2" - -[[deps.Grisu]] -git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" -uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" -version = "1.0.2" - -[[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "abbbb9ec3afd783a7cbd82ef01dcd088ea051398" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.1" - -[[deps.HarfBuzz_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] -git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" -uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" -version = "2.8.1+1" - -[[deps.HypergeometricFunctions]] -deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" -uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.23" - -[[deps.IOCapture]] -deps = ["Logging", "Random"] -git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c" -uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.4" - -[[deps.ImageAxes]] -deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] -git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" -uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" -version = "0.6.11" - -[[deps.ImageBase]] -deps = ["ImageCore", "Reexport"] -git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" -uuid = "c817782e-172a-44cc-b673-b171935fbb9e" -version = "0.1.7" - -[[deps.ImageCore]] -deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] -git-tree-sha1 = "fc5d1d3443a124fde6e92d0260cd9e064eba69f8" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.10.1" - -[[deps.ImageIO]] -deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] -git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" -uuid = "82e4d734-157c-48bb-816b-45c225c6df19" -version = "0.6.7" - -[[deps.ImageMetadata]] -deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] -git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" -uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" -version = "0.9.9" - -[[deps.Imath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" -uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" -version = "3.1.7+0" - -[[deps.IndirectArrays]] -git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" -uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" -version = "1.0.0" - -[[deps.Inflate]] -git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.4" - -[[deps.IntegerMathUtils]] -git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" -uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" -version = "0.1.2" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.0.2+0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[deps.Interpolations]] -deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" -uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.15.1" - - [deps.Interpolations.extensions] - InterpolationsUnitfulExt = "Unitful" - - [deps.Interpolations.weakdeps] - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - -[[deps.IntervalArithmetic]] -deps = ["CRlibm", "RoundingEmulator"] -git-tree-sha1 = "c274ec586ea58eb7b42afd0c5d67e50ff50229b5" -uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.5" -weakdeps = ["DiffRules", "RecipesBase"] - - [deps.IntervalArithmetic.extensions] - IntervalArithmeticDiffRulesExt = "DiffRules" - IntervalArithmeticRecipesBaseExt = "RecipesBase" - -[[deps.IntervalSets]] -deps = ["Dates", "Random"] -git-tree-sha1 = "3d8866c029dd6b16e69e0d4a939c4dfcb98fac47" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.8" -weakdeps = ["Statistics"] - - [deps.IntervalSets.extensions] - IntervalSetsStatisticsExt = "Statistics" - -[[deps.IrrationalConstants]] -git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.2" - -[[deps.Isoband]] -deps = ["isoband_jll"] -git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" -uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" -version = "0.1.1" - -[[deps.IterTools]] -git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.10.0" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[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.JpegTurbo]] -deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] -git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" -uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" -version = "0.1.5" - -[[deps.JpegTurbo_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "60b1194df0a3298f460063de985eae7b01bc011a" -uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.0.1+0" - -[[deps.KernelDensity]] -deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.8" - -[[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" -uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.1+0" - -[[deps.LLVMOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" -uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "15.0.7+0" - -[[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" -uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.1+0" - -[[deps.LaTeXStrings]] -git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" -uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.3.1" - -[[deps.LazilyInitializedFields]] -git-tree-sha1 = "8f7f3cabab0fd1800699663533b6d5cb3fc0e612" -uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf" -version = "1.2.2" - -[[deps.LazyArtifacts]] -deps = ["Artifacts", "Pkg"] -uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" - -[[deps.LazyModules]] -git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" -uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" -version = "0.3.1" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.4.0+0" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.6.4+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[deps.Libffi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" -uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" -version = "3.2.2+1" - -[[deps.Libgcrypt_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] -git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" -uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.7+0" - -[[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" -uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.42.0+0" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.17.0+0" - -[[deps.Libmount_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73" -uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.35.0+0" - -[[deps.Libuuid_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066" -uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.36.0+0" - -[[deps.LightXML]] -deps = ["Libdl", "XML2_jll"] -git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" -uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" -version = "0.9.1" - -[[deps.LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.2.0" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[deps.LinearAlgebraX]] -deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] -git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" -uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" -version = "0.2.7" - -[[deps.Literate]] -deps = ["Base64", "IOCapture", "JSON", "REPL"] -git-tree-sha1 = "bad26f1ccd99c553886ec0725e99a509589dcd11" -uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -version = "2.16.1" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.26" - - [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.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.0.0+0" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.13" - -[[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "35fa3c150cd96fd77417a23965b7037b90d6ffc9" -uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.19.12" - -[[deps.MakieCore]] -deps = ["Observables", "REPL"] -git-tree-sha1 = "9b11acd07f21c4d035bd4156e789532e8ee2cc70" -uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.6.9" - -[[deps.MappedArrays]] -git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.2" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[deps.MarkdownAST]] -deps = ["AbstractTrees", "Markdown"] -git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" -uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" -version = "0.1.2" - -[[deps.MathTeXEngine]] -deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] -git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" -uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.5.7" - -[[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.9" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+1" - -[[deps.Missings]] -deps = ["DataAPI"] -git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.1.0" - -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[deps.Mods]] -git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" -uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" -version = "2.2.4" - -[[deps.MosaicViews]] -deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] -git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" -uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" -version = "0.3.4" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.1.10" - -[[deps.Multisets]] -git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" -uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" -version = "0.4.4" - -[[deps.NLSolversBase]] -deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] -git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.8.3" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.0.2" - -[[deps.Netpbm]] -deps = ["FileIO", "ImageCore", "ImageMetadata"] -git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" -uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" -version = "1.1.1" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.Observables]] -git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" -uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.5.5" - -[[deps.OffsetArrays]] -git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.13.0" -weakdeps = ["Adapt"] - - [deps.OffsetArrays.extensions] - OffsetArraysAdaptExt = "Adapt" - -[[deps.Ogg_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" -uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" -version = "1.3.5+1" - -[[deps.OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.23+2" - -[[deps.OpenEXR]] -deps = ["Colors", "FileIO", "OpenEXR_jll"] -git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" -uuid = "52e1d378-f018-4a11-a4be-720524705ac7" -version = "0.3.2" - -[[deps.OpenEXR_jll]] -deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" -uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.1.4+0" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+2" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.1" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.12+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.Optim]] -deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.7.8" - -[[deps.Opus_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" -uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.3.2+0" - -[[deps.OrderedCollections]] -git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.3" - -[[deps.PCRE2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.42.0+1" - -[[deps.PDMats]] -deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.31" - -[[deps.PNGFiles]] -deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] -git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" -uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" -version = "0.4.3" - -[[deps.Packing]] -deps = ["GeometryBasics"] -git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" -uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" -version = "0.5.0" - -[[deps.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[deps.Pango_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4745216e94f71cb768d58330b059c9b76f32cb66" -uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.50.14+0" - -[[deps.Parameters]] -deps = ["OrderedCollections", "UnPack"] -git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.12.3" - -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.1" - -[[deps.Permutations]] -deps = ["Combinatorics", "LinearAlgebra", "Random"] -git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" -uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" -version = "0.4.20" - -[[deps.PikaParser]] -deps = ["DocStringExtensions"] -git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" -uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" -version = "0.6.1" - -[[deps.Pixman_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" -uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.42.2+0" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.10.0" - -[[deps.PkgVersion]] -deps = ["Pkg"] -git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" -uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.3" - -[[deps.PlotUtils]] -deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] -git-tree-sha1 = "862942baf5663da528f66d24996eb6da85218e76" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.4.0" - -[[deps.PolygonOps]] -git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" -uuid = "647866c9-e3ac-4575-94e7-e3d426903924" -version = "0.1.2" - -[[deps.Polynomials]] -deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "4.0.6" - - [deps.Polynomials.extensions] - PolynomialsChainRulesCoreExt = "ChainRulesCore" - PolynomialsFFTWExt = "FFTW" - PolynomialsMakieCoreExt = "MakieCore" - PolynomialsMutableArithmeticsExt = "MutableArithmetics" - - [deps.Polynomials.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" - MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" - MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" - -[[deps.PositiveFactorizations]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.4" - -[[deps.PrecompileTools]] -deps = ["Preferences"] -git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.0" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.1" - -[[deps.Primes]] -deps = ["IntegerMathUtils"] -git-tree-sha1 = "1d05623b5952aed1307bf8b43bec8b8d1ef94b6e" -uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.5.5" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[deps.ProgressMeter]] -deps = ["Distributed", "Printf"] -git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" -uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.9.0" - -[[deps.QOI]] -deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] -git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" -uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" -version = "1.0.0" - -[[deps.QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.9.4" - -[[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[deps.RangeArrays]] -git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" -uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" -version = "0.3.2" - -[[deps.Ratios]] -deps = ["Requires"] -git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" -uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" -version = "0.4.5" -weakdeps = ["FixedPointNumbers"] - - [deps.Ratios.extensions] - RatiosFixedPointNumbersExt = "FixedPointNumbers" - -[[deps.RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.RegistryInstances]] -deps = ["LazilyInitializedFields", "Pkg", "TOML", "Tar"] -git-tree-sha1 = "ffd19052caf598b8653b99404058fce14828be51" -uuid = "2792f1a3-b283-48e8-9a74-f99dce5104f3" -version = "0.1.0" - -[[deps.RelocatableFolders]] -deps = ["SHA", "Scratch"] -git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" -uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.1" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.0" - -[[deps.RingLists]] -deps = ["Random"] -git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" -uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" -version = "0.2.8" - -[[deps.Rmath]] -deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.7.1" - -[[deps.Rmath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.0+0" - -[[deps.RoundingEmulator]] -git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" -uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" -version = "0.2.1" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.Scratch]] -deps = ["Dates"] -git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" -uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.2.1" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.1" - -[[deps.ShaderAbstractions]] -deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "db0219befe4507878b1a90e07820fed3e62c289d" -uuid = "65257c39-d410-5151-9873-9b3e5be5013e" -version = "0.4.0" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[deps.Showoff]] -deps = ["Dates", "Grisu"] -git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "1.0.3" - -[[deps.SignedDistanceFields]] -deps = ["Random", "Statistics", "Test"] -git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" -uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" -version = "0.4.0" - -[[deps.SimpleBufferStream]] -git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.1.0" - -[[deps.SimpleGraphs]] -deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] -git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" -uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" -version = "0.8.6" - -[[deps.SimplePartitions]] -deps = ["AbstractLattices", "DataStructures", "Permutations"] -git-tree-sha1 = "e9330391d04241eafdc358713b48396619c83bcb" -uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" -version = "0.3.1" - -[[deps.SimplePolynomials]] -deps = ["Mods", "Multisets", "Polynomials", "Primes"] -git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" -uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" -version = "0.2.17" - -[[deps.SimpleRandom]] -deps = ["Distributions", "LinearAlgebra", "Random"] -git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" -uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" -version = "0.3.1" - -[[deps.SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" - -[[deps.Sixel]] -deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] -git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" -uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" -version = "0.1.3" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[deps.SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.10.0" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.1" -weakdeps = ["ChainRulesCore"] - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - -[[deps.StableHashTraits]] -deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] -git-tree-sha1 = "662f56ffe22b3985f3be7474f0aecbaf214ecf0f" -uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" -version = "1.1.6" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.1" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "f68dd04d131d9a8a8eb836173ee8f105c360b0c5" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.1" -weakdeps = ["ChainRulesCore", "Statistics"] - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.2" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.0" - -[[deps.StatsBase]] -deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.2" - -[[deps.StatsFuns]] -deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.3.0" - - [deps.StatsFuns.extensions] - StatsFunsChainRulesCoreExt = "ChainRulesCore" - StatsFunsInverseFunctionsExt = "InverseFunctions" - - [deps.StatsFuns.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - -[[deps.StructArrays]] -deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "1b0b1205a56dc288b71b1961d48e351520702e24" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.17" - -[[deps.SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.1" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[deps.TensorCore]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" -uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" -version = "0.1.1" - -[[deps.Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.TiffImages]] -deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] -git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" -uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.6.8" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.2" -weakdeps = ["Random", "Test"] - - [deps.TranscodingStreams.extensions] - TestExt = ["Test", "Random"] - -[[deps.TriplotBase]] -git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" -uuid = "981d1d27-644d-49a2-9326-4793e63143c3" -version = "0.1.0" - -[[deps.TupleTools]] -git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" -uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" -version = "1.4.3" - -[[deps.URIs]] -git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" -uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.5.1" - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[deps.UnicodeFun]] -deps = ["REPL"] -git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.1" - -[[deps.WoodburyMatrices]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "1.0.0" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.2+0" - -[[deps.XSLT_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] -git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" -uuid = "aed1982a-8fda-507f-9586-7b0439959a61" -version = "1.1.34+0" - -[[deps.Xorg_libX11_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] -git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" -uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" -version = "1.8.6+0" - -[[deps.Xorg_libXau_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" -uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" -version = "1.0.11+0" - -[[deps.Xorg_libXdmcp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" -uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" -version = "1.1.4+0" - -[[deps.Xorg_libXext_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" -uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.4+4" - -[[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" -uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.10+4" - -[[deps.Xorg_libpthread_stubs_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" -uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" -version = "0.1.1+0" - -[[deps.Xorg_libxcb_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] -git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" -uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.15.0+0" - -[[deps.Xorg_xtrans_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" -uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" -version = "1.5.0+0" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+1" - -[[deps.isoband_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" -uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" -version = "0.2.3+0" - -[[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" -uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.4.0+0" - -[[deps.libass_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" -uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" -version = "0.15.1+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+1" - -[[deps.libfdk_aac_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" -uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" -version = "2.0.2+0" - -[[deps.libpng_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "93284c28274d9e75218a416c65ec49d0e0fcdf3d" -uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.40+0" - -[[deps.libsixel_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] -git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" -uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" -version = "1.10.3+0" - -[[deps.libvorbis_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] -git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" -uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.7+1" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" - -[[deps.x264_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" -uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" -version = "2021.5.5+0" - -[[deps.x265_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" -uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" -version = "3.5.0+0" From 35ea53a4cebca794c05b614ca89c79a0989bef23 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 28 Mar 2024 09:57:01 +0200 Subject: [PATCH 154/182] use tagged version of Oceananigans --- Manifest.toml | 303 ++++++++++++++++++++++++++++++-------------------- Project.toml | 4 +- 2 files changed, 186 insertions(+), 121 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index f8603fe9..79336c04 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.0" +julia_version = "1.10.2" manifest_format = "2.0" -project_hash = "bcfc95e502c18276c6e7315f722ad6f48d7698c2" +project_hash = "4541400e0595766f463b7e38f77998862b782464" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -16,16 +16,17 @@ weakdeps = ["ChainRulesCore", "Test"] AbstractFFTsTestExt = "Test" [[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Test"] -git-tree-sha1 = "cb96992f1bec110ad211b7e410e57ddf7944c16f" +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] +git-tree-sha1 = "c0d491ef0b135fd7d63cbc6404286bc633329425" uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.35" +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" @@ -33,6 +34,7 @@ version = "0.1.35" 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"] @@ -50,9 +52,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "bbec08a37f8722786d87bedf84eae19c020c4efa" +git-tree-sha1 = "c5aeb516a84459e0318a02507d2261edad97eb75" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.7.0" +version = "7.7.1" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -93,6 +95,12 @@ git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" version = "0.1.8" +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.5+0" + [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" @@ -106,15 +114,15 @@ version = "0.5.0" [[deps.CFTime]] deps = ["Dates", "Printf"] -git-tree-sha1 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" +git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.1.2" +version = "0.1.3" [[deps.CLIMAParameters]] deps = ["DocStringExtensions", "TOML", "Test"] -git-tree-sha1 = "0c8c49ca2b7992490ab2a5292ed23aeae8b0768f" +git-tree-sha1 = "cf4f5ee75576ae855eca7da064540ce40b9a04c1" uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" -version = "0.8.2" +version = "0.8.6" [[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", "Statistics", "UnsafeAtomicsLLVM"] @@ -135,9 +143,9 @@ version = "0.7.0+1" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] -git-tree-sha1 = "bcc4a23cbbd99c8535a5318455dcf0f2546ec536" +git-tree-sha1 = "2cb12f6b2209f40a4b8967697689a47c50485490" uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.2.2" +version = "0.2.3" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] @@ -147,9 +155,9 @@ version = "0.10.1+0" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "c1deebd76f7a443d527fc0430d5758b8b2112ed8" +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.19.1" +version = "1.23.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -165,9 +173,9 @@ version = "0.1.0" [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.3" +version = "0.7.4" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] @@ -182,10 +190,10 @@ uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.12.10" [[deps.CommonDataModel]] -deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf"] -git-tree-sha1 = "7f5717cbb2c1ce650cfd454451f282df33103596" +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.2.5" +version = "0.3.5" [[deps.CommonSolve]] git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" @@ -200,9 +208,9 @@ version = "0.3.0" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.12.0" +version = "4.14.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -211,7 +219,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.5+1" +version = "1.1.0+0" [[deps.CompositionsBase]] git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" @@ -224,15 +232,15 @@ weakdeps = ["InverseFunctions"] [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.3.0" +version = "2.4.1" [[deps.ConstructionBase]] deps = ["LinearAlgebra"] -git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.4" +version = "1.5.5" [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" @@ -249,9 +257,9 @@ version = "4.1.1" [[deps.CubedSphere]] deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] -git-tree-sha1 = "253193dfb0384646936c5ff3230b27a20d91261e" +git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.2.4" +version = "0.2.5" [[deps.CubicSplines]] deps = ["Random", "Test"] @@ -266,21 +274,21 @@ version = "1.16.0" [[deps.DataDeps]] deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] -git-tree-sha1 = "d481f6419c262edcb7294179bd63249d123eb081" +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.12" +version = "0.7.13" [[deps.DataFrames]] -deps = ["Compat", "DataAPI", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SnoopPrecompile", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "aa51303df86f8626a962fccb878430cdb0a97eee" +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.5.0" +version = "1.6.1" [[deps.DataStructures]] -deps = ["InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "88d48e133e6d3dd68183309877eac74393daa7eb" +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "0f4b5d62a88d8f59003e43c25a8a90de9eb76317" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.17.20" +version = "0.18.18" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -304,10 +312,10 @@ uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" version = "1.15.1" [[deps.DiskArrays]] -deps = ["OffsetArrays"] -git-tree-sha1 = "1bfa9de80f35ac63c6c381b2d43c590875896a1f" +deps = ["LRUCache", "OffsetArrays"] +git-tree-sha1 = "ef25c513cad08d7ebbed158c91768ae32f308336" uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.3.22" +version = "0.3.23" [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] @@ -365,9 +373,9 @@ version = "3.3.10+0" [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc" +git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.2" +version = "1.16.3" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" @@ -392,6 +400,11 @@ weakdeps = ["StaticArrays"] 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 = "85d7fb51afb3def5dcb85ad31c3707795c8bccc1" @@ -415,6 +428,12 @@ 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 = "f3c0936dd685d57fa0b1eee7dbebf382b969ea63" +uuid = "0951126a-58fd-58f1-b5b3-b08c7c4a876d" +version = "3.8.3+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" @@ -423,9 +442,9 @@ version = "1.14.2+1" [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "abbbb9ec3afd783a7cbd82ef01dcd088ea051398" +git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.1" +version = "1.10.5" [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -462,9 +481,13 @@ uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[deps.InverseFunctions]] deps = ["Test"] -git-tree-sha1 = "68772f49f54b479fa88ace904f6127f0a3bb2e46" +git-tree-sha1 = "896385798a8d49a255c398bd49162062e4a4c435" uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.12" +version = "0.1.13" +weakdeps = ["Dates"] + + [deps.InverseFunctions.extensions] + DatesExt = "Dates" [[deps.InvertedIndices]] git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" @@ -478,9 +501,9 @@ version = "0.2.2" [[deps.IterativeSolvers]] deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] -git-tree-sha1 = "b435d190ef8369cf4d79cc9dd5fba88ba0165307" +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" -version = "0.9.3" +version = "0.9.4" [[deps.IteratorInterfaceExtensions]] git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" @@ -489,9 +512,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "7c0008f0b7622c6c0ee5c65cbc667b69f8a65672" +git-tree-sha1 = "5ea6acdd53a51d897672edb694e3cc2912f3f8a7" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.45" +version = "0.4.46" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -519,9 +542,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "4e0cb2f5aad44dcfdc91088e85dee4ecb22c791c" +git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.16" +version = "0.9.18" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -531,9 +554,9 @@ version = "0.9.16" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "cb4619f7353fc62a1a22ffa3d7ed9791cfb47ad8" +git-tree-sha1 = "ab01dde107f21aa76144d0771dccc08f152ccac7" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.4.2" +version = "6.6.2" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -541,9 +564,9 @@ weakdeps = ["BFloat16s"] [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "98eaee04d96d973e79c25d49167668c5c8fb50e2" +git-tree-sha1 = "88b916503aac4fb7f701bb625cd84ca5dd1677bc" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.27+1" +version = "0.0.29+0" [[deps.LLVMLoopInfo]] git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" @@ -556,6 +579,15 @@ 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" @@ -604,9 +636,9 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" +git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.26" +version = "0.3.27" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -627,6 +659,12 @@ git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" version = "1.0.3" +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.9.4+0" + [[deps.MKL_jll]] deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" @@ -648,10 +686,10 @@ version = "0.20.16" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" [[deps.MPICH_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "2ee75365ca243c1a39d467e35ffd3d4d32eef11e" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "656036b9ed6f942d35e536e249600bc31d0f9df8" uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.1.2+1" +version = "4.2.0+0" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] @@ -660,10 +698,10 @@ uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" version = "0.1.10" [[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "8eeb3c73bbc0ca203d0dc8dad4008350bbe5797b" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "77c3bd69fdb024d75af38713e883d0f249ce19c2" uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.3.1+1" +version = "5.3.2+0" [[deps.MacroTools]] deps = ["Markdown", "Random"] @@ -688,9 +726,9 @@ version = "2.28.2+1" [[deps.MicrosoftMPI_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "b01beb91d20b0d1312a9471a36017b5b339d26de" +git-tree-sha1 = "f12a29c4400ba812841c6ace3f4efbb6dbb3ba01" uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" -version = "10.1.4+1" +version = "10.1.4+2" [[deps.Missings]] deps = ["DataAPI"] @@ -707,9 +745,9 @@ version = "2023.1.10" [[deps.NCDatasets]] deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "173a378f357e9bb24b22019efb5e4778223ce8cf" +git-tree-sha1 = "d40d24d12f710c39d3a66be99c567ce0032f28a7" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.13.2" +version = "0.14.3" [[deps.NVTX]] deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] @@ -730,10 +768,16 @@ uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" version = "1.0.2" [[deps.NetCDF_jll]] -deps = ["Artifacts", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "XML2_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "10c612c81eaffdd6b7c28a45a554cdd9d2f40ff1" +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.208+0" +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" @@ -741,11 +785,9 @@ 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 = "f6e83dea28d816e28b1765b84503815c43ebf697" -repo-rev = "ss-glw/time-bcs" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +git-tree-sha1 = "4672af7242405313743af45168bfce3d87b84b2c" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.7" +version = "0.90.11" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -765,7 +807,7 @@ weakdeps = ["Adapt"] [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.23+2" +version = "0.3.23+4" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] @@ -774,21 +816,21 @@ version = "0.8.1+2" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] -git-tree-sha1 = "1d1421618bab0e820bdc7ae1a2b46ce576981273" +git-tree-sha1 = "f46caf663e069027a06942d00dced37f1eb3d8ad" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.1+0" +version = "5.0.2+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.1" +version = "1.4.2" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" +git-tree-sha1 = "60e3045590bd104a16fefb12836c00c0ef8c7f8c" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.12+0" +version = "3.0.13+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -801,6 +843,12 @@ git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.6.3" +[[deps.P11Kit_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "2cd396108e178f3ae8dedbd8e938a18726ab2fbf" +uuid = "c2071276-7c44-58a7-b746-946036e04d0a" +version = "0.24.1+0" + [[deps.PMIx_jll]] deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" @@ -858,15 +906,15 @@ version = "1.4.3" [[deps.PrecompileTools]] deps = ["Preferences"] -git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.0" +version = "1.2.1" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.1" +version = "1.4.3" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] @@ -886,9 +934,9 @@ version = "1.5.1" [[deps.Quaternions]] deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "9a46862d248ea548e340e30e2894118749dc7f51" +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.5" +version = "0.7.6" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] @@ -900,9 +948,9 @@ uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[deps.Random123]] deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "c860e84651f58ce240dd79e5d9e055d55234c35a" +git-tree-sha1 = "4743b43e5a9c4a2ede372de7061eed81795b12e7" uuid = "74087812-796a-5b5d-8853-05524746bad3" -version = "1.6.2" +version = "1.7.0" [[deps.RandomNumbers]] deps = ["Random", "Requires"] @@ -935,15 +983,15 @@ version = "1.3.0" [[deps.RootSolvers]] deps = ["ForwardDiff"] -git-tree-sha1 = "833d9914e748ca9329b762a82ec912897975f8d8" +git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" -version = "0.4.1" +version = "0.4.2" [[deps.Roots]] deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] -git-tree-sha1 = "af540898b1e6ca7aa6ba7213c05052809c6c522a" +git-tree-sha1 = "1ab580704784260ee5f45bffac810b152922747b" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.1.0" +version = "2.1.5" [deps.Roots.extensions] RootsForwardDiffExt = "ForwardDiff" @@ -959,9 +1007,13 @@ version = "2.1.0" [[deps.Rotations]] deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "792d8fd4ad770b6d517a13ebb8dadfcac79405b8" +git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.6.1" +version = "1.7.0" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" @@ -992,12 +1044,6 @@ git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" version = "1.1.0" -[[deps.SnoopPrecompile]] -deps = ["Preferences"] -git-tree-sha1 = "e760a70afdcd461cf01a575947738d359234665c" -uuid = "66db9d55-30c0-4569-8b51-7e840670fc0c" -version = "1.0.3" - [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" @@ -1024,9 +1070,9 @@ weakdeps = ["ChainRulesCore"] [[deps.Static]] deps = ["IfElse"] -git-tree-sha1 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" +git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "0.8.8" +version = "0.8.10" [[deps.StaticArrayInterface]] deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] @@ -1041,9 +1087,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "f68dd04d131d9a8a8eb836173ee8f105c360b0c5" +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.1" +version = "1.9.3" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -1094,10 +1140,17 @@ uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" version = "0.3.4" [[deps.StructArrays]] -deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "1b0b1205a56dc288b71b1961d48e351520702e24" +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.17" +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"] @@ -1146,9 +1199,9 @@ version = "1.10.0" [[deps.TaylorSeries]] deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] -git-tree-sha1 = "9138fdc8ee4e3b8839eca696a76d15e16c9c7af0" +git-tree-sha1 = "1c7170668366821b0c4c4fe03ee78f8d6cf36e2c" uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.15.4" +version = "0.16.0" [deps.TaylorSeries.extensions] TaylorSeriesIAExt = "IntervalArithmetic" @@ -1179,18 +1232,18 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.23" [[deps.TranscodingStreams]] -git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" +git-tree-sha1 = "14389d51751169994b2e1317d5c72f7dc4f21045" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.2" +version = "0.10.6" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] TestExt = ["Test", "Random"] [[deps.TupleTools]] -git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" +git-tree-sha1 = "41d61b1c545b06279871ef1a4b5fcb2cac2191cd" uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" -version = "1.4.3" +version = "1.5.0" [[deps.URIs]] git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" @@ -1222,9 +1275,15 @@ version = "1.3.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" +git-tree-sha1 = "07e470dabc5a6a4254ffebc29a1b3fc01464e105" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.2+0" +version = "2.12.5+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "31c421e5516a6248dfb22c194519e37effbf1f30" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.6.1+0" [[deps.Zlib_jll]] deps = ["Libdl"] @@ -1239,9 +1298,9 @@ version = "1.5.5+0" [[deps.libaec_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "eddd19a8dea6b139ea97bdc8a0e2667d4b661720" +git-tree-sha1 = "46bf7be2917b59b761247be3f317ddf75e50e997" uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.0.6+1" +version = "1.1.2+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] @@ -1254,6 +1313,12 @@ git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" version = "2.1.13+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" diff --git a/Project.toml b/Project.toml index 5018ab52..c7987b2c 100644 --- a/Project.toml +++ b/Project.toml @@ -30,8 +30,8 @@ DataDeps = "0.7" Downloads = "1.6" JLD2 = "0.4" KernelAbstractions = "0.9" -NCDatasets = "0.12, 0.13" -Oceananigans = "0.90" +NCDatasets = "0.12, 0.13, 0.14" +Oceananigans = "0.90.8" SeawaterPolynomials = "0.3" Statistics = "1.9" julia = "1.9" From a24cf5b414331cb0ddfbfafba4fb3d727820e38f Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 28 Mar 2024 12:31:26 +0200 Subject: [PATCH 155/182] use latest deps --- Manifest.toml | 68 ++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 79336c04..69982140 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.2" manifest_format = "2.0" -project_hash = "4541400e0595766f463b7e38f77998862b782464" +project_hash = "447a422c075ffbcbf503bd4470cb7332cca98e65" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -38,9 +38,9 @@ version = "0.1.36" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.7.2" +version = "4.0.4" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] @@ -51,16 +51,18 @@ uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" version = "1.1.1" [[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "c5aeb516a84459e0318a02507d2261edad97eb75" +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.7.1" +version = "7.9.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceChainRulesExt = "ChainRules" ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" ArrayInterfaceTrackerExt = "Tracker" @@ -68,7 +70,9 @@ version = "7.7.1" BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" @@ -118,17 +122,11 @@ git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" uuid = "179af706-886a-5703-950a-314cd64e0468" version = "0.1.3" -[[deps.CLIMAParameters]] -deps = ["DocStringExtensions", "TOML", "Test"] -git-tree-sha1 = "cf4f5ee75576ae855eca7da064540ce40b9a04c1" -uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" -version = "0.8.6" - [[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", "Statistics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "95ac638373ac40e29c1b6d086a3698f5026ff6a6" +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] +git-tree-sha1 = "baa8ea7a1ea63316fa3feb454635215773c9c845" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.1.2" +version = "5.2.0" weakdeps = ["ChainRulesCore", "SpecialFunctions"] [deps.CUDA.extensions] @@ -149,9 +147,9 @@ version = "0.2.3" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "9704e50c9158cf8896c2776b8dbc5edd136caf80" +git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.10.1+0" +version = "0.11.1+0" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] @@ -165,7 +163,7 @@ weakdeps = ["SparseArrays"] [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" +git-tree-sha1 = "6afd99a2cb2495792aaed92dc895ba78a3b82870" repo-rev = "main" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" @@ -407,15 +405,15 @@ version = "6.2.1+6" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "85d7fb51afb3def5dcb85ad31c3707795c8bccc1" +git-tree-sha1 = "47e4686ec18a9620850bad110b79966132f14283" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "9.1.0" +version = "10.0.2" [[deps.GPUArraysCore]] deps = ["Adapt"] -git-tree-sha1 = "2d6ca471a6c7b536127afccfa7564b5b39227fe0" +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.1.5" +version = "0.1.6" [[deps.GPUCompiler]] deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] @@ -1168,12 +1166,18 @@ uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.1+1" [[deps.SurfaceFluxes]] -deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "3b54de787d5f07b56a34578174174c99dc30beda" +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "c2c43206af0d861e018f746286d1af036aa7bc3a" repo-rev = "glw/generalize-parameters" repo-url = "https://github.com/glwagner/SurfaceFluxes.jl.git" uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.8.1" +version = "0.9.2" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "CLIMAParameters" + + [deps.SurfaceFluxes.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" [[deps.TOML]] deps = ["Dates"] @@ -1215,15 +1219,17 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "f4555e1302df12011b836fbdcdd3e10e5df7329a" -repo-rev = "glw/density-example" -repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" +git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" +repo-rev = "main" +repo-url = "https://github.com/CliMA/Thermodynamics.jl.git" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.11.5" -weakdeps = ["CLIMAParameters"] +version = "0.12.6" [deps.Thermodynamics.extensions] - CreateParametersExt = "CLIMAParameters" + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] From 54cb9b7a6b4caf4beb05bb2728b37a04baa01f26 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 28 Mar 2024 12:32:52 +0200 Subject: [PATCH 156/182] updates --- Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index c7987b2c..33627c12 100644 --- a/Project.toml +++ b/Project.toml @@ -2,7 +2,7 @@ name = "ClimaOcean" uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" license = "MIT" authors = ["Climate Modeling Alliance and contributors"] -version = "0.1.0" +version = "0.1.2" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" @@ -31,7 +31,7 @@ Downloads = "1.6" JLD2 = "0.4" KernelAbstractions = "0.9" NCDatasets = "0.12, 0.13, 0.14" -Oceananigans = "0.90.8" +Oceananigans = "0.90.10" SeawaterPolynomials = "0.3" Statistics = "1.9" julia = "1.9" From e4ce25cc45ffe42a36289da7117d4e5cd744ef72 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 28 Mar 2024 12:34:33 +0200 Subject: [PATCH 157/182] merge main --- examples/generate_bathymetry.jl | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 5ded7e62..0468499a 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -35,23 +35,31 @@ display(fig) ##### Regional Mediterranean grid ##### +# 1/25th degree resolution +Nλ = 25 * 55 +Nφ = 25 * 25 + grid = LatitudeLongitudeGrid(CPU(); - size = (25 * 50, 55 * 50, 1), + size = (Nλ, Nφ, 1), latitude = (25, 50), longitude = (-10, 45), z = (0, 1), halo = (4, 4, 4)) -h = regrid_bathymetry(grid, height_above_water=1) +h_smooth = regrid_bathymetry(grid, height_above_water=1, interpolation_passes = 40) +h_rough = regrid_bathymetry(grid, height_above_water=1, interpolation_passes = 1) -λ, φ, z = nodes(h) +λ, φ, z = nodes(h_smooth) -land = interior(h) .> 0 -interior(h)[land] .= NaN +land_smooth = interior(h_smooth) .> 0 +interior(h_smooth)[land_smooth] .= NaN +land_rough = interior(h_rough) .> 0 +interior(h_rough)[land_rough] .= NaN fig = Figure(size=(2400, 1200)) ax = Axis(fig[1, 1]) -heatmap!(ax, λ, φ, interior(h, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) +heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) +ax = Axis(fig[1, 2]) +heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) display(fig) - From 8172bba521a59ea67d86e57367dfaec1e1174add Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 4 Apr 2024 12:16:18 +0300 Subject: [PATCH 158/182] some things lost in merge --- src/DataWrangling/ECCO2.jl | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 4fe87dba..526536d1 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -96,13 +96,22 @@ filenames_19920102 = Dict( :v_velocity => "VVEL.1440x720.19920102.nc", ) +filenames_19921001 = Dict( + :temperature => "THETA.1440x720x50.19921001.nc", + :salinity => "SALT.1440x720x50.19921001.nc", + :sea_ice_thickness => "SIheff.1440x720.19921001.nc", + :sea_ice_area_fraction => "SIarea.1440x720.19921001.nc", + :u_velocity => "UVEL.1440x720.19921001.nc", + :v_velocity => "VVEL.1440x720.19921001.nc", +) + ecco2_location = Dict( - :temperature => (Center, Center, Center), - :salinity => (Center, Center, Center), - :u_velocity => (Face, Center, Center), - :v_velocity => (Center, Face, Center), - :sea_ice_thickness => (Center, Center, Nothing) - :sea_ice_fraction => (Center, Center, Nothing) + :temperature => (Center, Center, Center), + :salinity => (Center, Center, Center), + :sea_ice_thickness => (Center, Center, Nothing), + :sea_ice_area_fraction => (Center, Center, Nothing), + :u_velocity => (Face, Center, Center), + :v_velocity => (Center, Face, Center), ) ecco2_depth_names = Dict( From 46b89179175b842a95e0f147892768fcca1592d1 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 4 Apr 2024 12:16:36 +0300 Subject: [PATCH 159/182] add back Manifest --- Manifest.toml | 1348 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1348 insertions(+) create mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 00000000..f0ea6a7f --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,1348 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.2" +manifest_format = "2.0" +project_hash = "447a422c075ffbcbf503bd4470cb7332cca98e65" + +[[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.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 = "44691067188f6bd1b2289552a23e4b7572f4528d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.9.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random", "Test"] +git-tree-sha1 = "2c7cc21e8678eff479978a0a2ef5ce2f51b63dff" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.5+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.3" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] +git-tree-sha1 = "baa8ea7a1ea63316fa3feb454635215773c9c845" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.2.0" +weakdeps = ["ChainRulesCore", "SpecialFunctions"] + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.7.0+1" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "2cb12f6b2209f40a4b8967697689a47c50485490" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.2.3" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.11.1+0" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.23.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "6afd99a2cb2495792aaed92dc895ba78a3b82870" +repo-rev = "main" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.1.0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.5" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.14.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.0+0" + +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.4.1" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.5" + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + + [deps.ConstructionBase.weakdeps] + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[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", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SnoopPrecompile", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "aa51303df86f8626a962fccb878430cdb0a97eee" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.5.0" + +[[deps.DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "88d48e133e6d3dd68183309877eac74393daa7eb" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.17.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 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.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.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 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GMP_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" +version = "6.2.1+6" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] +git-tree-sha1 = "47e4686ec18a9620850bad110b79966132f14283" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "10.0.2" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.25.0" + +[[deps.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 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.5" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.10.0+0" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[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 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.0.2+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "896385798a8d49a255c398bd49162062e4a4c435" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.13" +weakdeps = ["Dates"] + + [deps.InverseFunctions.extensions] + DatesExt = "Dates" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] +git-tree-sha1 = "5ea6acdd53a51d897672edb694e3cc2912f3f8a7" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.46" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.18" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] +git-tree-sha1 = "839c82932db86740ae729779e610f07a1640be9a" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "6.6.3" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "88b916503aac4fb7f701bb625cd84ca5dd1677bc" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.29+0" + +[[deps.LLVMLoopInfo]] +git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" +uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" +version = "1.0.0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.7+0" + +[[deps.LRUCache]] +git-tree-sha1 = "b3cc6698599b10e652832c2f23db3cab99d51b59" +uuid = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" +version = "1.6.1" +weakdeps = ["Serialization"] + + [deps.LRUCache.extensions] + SerializationExt = ["Serialization"] + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.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 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.27" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.0.3" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.9.4+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.0.0+0" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "b4d8707e42b693720b54f0b3434abee6dd4d947a" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.16" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "656036b9ed6f942d35e536e249600bc31d0f9df8" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.2.0+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.10" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "77c3bd69fdb024d75af38713e883d0f249ce19c2" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.3.2+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f12a29c4400ba812841c6ace3f4efbb6dbb3ba01" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.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 = "d40d24d12f710c39d3a66be99c567ce0032f28a7" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.3" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "0.3.4" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.1.0+2" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenMPI_jll", "XML2_jll", "Zlib_jll", "Zstd_jll", "libzip_jll"] +git-tree-sha1 = "a8af1798e4eb9ff768ce7fdefc0e957097793f15" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "400.902.209+0" + +[[deps.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 = "4672af7242405313743af45168bfce3d87b84b2c" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.90.11" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.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", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] +git-tree-sha1 = "f46caf663e069027a06942d00dced37f1eb3d8ad" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.2+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.2" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.13+1" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.P11Kit_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "2cd396108e178f3ae8dedbd8e938a18726ab2fbf" +uuid = "c2071276-7c44-58a7-b746-946036e04d0a" +version = "0.24.1+0" + +[[deps.PMIx_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] +git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" +uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" +version = "4.2.7+0" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.PencilArrays]] +deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] +git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" +uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" +version = "0.19.3" + + [deps.PencilArrays.extensions] + PencilArraysDiffEqExt = ["DiffEqBase"] + PencilArraysHDF5Ext = ["HDF5"] + + [deps.PencilArrays.weakdeps] + DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" + HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" + +[[deps.PencilFFTs]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" +uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" +version = "0.15.1" + +[[deps.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.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 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.1" + +[[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.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 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.0" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.4" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + +[[deps.SnoopPrecompile]] +deps = ["Preferences"] +git-tree-sha1 = "e760a70afdcd461cf01a575947738d359234665c" +uuid = "66db9d55-30c0-4569-8b51-7e840670fc0c" +version = "1.0.3" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.Static]] +deps = ["IfElse"] +git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "0.8.10" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.5.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.3" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.StaticPermutations]] +git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" +uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" +version = "0.3.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.Strided]] +deps = ["LinearAlgebra", "StridedViews", "TupleTools"] +git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "2.0.4" + +[[deps.StridedViews]] +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" +uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" +version = "0.2.2" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.18" +weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = "GPUArraysCore" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "c2c43206af0d861e018f746286d1af036aa7bc3a" +repo-rev = "glw/generalize-parameters" +repo-url = "https://github.com/glwagner/SurfaceFluxes.jl.git" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.9.2" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "CLIMAParameters" + + [deps.SurfaceFluxes.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TaylorSeries]] +deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] +git-tree-sha1 = "1c7170668366821b0c4c4fe03ee78f8d6cf36e2c" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.16.0" + + [deps.TaylorSeries.extensions] + TaylorSeriesIAExt = "IntervalArithmetic" + + [deps.TaylorSeries.weakdeps] + IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" +repo-rev = "main" +repo-url = "https://github.com/CliMA/Thermodynamics.jl.git" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.6" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.23" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.7" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.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.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 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.3" + +[[deps.VersionParsing]] +git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.3.0" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.6+0" + +[[deps.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.libevent_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll"] +git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" +uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" +version = "2.1.13+1" + +[[deps.libzip_jll]] +deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "3282b7d16ae7ac3e57ec2f3fa8fafb564d8f9f7f" +uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" +version = "1.10.1+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[deps.prrte_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_jll"] +git-tree-sha1 = "5adb2d7a18a30280feb66cad6f1a1dfdca2dc7b0" +uuid = "eb928a42-fffd-568d-ab9c-3f5d54fc65b9" +version = "3.0.2+0" From 38c9fd745afb0290e2faac9be9dbf1db8d1bb3eb Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 4 Apr 2024 12:26:56 +0300 Subject: [PATCH 160/182] some more fixes --- Project.toml | 2 +- .../prototype_omip_simulation/Manifest.toml | 2359 +++++++++++++++++ .../prototype_omip_simulation/Project.toml | 4 +- 3 files changed, 2363 insertions(+), 2 deletions(-) create mode 100644 experiments/prototype_omip_simulation/Manifest.toml diff --git a/Project.toml b/Project.toml index e884fc3b..b1a5bfc4 100644 --- a/Project.toml +++ b/Project.toml @@ -32,7 +32,7 @@ JLD2 = "0.4" KernelAbstractions = "0.9" NCDatasets = "0.12, 0.13, 0.14" Oceananigans = "0.90.10" -SeawaterPolynomials = "0.3" +SeawaterPolynomials = "0.3.4" Statistics = "1.9" julia = "1.9" diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml new file mode 100644 index 00000000..230b6f71 --- /dev/null +++ b/experiments/prototype_omip_simulation/Manifest.toml @@ -0,0 +1,2359 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.2" +manifest_format = "2.0" +project_hash = "d8dbe9035fba3af9077b6e3c6495e511c55cd6e3" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.3.0" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] +git-tree-sha1 = "c0d491ef0b135fd7d63cbc6404286bc633329425" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.36" + + [deps.Accessors.extensions] + AccessorsAxisKeysExt = "AxisKeys" + AccessorsIntervalSetsExt = "IntervalSets" + AccessorsStaticArraysExt = "StaticArrays" + AccessorsStructArraysExt = "StructArrays" + AccessorsUnitfulExt = "Unitful" + + [deps.Accessors.weakdeps] + AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.0.4" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.9.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.Automa]] +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "1.0.3" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random", "Test"] +git-tree-sha1 = "2c7cc21e8678eff479978a0a2ef5ce2f51b63dff" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.5+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.3" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm]] +deps = ["CRlibm_jll"] +git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "1.0.1" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] +git-tree-sha1 = "baa8ea7a1ea63316fa3feb454635215773c9c845" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.2.0" +weakdeps = ["ChainRulesCore", "SpecialFunctions"] + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.7.0+1" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "2cb12f6b2209f40a4b8967697689a47c50485490" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.2.3" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.11.1+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "a4c43f59baa34011e303e76f5c8c91bf58415aaf" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.23.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ClimaOcean]] +deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +git-tree-sha1 = "2cd02219dd1feb66fa43bab0f3d80a9c04a2af4e" +repo-rev = "glw-ss/ice-ocean-model" +repo-url = "../.." +uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +version = "0.2.0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "6afd99a2cb2495792aaed92dc895ba78a3b82870" +repo-rev = "main" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.1.0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.5" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.14.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.0+0" + +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.4.1" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.5" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] +git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.2.5" + +[[deps.CubicSplines]] +deps = ["Random", "Test"] +git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" +uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" +version = "0.2.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "0f4b5d62a88d8f59003e43c25a8a90de9eb76317" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.18" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "d4e9dc4c6106b8d44e40cd4faf8261a678552c7c" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.12" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DiskArrays]] +deps = ["LRUCache", "OffsetArrays"] +git-tree-sha1 = "ef25c513cad08d7ebbed158c91768ae32f308336" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.3.23" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.107" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.Elliptic]] +git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" +uuid = "b305315f-e792-5b7a-8f41-49f472929428" +version = "1.0.1" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.ErrorfreeArithmetic]] +git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.5.2" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] +git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.5" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.Extents]] +git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.2" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "ab3f7e1819dba9434a3a5126510c8fda3a4e7000" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "6.1.1+0" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.8.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + +[[deps.FastRounding]] +deps = ["ErrorfreeArithmetic", "LinearAlgebra"] +git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.3.1" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.3" + +[[deps.FilePaths]] +deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] +git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" +uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" +version = "0.8.3" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] +git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.21" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "bfe82a708416cf00b73a3198db0859c82f741558" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.10.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "bc0c5092d6caaea112d3c8e3b238d61563c58d5f" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.23.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.1" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.1" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GLFW]] +deps = ["GLFW_jll"] +git-tree-sha1 = "35dbc482f0967d8dceaa7ce007d16f9064072166" +uuid = "f7f18e0c-5ee9-5ccd-a5bf-e8befd85ed98" +version = "3.4.1" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.3.9+0" + +[[deps.GLMakie]] +deps = ["ColorTypes", "Colors", "FileIO", "FixedPointNumbers", "FreeTypeAbstraction", "GLFW", "GeometryBasics", "LinearAlgebra", "Makie", "Markdown", "MeshIO", "ModernGL", "Observables", "PrecompileTools", "Printf", "ShaderAbstractions", "StaticArrays"] +git-tree-sha1 = "b99a999cdcc7467769c7ea8cdc0978a5f059aa7b" +uuid = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +version = "0.9.10" + +[[deps.GMP_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" +version = "6.2.1+6" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] +git-tree-sha1 = "47e4686ec18a9620850bad110b79966132f14283" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "10.0.2" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.25.0" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.3" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "5694b56ccf9d15addedc35e9a4ba9c317721b788" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.10" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.0+0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.GnuTLS_jll]] +deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Nettle_jll", "P11Kit_jll", "Zlib_jll"] +git-tree-sha1 = "383db7d3f900f4c1f47a8a04115b053c095e48d3" +uuid = "0951126a-58fd-58f1-b5b3-b08c7c4a876d" +version = "3.8.4+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "6f93a83ca11346771a93bbde2bdad2f65b61498f" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.10.2" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "38c8874692d48d5440d5752d6c74b0c6b0b60739" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.2+1" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.5" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.10.0+0" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.7" + +[[deps.ImageCore]] +deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "b2a7eaa169c13f5bcae8131a83bc30eff8f71be0" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.2" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IncompleteLU]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" +uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" +version = "0.2.1" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.0.2+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.15.1" + + [deps.Interpolations.extensions] + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] +git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.20.9" + +[[deps.IntervalSets]] +git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.10" +weakdeps = ["Random", "RecipesBase", "Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "896385798a8d49a255c398bd49162062e4a4c435" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.13" +weakdeps = ["Dates"] + + [deps.InverseFunctions.extensions] + DatesExt = "Dates" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.10.0" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] +git-tree-sha1 = "5ea6acdd53a51d897672edb694e3cc2912f3f8a7" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.46" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.5" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3336abae9a713d2210bb57ab484b1e065edd7d23" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.2+0" + +[[deps.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.18" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.8" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] +git-tree-sha1 = "839c82932db86740ae729779e610f07a1640be9a" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "6.6.3" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "88b916503aac4fb7f701bb625cd84ca5dd1677bc" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.29+0" + +[[deps.LLVMLoopInfo]] +git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" +uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" +version = "1.0.0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.7+0" + +[[deps.LRUCache]] +git-tree-sha1 = "b3cc6698599b10e652832c2f23db3cab99d51b59" +uuid = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" +version = "1.6.1" +weakdeps = ["Serialization"] + + [deps.LRUCache.extensions] + SerializationExt = ["Serialization"] + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.6.0+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.39.3+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.39.3+1" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.1" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] +git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.2.7" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.27" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.0.3" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.9.4+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.0.0+0" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "b4d8707e42b693720b54f0b3434abee6dd4d947a" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.16" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "656036b9ed6f942d35e536e249600bc31d0f9df8" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.2.0+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.10" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "77c3bd69fdb024d75af38713e883d0f249ce19c2" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.3.2+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "46ca613be7a1358fb93529726ea2fc28050d3ae0" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.20.9" + +[[deps.MakieCore]] +deps = ["Observables", "REPL"] +git-tree-sha1 = "248b7a4be0f92b497f7a331aed02c1e9a878f46b" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.7.3" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] +git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.7" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MeshIO]] +deps = ["ColorTypes", "FileIO", "GeometryBasics", "Printf"] +git-tree-sha1 = "8c26ab950860dfca6767f2bbd90fdf1e8ddc678b" +uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" +version = "0.4.11" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f12a29c4400ba812841c6ace3f4efbb6dbb3ba01" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.ModernGL]] +deps = ["Libdl"] +git-tree-sha1 = "b76ea40b5c0f45790ae09492712dd326208c28b2" +uuid = "66fc600b-dfda-50eb-8b99-91cfa97b1301" +version = "1.1.7" + +[[deps.Mods]] +git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "2.2.4" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "d40d24d12f710c39d3a66be99c567ce0032f28a7" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.3" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "0.3.4" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.1.0+2" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenMPI_jll", "XML2_jll", "Zlib_jll", "Zstd_jll", "libzip_jll"] +git-tree-sha1 = "a8af1798e4eb9ff768ce7fdefc0e957097793f15" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "400.902.209+0" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + +[[deps.Nettle_jll]] +deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "eca63e3847dad608cfa6a3329b95ef674c7160b4" +uuid = "4c82536e-c426-54e4-b420-14f461c4ed8b" +version = "3.7.2+0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.Oceananigans]] +deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "4672af7242405313743af45168bfce3d87b84b2c" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.90.11" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+4" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+2" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] +git-tree-sha1 = "f46caf663e069027a06942d00dced37f1eb3d8ad" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.2+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.2" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.13+1" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.Optim]] +deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "d9b79c4eed437421ac4285148fcadf42e0700e89" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.9.4" + + [deps.Optim.extensions] + OptimMOIExt = "MathOptInterface" + + [deps.Optim.weakdeps] + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.P11Kit_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "2cd396108e178f3ae8dedbd8e938a18726ab2fbf" +uuid = "c2071276-7c44-58a7-b746-946036e04d0a" +version = "0.24.1+0" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.31" + +[[deps.PMIx_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] +git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" +uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" +version = "4.2.7+0" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.3" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.PencilArrays]] +deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] +git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" +uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" +version = "0.19.3" + + [deps.PencilArrays.extensions] + PencilArraysDiffEqExt = ["DiffEqBase"] + PencilArraysHDF5Ext = ["HDF5"] + + [deps.PencilArrays.weakdeps] + DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" + HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" + +[[deps.PencilFFTs]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" +uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" +version = "0.15.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.20" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "7b1a9df27f072ac4c9c7cbe5efb198489258d1f5" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.1" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.6" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.1" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "cb420f77dc474d23ee47ca8d14c90810cafe69e7" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.6" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.ProgressBars]] +deps = ["Printf"] +git-tree-sha1 = "b437cdb0385ed38312d91d9c00c20f3798b30256" +uuid = "49802e3a-d2f1-5c88-81d8-b72133a6f568" +version = "1.5.1" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "763a8ceb07833dd51bb9e3bbca372de32c0605ad" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.10.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.4" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.6" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Random123]] +deps = ["Random", "RandomNumbers"] +git-tree-sha1 = "4743b43e5a9c4a2ede372de7061eed81795b12e7" +uuid = "74087812-796a-5b5d-8853-05524746bad3" +version = "1.7.0" + +[[deps.RandomNumbers]] +deps = ["Random", "Requires"] +git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111" +uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" +version = "1.5.3" + +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.RootSolvers]] +deps = ["ForwardDiff"] +git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.2" + +[[deps.Roots]] +deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] +git-tree-sha1 = "1ab580704784260ee5f45bffac810b152922747b" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.1.5" + + [deps.Roots.extensions] + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + + [deps.Roots.weakdeps] + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" + SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" + SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.0" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.4" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SetRounding]] +git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.1" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "79123bc60c5507f035e6d1d9e563bb2971954ec8" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.4.1" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.6" + +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "e182b9e5afb194142d4668536345a365ea19363a" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.2" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.17" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.Static]] +deps = ["IfElse"] +git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "0.8.10" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.5.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.3" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.StaticPermutations]] +git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" +uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" +version = "0.3.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.3" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.1" +weakdeps = ["ChainRulesCore", "InverseFunctions"] + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + +[[deps.Strided]] +deps = ["LinearAlgebra", "StridedViews", "TupleTools"] +git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "2.0.4" + +[[deps.StridedViews]] +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" +uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" +version = "0.2.2" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.18" +weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = "GPUArraysCore" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "c2c43206af0d861e018f746286d1af036aa7bc3a" +repo-rev = "glw/generalize-parameters" +repo-url = "https://github.com/glwagner/SurfaceFluxes.jl.git" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.9.2" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "CLIMAParameters" + + [deps.SurfaceFluxes.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TaylorSeries]] +deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] +git-tree-sha1 = "1c7170668366821b0c4c4fe03ee78f8d6cf36e2c" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.16.0" +weakdeps = ["IntervalArithmetic"] + + [deps.TaylorSeries.extensions] + TaylorSeriesIAExt = "IntervalArithmetic" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.6" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.8" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.23" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.7" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + +[[deps.TupleTools]] +git-tree-sha1 = "41d61b1c545b06279871ef1a4b5fcb2cac2191cd" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.5.0" + +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.2.1" + +[[deps.UnsafeAtomicsLLVM]] +deps = ["LLVM", "UnsafeAtomics"] +git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.3" + +[[deps.VersionParsing]] +git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.3.0" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.6+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.4.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.0+4" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "5.0.3+4" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.7.10+4" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] +git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.4+4" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.2+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.6+0" + +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "46bf7be2917b59b761247be3f317ddf75e50e997" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.1.2+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.libevent_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll"] +git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" +uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" +version = "2.1.13+1" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.43+1" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.libzip_jll]] +deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "3282b7d16ae7ac3e57ec2f3fa8fafb564d8f9f7f" +uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" +version = "1.10.1+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[deps.prrte_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_jll"] +git-tree-sha1 = "5adb2d7a18a30280feb66cad6f1a1dfdca2dc7b0" +uuid = "eb928a42-fffd-568d-ab9c-3f5d54fc65b9" +version = "3.0.2+0" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" diff --git a/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml index deaf8c37..7744d52a 100644 --- a/experiments/prototype_omip_simulation/Project.toml +++ b/experiments/prototype_omip_simulation/Project.toml @@ -14,4 +14,6 @@ Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" [compat] GLMakie = "0.9" -Oceananigans = "0.90.6" +Oceananigans = "0.90.10" +SeawaterPolynomials = "0.3.4" +Thermodynamics = "0.12.6" From 3836fb0b8376ac39c169ac1aae008514e103acb5 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 4 Apr 2024 12:29:51 +0300 Subject: [PATCH 161/182] resolve --- Manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index f0ea6a7f..4a313174 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.2" manifest_format = "2.0" -project_hash = "447a422c075ffbcbf503bd4470cb7332cca98e65" +project_hash = "64b3862ff4f09c6ae71318d88c2bbc084ba4e0f1" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] From 8c91b2abac416fcd1600d79a51581d93bb64909b Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 4 Apr 2024 12:41:31 +0300 Subject: [PATCH 162/182] add docs/src/literated/ --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9129be9e..353c5651 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ deps/src/ # Build artifacts for creating documentation generated by the Documenter package docs/build/ docs/site/ -docs/Manifest.toml +docs/src/literated/ # File generated by Pkg, the package manager, based on a corresponding Project.toml # It records a fixed state of all packages used by the project. As such, it should not be From bf789d543afbeee1dd0f4b7f3e1d02047c33d0c3 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 4 Apr 2024 12:41:46 +0300 Subject: [PATCH 163/182] working docs --- .github/workflows/Documenter.yml | 6 +- docs/Manifest.toml | 2256 ++++++++++++++++++++++++++++++ docs/make.jl | 2 + 3 files changed, 2263 insertions(+), 1 deletion(-) create mode 100644 docs/Manifest.toml diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 56d3abf2..1eb5ef50 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -21,7 +21,11 @@ jobs: version: '1.10' show-versioninfo: true - name: Install dependencies - run: julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()' + run: | + julia --color=yes --project -e 'using Pkg; Pkg.instantiate()' + julia --color=yes --project -e 'using Pkg; Pkg.precompile()' + julia --color=yes --project=docs/ -e 'using Pkg; Pkg.instantiate()' + julia --color=yes --project=docs/ -e 'using Pkg; Pkg.precompile()' - name: Build and deploy env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token diff --git a/docs/Manifest.toml b/docs/Manifest.toml new file mode 100644 index 00000000..60dfad2c --- /dev/null +++ b/docs/Manifest.toml @@ -0,0 +1,2256 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.2" +manifest_format = "2.0" +project_hash = "2b1abab6f384a62f893ca939d86c6775549fc57e" + +[[deps.ANSIColoredPrinters]] +git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" +uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" +version = "0.0.1" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractLattices]] +git-tree-sha1 = "222ee9e50b98f51b5d78feb93dd928880df35f06" +uuid = "398f06c4-4d28-53ec-89ca-5b2656b7603d" +version = "0.3.0" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.0.4" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.Animations]] +deps = ["Colors"] +git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" +uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" +version = "0.4.1" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.9.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.Automa]] +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "1.0.3" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "16351be62963a67ac4083f748fdb3cca58bfd52f" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.7" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random", "Test"] +git-tree-sha1 = "2c7cc21e8678eff479978a0a2ef5ce2f51b63dff" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.5+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.3" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[deps.CRlibm]] +deps = ["CRlibm_jll"] +git-tree-sha1 = "32abd86e3c2025db5172aa182b982debed519834" +uuid = "96374032-68de-5a5b-8d9e-752f78720389" +version = "1.0.1" + +[[deps.CRlibm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e329286945d0cfc04456972ea732551869af1cfc" +uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" +version = "1.0.1+0" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] +git-tree-sha1 = "baa8ea7a1ea63316fa3feb454635215773c9c845" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.2.0" +weakdeps = ["ChainRulesCore", "SpecialFunctions"] + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.7.0+1" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "2cb12f6b2209f40a4b8967697689a47c50485490" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.2.3" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.11.1+0" + +[[deps.Cairo]] +deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] +git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b" +uuid = "159f3aea-2a34-519c-b102-8c37f9878175" +version = "1.0.5" + +[[deps.CairoMakie]] +deps = ["Base64", "Cairo", "Colors", "FFTW", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools", "SHA"] +git-tree-sha1 = "5e21a254d82c64b1a4ed9dbdc7e87c5d9cf4a686" +uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +version = "0.10.12" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "a4c43f59baa34011e303e76f5c8c91bf58415aaf" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.23.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.ColorBrewer]] +deps = ["Colors", "JSON", "Test"] +git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" +uuid = "a2cac450-b92f-5266-8821-25eda20663c8" +version = "0.4.0" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.5" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.14.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.0+0" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.4.1" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.5" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] +git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.2.5" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "0f4b5d62a88d8f59003e43c25a8a90de9eb76317" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.18" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelaunayTriangulation]] +deps = ["DataStructures", "EnumX", "ExactPredicates", "Random", "SimpleGraphs"] +git-tree-sha1 = "d4e9dc4c6106b8d44e40cd4faf8261a678552c7c" +uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" +version = "0.8.12" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DiskArrays]] +deps = ["LRUCache", "OffsetArrays"] +git-tree-sha1 = "ef25c513cad08d7ebbed158c91768ae32f308336" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.3.23" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.107" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Documenter]] +deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] +git-tree-sha1 = "4a40af50e8b24333b9ec6892546d9ca5724228eb" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "1.3.0" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.EarCut_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" +uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" +version = "2.2.4+0" + +[[deps.Elliptic]] +git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" +uuid = "b305315f-e792-5b7a-8f41-49f472929428" +version = "1.0.1" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.ErrorfreeArithmetic]] +git-tree-sha1 = "d6863c556f1142a061532e79f611aa46be201686" +uuid = "90fa49ef-747e-5e6f-a989-263ba693cf1a" +version = "0.5.2" + +[[deps.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] +git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.5" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.Extents]] +git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.2" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "ab3f7e1819dba9434a3a5126510c8fda3a4e7000" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "6.1.1+0" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "4820348781ae578893311153d69049a93d05f39d" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.8.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + +[[deps.FastRounding]] +deps = ["ErrorfreeArithmetic", "LinearAlgebra"] +git-tree-sha1 = "6344aa18f654196be82e62816935225b3b9abe44" +uuid = "fa42c844-2597-5d31-933b-ebd51ab2693f" +version = "0.3.1" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.3" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "bfe82a708416cf00b73a3198db0859c82f741558" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.10.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "bc0c5092d6caaea112d3c8e3b238d61563c58d5f" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.23.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Formatting]] +deps = ["Logging", "Printf"] +git-tree-sha1 = "fb409abab2caf118986fc597ba84b50cbaf00b87" +uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" +version = "0.4.3" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType]] +deps = ["CEnum", "FreeType2_jll"] +git-tree-sha1 = "907369da0f8e80728ab49c1c7e09327bf0d6d999" +uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" +version = "4.1.1" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "055626e1a35f6771fe99060e835b72ca61a52621" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.1" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GMP_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" +version = "6.2.1+6" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] +git-tree-sha1 = "47e4686ec18a9620850bad110b79966132f14283" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "10.0.2" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.25.0" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.3" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "5694b56ccf9d15addedc35e9a4ba9c317721b788" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.10" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Git]] +deps = ["Git_jll"] +git-tree-sha1 = "04eff47b1354d702c3a85e8ab23d539bb7d5957e" +uuid = "d7ba0133-e1db-5d97-8f8c-041e4b3a1eb2" +version = "1.3.1" + +[[deps.Git_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "d18fb8a1f3609361ebda9bf029b60fd0f120c809" +uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb" +version = "2.44.0+2" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.0+0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.GnuTLS_jll]] +deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Nettle_jll", "P11Kit_jll", "Zlib_jll"] +git-tree-sha1 = "383db7d3f900f4c1f47a8a04115b053c095e48d3" +uuid = "0951126a-58fd-58f1-b5b3-b08c7c4a876d" +version = "3.8.4+0" + +[[deps.Graphics]] +deps = ["Colors", "LinearAlgebra", "NaNMath"] +git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "1.1.2" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.GridLayoutBase]] +deps = ["GeometryBasics", "InteractiveUtils", "Observables"] +git-tree-sha1 = "f57a64794b336d4990d90f80b147474b869b1bc4" +uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" +version = "0.9.2" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "38c8874692d48d5440d5752d6c74b0c6b0b60739" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.2+1" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.5" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.10.0+0" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.4" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "2e4520d67b0cef90865b3ef727594d2a58e0e1f8" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.11" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.7" + +[[deps.ImageCore]] +deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "b2a7eaa169c13f5bcae8131a83bc30eff8f71be0" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.2" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] +git-tree-sha1 = "bca20b2f5d00c4fbc192c3212da8fa79f4688009" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.7" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3d09a9f60edf77f8a4d99f9e015e8fbf9989605d" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.7+0" + +[[deps.IncompleteLU]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" +uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" +version = "0.2.1" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.0.2+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.15.1" + + [deps.Interpolations.extensions] + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.IntervalArithmetic]] +deps = ["CRlibm", "FastRounding", "LinearAlgebra", "Markdown", "Random", "RecipesBase", "RoundingEmulator", "SetRounding", "StaticArrays"] +git-tree-sha1 = "5ab7744289be503d76a944784bac3f2df7b809af" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.20.9" + +[[deps.IntervalSets]] +git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.10" +weakdeps = ["Random", "RecipesBase", "Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.Isoband]] +deps = ["isoband_jll"] +git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" +uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.10.0" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] +git-tree-sha1 = "5ea6acdd53a51d897672edb694e3cc2912f3f8a7" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.46" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.5" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3336abae9a713d2210bb57ab484b1e065edd7d23" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.2+0" + +[[deps.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] +git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.18" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.8" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] +git-tree-sha1 = "839c82932db86740ae729779e610f07a1640be9a" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "6.6.3" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "88b916503aac4fb7f701bb625cd84ca5dd1677bc" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.29+0" + +[[deps.LLVMLoopInfo]] +git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" +uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" +version = "1.0.0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.7+0" + +[[deps.LRUCache]] +git-tree-sha1 = "b3cc6698599b10e652832c2f23db3cab99d51b59" +uuid = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" +version = "1.6.1" +weakdeps = ["Serialization"] + + [deps.LRUCache.extensions] + SerializationExt = ["Serialization"] + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LazilyInitializedFields]] +git-tree-sha1 = "8f7f3cabab0fd1800699663533b6d5cb3fc0e612" +uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf" +version = "1.2.2" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.39.3+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.39.3+1" + +[[deps.LightXML]] +deps = ["Libdl", "XML2_jll"] +git-tree-sha1 = "3a994404d3f6709610701c7dabfc03fed87a81f8" +uuid = "9c8b4983-aa76-5018-a973-4c85ecc9e179" +version = "0.9.1" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearAlgebraX]] +deps = ["LinearAlgebra", "Mods", "Primes", "SimplePolynomials"] +git-tree-sha1 = "d76cec8007ec123c2b681269d40f94b053473fcf" +uuid = "9b3f67b0-2d00-526e-9884-9e4938f8fb88" +version = "0.2.7" + +[[deps.Literate]] +deps = ["Base64", "IOCapture", "JSON", "REPL"] +git-tree-sha1 = "bad26f1ccd99c553886ec0725e99a509589dcd11" +uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" +version = "2.16.1" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.27" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.0.3" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.9.4+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.0.0+0" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "b4d8707e42b693720b54f0b3434abee6dd4d947a" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.16" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "656036b9ed6f942d35e536e249600bc31d0f9df8" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.2.0+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.10" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "77c3bd69fdb024d75af38713e883d0f249ce19c2" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.3.2+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Makie]] +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Setfield", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "StableHashTraits", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] +git-tree-sha1 = "35fa3c150cd96fd77417a23965b7037b90d6ffc9" +uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +version = "0.19.12" + +[[deps.MakieCore]] +deps = ["Observables", "REPL"] +git-tree-sha1 = "9b11acd07f21c4d035bd4156e789532e8ee2cc70" +uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" +version = "0.6.9" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MarkdownAST]] +deps = ["AbstractTrees", "Markdown"] +git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" +uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" +version = "0.1.2" + +[[deps.MathTeXEngine]] +deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] +git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" +version = "0.5.7" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f12a29c4400ba812841c6ace3f4efbb6dbb3ba01" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.Mods]] +git-tree-sha1 = "924f962b524a71eef7a21dae1e6853817f9b658f" +uuid = "7475f97c-0381-53b1-977b-4c60186c8d62" +version = "2.2.4" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.Multisets]] +git-tree-sha1 = "8d852646862c96e226367ad10c8af56099b4047e" +uuid = "3b2b4ff1-bcff-5658-a3ee-dbcf1ce5ac09" +version = "0.4.4" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "d40d24d12f710c39d3a66be99c567ce0032f28a7" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.3" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "0.3.4" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.1.0+2" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenMPI_jll", "XML2_jll", "Zlib_jll", "Zstd_jll", "libzip_jll"] +git-tree-sha1 = "a8af1798e4eb9ff768ce7fdefc0e957097793f15" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "400.902.209+0" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + +[[deps.Nettle_jll]] +deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "eca63e3847dad608cfa6a3329b95ef674c7160b4" +uuid = "4c82536e-c426-54e4-b420-14f461c4ed8b" +version = "3.7.2+0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.Oceananigans]] +deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "4672af7242405313743af45168bfce3d87b84b2c" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.90.11" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+4" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.2" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "a4ca623df1ae99d09bc9868b008262d0c0ac1e4f" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.1.4+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+2" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "PMIx_jll", "TOML", "Zlib_jll", "libevent_jll", "prrte_jll"] +git-tree-sha1 = "f46caf663e069027a06942d00dced37f1eb3d8ad" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.2+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.2" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.13+1" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.Optim]] +deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "d9b79c4eed437421ac4285148fcadf42e0700e89" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.9.4" + + [deps.Optim.extensions] + OptimMOIExt = "MathOptInterface" + + [deps.Optim.weakdeps] + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.P11Kit_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "2cd396108e178f3ae8dedbd8e938a18726ab2fbf" +uuid = "c2071276-7c44-58a7-b746-946036e04d0a" +version = "0.24.1+0" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.31" + +[[deps.PMIx_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] +git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" +uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" +version = "4.2.7+0" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.3" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.Packing]] +deps = ["GeometryBasics"] +git-tree-sha1 = "ec3edfe723df33528e085e632414499f26650501" +uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" +version = "0.5.0" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "526f5a03792669e4187e584e8ec9d534248ca765" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.52.1+0" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.PencilArrays]] +deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] +git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" +uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" +version = "0.19.3" + + [deps.PencilArrays.extensions] + PencilArraysDiffEqExt = ["DiffEqBase"] + PencilArraysHDF5Ext = ["HDF5"] + + [deps.PencilArrays.weakdeps] + DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" + HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" + +[[deps.PencilFFTs]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" +uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" +version = "0.15.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.20" + +[[deps.PikaParser]] +deps = ["DocStringExtensions"] +git-tree-sha1 = "d6ff87de27ff3082131f31a714d25ab6d0a88abf" +uuid = "3bbf5609-3e7b-44cd-8549-7c69f321e792" +version = "0.6.1" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "7b1a9df27f072ac4c9c7cbe5efb198489258d1f5" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.1" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.6" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieCoreExt = "MakieCore" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.1" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "cb420f77dc474d23ee47ca8d14c90810cafe69e7" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.6" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.ProgressBars]] +deps = ["Printf"] +git-tree-sha1 = "b437cdb0385ed38312d91d9c00c20f3798b30256" +uuid = "49802e3a-d2f1-5c88-81d8-b72133a6f568" +version = "1.5.1" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "763a8ceb07833dd51bb9e3bbca372de32c0605ad" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.10.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.4" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.6" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Random123]] +deps = ["Random", "RandomNumbers"] +git-tree-sha1 = "4743b43e5a9c4a2ede372de7061eed81795b12e7" +uuid = "74087812-796a-5b5d-8853-05524746bad3" +version = "1.7.0" + +[[deps.RandomNumbers]] +deps = ["Random", "Requires"] +git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111" +uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" +version = "1.5.3" + +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RegistryInstances]] +deps = ["LazilyInitializedFields", "Pkg", "TOML", "Tar"] +git-tree-sha1 = "ffd19052caf598b8653b99404058fce14828be51" +uuid = "2792f1a3-b283-48e8-9a74-f99dce5104f3" +version = "0.1.0" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RingLists]] +deps = ["Random"] +git-tree-sha1 = "f39da63aa6d2d88e0c1bd20ed6a3ff9ea7171ada" +uuid = "286e9d63-9694-5540-9e3c-4e6708fa07b2" +version = "0.2.8" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.0" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.RoundingEmulator]] +git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" +uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" +version = "0.2.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.4" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SetRounding]] +git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" +uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +version = "0.2.1" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.ShaderAbstractions]] +deps = ["ColorTypes", "FixedPointNumbers", "GeometryBasics", "LinearAlgebra", "Observables", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "79123bc60c5507f035e6d1d9e563bb2971954ec8" +uuid = "65257c39-d410-5151-9873-9b3e5be5013e" +version = "0.4.1" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SignedDistanceFields]] +deps = ["Random", "Statistics", "Test"] +git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" +uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" +version = "0.4.0" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + +[[deps.SimpleGraphs]] +deps = ["AbstractLattices", "Combinatorics", "DataStructures", "IterTools", "LightXML", "LinearAlgebra", "LinearAlgebraX", "Optim", "Primes", "Random", "RingLists", "SimplePartitions", "SimplePolynomials", "SimpleRandom", "SparseArrays", "Statistics"] +git-tree-sha1 = "f65caa24a622f985cc341de81d3f9744435d0d0f" +uuid = "55797a34-41de-5266-9ec1-32ac4eb504d3" +version = "0.8.6" + +[[deps.SimplePartitions]] +deps = ["AbstractLattices", "DataStructures", "Permutations"] +git-tree-sha1 = "e182b9e5afb194142d4668536345a365ea19363a" +uuid = "ec83eff0-a5b5-5643-ae32-5cbf6eedec9d" +version = "0.3.2" + +[[deps.SimplePolynomials]] +deps = ["Mods", "Multisets", "Polynomials", "Primes"] +git-tree-sha1 = "7063828369cafa93f3187b3d0159f05582011405" +uuid = "cc47b68c-3164-5771-a705-2bc0097375a0" +version = "0.2.17" + +[[deps.SimpleRandom]] +deps = ["Distributions", "LinearAlgebra", "Random"] +git-tree-sha1 = "3a6fb395e37afab81aeea85bae48a4db5cd7244a" +uuid = "a6525b86-64cd-54fa-8f65-62fc48bdc0e8" +version = "0.3.1" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "2da10356e31327c7096832eb9cd86307a50b1eb6" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.3" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableHashTraits]] +deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "10dc702932fe05a0e09b8e5955f00794ea1e8b12" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.1.8" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.Static]] +deps = ["IfElse"] +git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "0.8.10" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.5.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.3" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.StaticPermutations]] +git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" +uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" +version = "0.3.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.3" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.1" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Strided]] +deps = ["LinearAlgebra", "StridedViews", "TupleTools"] +git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "2.0.4" + +[[deps.StridedViews]] +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" +uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" +version = "0.2.2" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.18" +weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = "GPUArraysCore" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TaylorSeries]] +deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] +git-tree-sha1 = "1c7170668366821b0c4c4fe03ee78f8d6cf36e2c" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.16.0" +weakdeps = ["IntervalArithmetic"] + + [deps.TaylorSeries.extensions] + TaylorSeriesIAExt = "IntervalArithmetic" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] +git-tree-sha1 = "34cc045dd0aaa59b8bbe86c644679bc57f1d5bd0" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.6.8" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.23" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.7" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.TriplotBase]] +git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" +uuid = "981d1d27-644d-49a2-9326-4793e63143c3" +version = "0.1.0" + +[[deps.TupleTools]] +git-tree-sha1 = "41d61b1c545b06279871ef1a4b5fcb2cac2191cd" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.5.0" + +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.2.1" + +[[deps.UnsafeAtomicsLLVM]] +deps = ["LLVM", "UnsafeAtomics"] +git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.3" + +[[deps.VersionParsing]] +git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.3.0" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.6+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.4.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.6+0" + +[[deps.isoband_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" +uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" +version = "0.2.3+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "46bf7be2917b59b761247be3f317ddf75e50e997" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.1.2+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.libevent_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll"] +git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" +uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" +version = "2.1.13+1" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.43+1" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] +git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.3+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.libzip_jll]] +deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "3282b7d16ae7ac3e57ec2f3fa8fafb564d8f9f7f" +uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" +version = "1.10.1+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[deps.prrte_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_jll"] +git-tree-sha1 = "5adb2d7a18a30280feb66cad6f1a1dfdca2dc7b0" +uuid = "eb928a42-fffd-568d-ab9c-3f5d54fc65b9" +version = "3.0.2+0" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" diff --git a/docs/make.jl b/docs/make.jl index 81bb2d65..9724e318 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,3 +1,5 @@ +pushfirst!(LOAD_PATH, joinpath(@__DIR__, "..")) # add ClimaOcean to environment stack + using Documenter, Literate, From 43229cbcd5183d5930e2966fe2b8b257d9275ff0 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 4 Apr 2024 13:51:59 +0300 Subject: [PATCH 164/182] fixes --- Manifest.toml | 2 +- src/DataWrangling/JRA55.jl | 24 ++++++++++++------------ test/test_downloading.jl | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 4a313174..d397c240 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -163,7 +163,7 @@ weakdeps = ["SparseArrays"] [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "6afd99a2cb2495792aaed92dc895ba78a3b82870" +git-tree-sha1 = "e25e43451edd449c3dcc899bd447983d7b76a59f" repo-rev = "main" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 87089caa..47849a71 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -268,18 +268,18 @@ Ocean Modelling, 2020, https://doi.org/10.1016/j.ocemod.2019.101557. The `variable_name`s (and their `shortname`s used in NetCDF files) available from the JRA55-do are: - - `:freshwater_river_flux` ("friver") - - `:rain_freshwater_flux` ("prra") - - `:snow_freshwater_flux` ("prsn") - - `:freshwater_iceberg_flux` ("licalvf") - - `:specific_humidity` ("huss") - - `:sea_level_pressure` ("psl") - - `:relative_humidity` ("rhuss") - - `:downwelling_longwave_radiation` ("rlds") - - `:downwelling_shortwave_radiation` ("rsds") - - `:temperature` ("ras") - - `:eastward_velocity` ("uas") - - `:northward_velocity` ("vas") + - `:freshwater_river_flux` ("friver") + - `:rain_freshwater_flux` ("prra") + - `:snow_freshwater_flux` ("prsn") + - `:freshwater_iceberg_flux` ("licalvf") + - `:specific_humidity` ("huss") + - `:sea_level_pressure` ("psl") + - `:relative_humidity` ("rhuss") + - `:downwelling_longwave_radiation` ("rlds") + - `:downwelling_shortwave_radiation` ("rsds") + - `:temperature` ("ras") + - `:eastward_velocity` ("uas") + - `:northward_velocity` ("vas") Keyword arguments ================= diff --git a/test/test_downloading.jl b/test/test_downloading.jl index 128efcb3..6ff308f4 100644 --- a/test/test_downloading.jl +++ b/test/test_downloading.jl @@ -2,7 +2,7 @@ include("runtests_setup.jl") @testset "Availability of JRA55 data" begin @info "Testing that we can download all the JRA55 data..." - for name in ClimaOcean.DataWrangling.JRA55.jra55_short_names - fts = ClimaOcean.JRA55.jra55_field_time_series(name; time_indices=1:1) + for name in ClimaOcean.DataWrangling.JRA55.JRA55_variable_names + fts = ClimaOcean.JRA55.JRA55_field_time_series(name; time_indices=1:1) end end From d35ef1178aa591601f70ff15bd63ee7423be26c0 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sun, 7 Apr 2024 13:18:57 +0300 Subject: [PATCH 165/182] use ClimaSeaIce v0.1 --- Manifest.toml | 4 +--- Project.toml | 1 + docs/Project.toml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index d397c240..fb4227f0 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.2" manifest_format = "2.0" -project_hash = "64b3862ff4f09c6ae71318d88c2bbc084ba4e0f1" +project_hash = "b77431445966c6920fb04c6ab1b5a7dbdaa668aa" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -164,8 +164,6 @@ weakdeps = ["SparseArrays"] [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] git-tree-sha1 = "e25e43451edd449c3dcc899bd447983d7b76a59f" -repo-rev = "main" -repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" diff --git a/Project.toml b/Project.toml index b1a5bfc4..32e35584 100644 --- a/Project.toml +++ b/Project.toml @@ -25,6 +25,7 @@ Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" [compat] CUDA = "4, 5" +ClimaSeaIce = "0.1" CubicSplines = "0.2" DataDeps = "0.7" Downloads = "1.6" diff --git a/docs/Project.toml b/docs/Project.toml index 369e2aeb..d7cbe6e6 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -9,4 +9,4 @@ Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" CairoMakie = "0.10.12" DataDeps = "0.7" Documenter = "1" -Oceananigans = "0.90.10" \ No newline at end of file +Oceananigans = "0.90.10" From c75dfdd785147f03723ece1ec59ae56f44292c8d Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 11 Apr 2024 13:06:25 +0300 Subject: [PATCH 166/182] some fixes; still not all tests pass --- Manifest.toml | 6 ++---- examples/surface_flux_computation.jl | 1 - src/DataWrangling/JRA55.jl | 4 ++++ test/test_downloading.jl | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index fb4227f0..7078111f 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -781,9 +781,9 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "Glob", "IncompleteLU", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "LinearAlgebra", "Logging", "MPI", "NCDatasets", "OffsetArrays", "OrderedCollections", "PencilArrays", "PencilFFTs", "Pkg", "Printf", "Random", "Rotations", "SeawaterPolynomials", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "4672af7242405313743af45168bfce3d87b84b2c" +git-tree-sha1 = "aa709412dbde10fe375e4b729fc903166e7669bd" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.11" +version = "0.90.12" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -1224,8 +1224,6 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" -repo-rev = "main" -repo-url = "https://github.com/CliMA/Thermodynamics.jl.git" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" version = "0.12.6" diff --git a/examples/surface_flux_computation.jl b/examples/surface_flux_computation.jl index 33cbf85d..9b786df6 100644 --- a/examples/surface_flux_computation.jl +++ b/examples/surface_flux_computation.jl @@ -99,4 +99,3 @@ values = SurfaceFluxes.ValuesOnly(atmos_dynamic_state, buoyancy_roughness_length) conditions = SurfaceFluxes.surface_conditions(surface_flux_parameters, values) - diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 47849a71..8ad87344 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -461,6 +461,9 @@ function JRA55_field_time_series(variable_name; copyto!(interior(native_fts, :, :, 1, :), data) fill_halo_regions!(native_fts) + @show on_native_grid + @show totally_in_memory + if on_native_grid && totally_in_memory return native_fts @@ -472,6 +475,7 @@ function JRA55_field_time_series(variable_name; end end + @show totally_in_memory @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(fts.grid; diff --git a/test/test_downloading.jl b/test/test_downloading.jl index 6ff308f4..7bc53331 100644 --- a/test/test_downloading.jl +++ b/test/test_downloading.jl @@ -3,6 +3,6 @@ include("runtests_setup.jl") @testset "Availability of JRA55 data" begin @info "Testing that we can download all the JRA55 data..." for name in ClimaOcean.DataWrangling.JRA55.JRA55_variable_names - fts = ClimaOcean.JRA55.JRA55_field_time_series(name; time_indices=1:1) + fts = ClimaOcean.JRA55.JRA55_field_time_series(name; time_indices=2:3) end end From f230f06e6320af480e6cee18efc8be1abf3fea86 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Thu, 11 Apr 2024 18:34:25 +0300 Subject: [PATCH 167/182] Update src/DataWrangling/JRA55.jl Co-authored-by: Simone Silvestri --- src/DataWrangling/JRA55.jl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 8ad87344..66e8a9fe 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -477,12 +477,13 @@ function JRA55_field_time_series(variable_name; @show totally_in_memory @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." + preprocessing_grid = on_native_grid ? JRA55_native_grid : grid - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(fts.grid; - boundary_conditions, - backend = OnDisk(), - path = jld2_filename, - name = fts_name) + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid; + boundary_conditions, + backend = OnDisk(), + path = jld2_filename, + name = fts_name) # Re-open the dataset! ds = Dataset(filename) From 3c47d887659d81e0caed6c9df41b7438e1f1cd52 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:48:38 -0400 Subject: [PATCH 168/182] fixed the docs --- src/DataWrangling/ECCO2.jl | 83 ++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 526536d1..e4ac88b7 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -87,7 +87,7 @@ const ECCO2_z = [ 0.0, ] -filenames_19920102 = Dict( +ecco2_file_names = Dict( :temperature => "THETA.1440x720x50.19920102.nc", :salinity => "SALT.1440x720x50.19920102.nc", :sea_ice_thickness => "SIheff.1440x720.19920102.nc", @@ -96,13 +96,22 @@ filenames_19920102 = Dict( :v_velocity => "VVEL.1440x720.19920102.nc", ) -filenames_19921001 = Dict( - :temperature => "THETA.1440x720x50.19921001.nc", - :salinity => "SALT.1440x720x50.19921001.nc", - :sea_ice_thickness => "SIheff.1440x720.19921001.nc", - :sea_ice_area_fraction => "SIarea.1440x720.19921001.nc", - :u_velocity => "UVEL.1440x720.19921001.nc", - :v_velocity => "VVEL.1440x720.19921001.nc", +variable_is_three_dimensional = Dict( + :temperature => true, + :salinity => true, + :u_velocity => true, + :v_velocity => true, + :sea_ice_thickness => false, + :sea_ice_area_fraction => false, +) + +ecco2_short_names = Dict( + :temperature => "THETA", + :salinity => "SALT", + :u_velocity => "UVEL", + :v_velocity => "VVEL", + :sea_ice_thickness => "SIheff", + :sea_ice_area_fraction => "SIarea" ) ecco2_location = Dict( @@ -119,7 +128,7 @@ ecco2_depth_names = Dict( :salinity => "DEPTH_T", ) -urls_19920102 = Dict( +ecco2_urls = Dict( :temperature => "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs", :salinity => "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw", :sea_ice_thickness => "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am", @@ -128,25 +137,6 @@ urls_19920102 = Dict( :v_velocity => "https://www.dropbox.com/scl/fi/buic35gssyeyfqohenkeo/VVEL.1440x720x50.19920102.nc?rlkey=fau48w4t5ruop4s6gm8t7z0a0", ) -urls_19921001 = Dict( - :temperature => "https://www.dropbox.com/scl/fi/169f3981460uhk9h69k0f/THETA.1440x720x50.19921001.nc?rlkey=mgal3xt0qy2c59y395ybio11v", - :salinity => "https://www.dropbox.com/scl/fi/f9zfm34vqz732jrrhjrg3/SALT.1440x720x50.19921001.nc?rlkey=y5dv0s41gb6f9guvu0iorw28p", - :sea_ice_thickness => "https://www.dropbox.com/scl/fi/mtmziurepom8kpjn82d07/SIheff.1440x720.19921001.nc?rlkey=9uhuxg2n9iw6894afj4t53drv", - :sea_ice_area_fraction => "https://www.dropbox.com/scl/fi/ntflhyrmsnit9vco402co/SIarea.1440x720.19921001.nc?rlkey=eakzc788btql1q6ndj9l8cr2q", - #:u_velocity => "https://www.dropbox.com/scl/fi/e6s9c013r2ddift4f8ugi/UVEL.1440x720x50.19921001.nc?rlkey=fpd7mv1zv3fkmyg8w11b94sbp&dl=0", - :u_velocity => "https://www.dropbox.com/scl/fi/e6s9c013r2ddift4f8ugi/UVEL.1440x720x50.19921001.nc?rlkey=fpd7mv1zv3fkmyg8w11b94sbp&dl=0", - :v_velocity => "https://www.dropbox.com/scl/fi/nxuohvhvdu0ig552osf1d/VVEL.1440x720x50.19921001.nc?rlkey=vz4ttp3myxhertdxvt1lyjp1d", -) - -filenames = Dict( - "1992-01-02" => filenames_19920102, - "1992-10-01" => filenames_19921001, -) - -urls = Dict( - "1992-01-02" => urls_19920102, - "1992-10-01" => urls_19921001, -) shortnames = Dict( :temperature => "THETA", @@ -159,6 +149,33 @@ shortnames = Dict( surface_variable(variable_name) = variable_name == :sea_ice_thickness +""" + construct_vertical_interfaces(ds, depth_name) + +Constructs vertical interfaces for a given dataset `ds` and depth variable `depth_name`. + +# Arguments +- `ds`: The dataset containing the depth variable. +- `depth_name`: The name of the depth variable in the dataset. + +# Returns +- `zf`: An array of interface depths. +""" +function construct_vertical_interfaces(ds, depth_name) + # Construct vertical coordinate + depth = ds[depth_name][:] + zc = -reverse(depth) + + # Interface depths from cell center depths + zf = (zc[1:end-1] .+ zc[2:end]) ./ 2 + push!(zf, 0) + + Δz = zc[2] - zc[1] + pushfirst!(zf, zf[1] - Δz) + + return zf +end + function empty_ecco2_field(data::ECCO2Metadata; architecture = CPU(), horizontal_halo = (1, 1)) @@ -167,13 +184,9 @@ function empty_ecco2_field(data::ECCO2Metadata; location = ecco2_location[variable_name] - grid = LatitudeLongitudeGrid(architecture, - size = (ECCO2_Nx, ECCO2_Ny, ECCO2_Nz), - longitude = (0, 360), - latitude = (-90, 90), - z = ECCO2_z, - halo = (1, 1, 1), - topology = (Periodic, Bounded, Bounded)) + longitude = (0, 360) + latitude = (-90, 90) + TX, TY = (Periodic, Bounded) filename = ecco2_file_names[variable_name] From 9731163d264bcf8bfed86b89f4432fd1dee50067 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:11:13 -0400 Subject: [PATCH 169/182] updated Oceananigans to #main --- Manifest.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index 7078111f..de7f1d1e 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -781,7 +781,9 @@ 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 = "aa709412dbde10fe375e4b729fc903166e7669bd" +git-tree-sha1 = "82eddd14528a13419be8b75da9daa23fb2a14363" +repo-rev = "main" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.12" From 256cabb9a70bb6734b42b00fc66b748e00187754 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:26:12 -0400 Subject: [PATCH 170/182] text fix --- test/test_ecco2.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_ecco2.jl b/test/test_ecco2.jl index 278dc2bf..abbebec2 100644 --- a/test/test_ecco2.jl +++ b/test/test_ecco2.jl @@ -24,8 +24,8 @@ using Oceananigans.Grids: topology @test Ny == 720 @test Nz == 50 - ice_thickness_filename = ECCO2.ecco2_file_names[:effective_ice_thickness] - ecco2_ice_thickness = ECCO2.ecco2_field(:effective_ice_thickness; architecture=arch) + ice_thickness_filename = ECCO2.ecco2_file_names[:sea_ice_thickness] + ecco2_ice_thickness = ECCO2.ecco2_field(:sea_ice_thickness; architecture=arch) @test isfile(ice_thickness_filename) rm(ice_thickness_filename) From 7899dd35069d0081d049cfbb699506742bb3f7ac Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:29:53 -0400 Subject: [PATCH 171/182] fixed all tests --- src/DataWrangling/JRA55.jl | 5 +++++ test/test_jra55.jl | 8 -------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 66e8a9fe..e892089b 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -322,6 +322,11 @@ function JRA55_field_time_series(variable_name; preprocess_architecture = CPU(), time_indices = nothing) + if backend isa OnDisk + msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") + throw(ArgumentError(msg)) + end + if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) variables_msg = prod(variable_strs) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 55c9cd30..0ead54af 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -36,14 +36,6 @@ include("runtests_setup.jl") @info "Testing preprocessing JRA55 data on $A..." rm(test_jld2_filename, force=true) - on_disk_jra55_fts = ClimaOcean.JRA55.JRA55_field_time_series(test_name; - architecture = arch, - backend = OnDisk(), - time_indices) - - @test on_disk_jra55_fts isa FieldTimeSeries - @test parent(on_disk_jra55_fts[1]) == parent(jra55_fts[1]) - @info "Testing loading preprocessed JRA55 data on $A..." in_memory_jra55_fts = ClimaOcean.JRA55.JRA55_field_time_series(test_name; architecture = arch, From 9ac4f27e0eef5e7b7909b0ad7e33af738b5dc116 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:31:11 -0400 Subject: [PATCH 172/182] Removed methods that already exist in oceananigans --- src/DataWrangling/DataWrangling.jl | 39 ------------------------------ 1 file changed, 39 deletions(-) diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index fb2a5b4a..706c7dcf 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -52,45 +52,6 @@ end ##### FieldTimeSeries utilities ##### -# TODO: move this to Oceananigans - -@kernel function _interpolate_field_time_series!(target_fts, target_grid, target_location, - source_fts, source_grid, source_location) - - # 4D index, cool! - i, j, k, n = @index(Global, NTuple) - - source_field = view(source_fts, :, :, :, n) - target_node = node(i, j, k, target_grid, target_location...) - - @inbounds target_fts[i, j, k, n] = interpolate(target_node, source_field, source_location, source_grid) -end - -function interpolate_field_time_series!(target_fts, source_fts) - @assert target_fts.times == source_fts.times - times = target_fts.times - Nt = length(times) - - target_grid = target_fts.grid - source_grid = source_fts.grid - - @assert architecture(target_grid) == architecture(source_grid) - arch = architecture(target_grid) - - # Make locations - source_location = Tuple(L() for L in location(source_fts)) - target_location = Tuple(L() for L in location(target_fts)) - - launch!(arch, target_grid, size(target_fts), - _interpolate_field_time_series!, - target_fts.data, target_grid, target_location, - source_fts.data, source_grid, source_location) - - fill_halo_regions!(target_fts) - - return nothing -end - function save_field_time_series!(fts; path, name, overwrite_existing=false) overwrite_existing && rm(path; force=true) times = fts.times From 44cd894b69e57d23a077dc392aac113ea94260dd Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 23 Apr 2024 23:08:37 -0400 Subject: [PATCH 173/182] now everything should work --- .../PrescribedAtmospheres.jl | 205 ----------- sandbox/one_degree_75S_75N.jl | 333 ------------------ src/DataWrangling/JRA55.jl | 109 +++--- 3 files changed, 59 insertions(+), 588 deletions(-) delete mode 100644 sandbox/PrescribedAtmospheres/PrescribedAtmospheres.jl delete mode 100755 sandbox/one_degree_75S_75N.jl diff --git a/sandbox/PrescribedAtmospheres/PrescribedAtmospheres.jl b/sandbox/PrescribedAtmospheres/PrescribedAtmospheres.jl deleted file mode 100644 index 301cc2c1..00000000 --- a/sandbox/PrescribedAtmospheres/PrescribedAtmospheres.jl +++ /dev/null @@ -1,205 +0,0 @@ -module AtmosphericForcings - -export PrescribedAtmosphere, PrescribedFluxes - -using Adapt -using Oceananigans -using Oceananigans.Utils -using Oceananigans.BoundaryConditions: getbc -using KernelAbstractions: @kernel, @index - -import IceOceanModel: compute_air_sea_fluxes! - -abstract type AbstractAtmospericForcing end - -# We generally have 2 types of atmospheric forcing: Prescribed fluxes and -# Prescribed atmospheric state (to treat with bulk formulae) -# This implementation also allows to have in future a prognostic atmospheric model - -# Prescribed fluxes can be arrays, fields, of functions. -# When functions, the signature should be -# `f(i, j, grid, clock, fields)` where `fields` are the ocean model's prognostic fields -# in case of OnyOceanModel and the coupled model's prognostic fields in case of an `IceOceanModel` -# Parameters can be implemented using callable structs that subtype `Function` -struct PrescribedFluxes{T, S, U, V} <: AbstractAtmospericForcing - heat_flux :: T # heat flux - freshwater_flux :: S # freshwater flux - zonal_stress :: U # zonal stress - meriodional_stress :: V # meriodional stress -end - -Adapt.adapt_structure(to, f::PrescribedFluxes) = - PrescribedFluxes(Adapt.adapt(to, f.heat_flux), - Adapt.adapt(to, f.freshwater_flux), - Adapt.adapt(to, f.zonal_stress), - Adapt.adapt(to, f.meriodional_stress)) - -# Here we leverage a `getflux` function similar to the `getbc` from Oceananigans.jl to extract the fluxes, -# In this way we allow prescribed fluxes as well as relaxation fluxes -@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, - grid, clock, fields, ice_thickness, solar_insolation, f::PrescribedFluxes) - i, j = @index(Global, NTuple) - @inbounds begin - I₀ = solar_insolation[i, j, 1] - Qˢ[i, j] = getflux(ice_thickness, f.heat_flux, i, j, grid, clock, fields) + ε * I₀ / (ρₒ * cₒ) - Fˢ[i, j] = getflux(ice_thickness, f.freshwater_fluxes, i, j, grid, clock, fields) - τˣ[i, j] = getflux(ice_thickness, f.zonal_stress, i, j, grid, clock, fields) - τʸ[i, j] = getflux(ice_thickness, f.meriodional_stress, i, j, grid, clock, fields) - end -end - -struct PrescribedAtmosphere{R, H, P, W, T, Q, D, C, G} <: AbstractAtmospericForcing - adiabatic_lapse_rate :: R # - - atmosphere_state_height :: H # m - reference_height :: H # m - surface_pressure :: P # Pa - atmosphere_velocities :: W # (m/s, m/s) - air_temperature :: T # deg ᵒC - air_humidity :: Q # kg/m³ - air_density :: D # kg/m³ - cloud_cover_feedback :: C # - - gamma_air :: C # - -end - -# The atmospheric state (T, u, v, q, ρ and p) can be composed of Values, Arrays, Functions, Fields or FieldTimeSerieses -function PrescribedAtmosphere(; - adiabatic_lapse_rate = 0.08, - atmosphere_state_height = 10, # m - reference_height = 10, # m - surface_pressure = 1e5, # Pa - atmosphere_velocities, # (m/s, m/s) - air_temperature, # deg ᵒC - air_humidity = 0.01, # kg/m³ - air_density = 1.25, # kg/m³ - cloud_cover_coeff = 0.8, - gamma_air = 0.01) - - return PrescribedAtmosphere(adiabatic_lapse_rate, - atmosphere_state_height, - reference_height, - surface_pressure, - atmosphere_velocities, - air_temperature, - air_humidity, - air_density, - cloud_cover_coeff, - gamma_air) -end - -Adapt.adapt_structure(to, f::PrescribedAtmosphere) = - PrescribedAtmosphere(Adapt.adapt(to, f.adiabatic_lapse_rate), - Adapt.adapt(to, f.atmosphere_state_height), - Adapt.adapt(to, f.reference_height), - Adapt.adapt(to, f.surface_pressure), - Adapt.adapt(to, f.atmosphere_velocities), - Adapt.adapt(to, f.air_temperature), - Adapt.adapt(to, f.air_humidity), - Adapt.adapt(to, f.air_density), - Adapt.adapt(to, f.cloud_cover_feedback), - Adapt.adapt(to, f.gamma_air)) - -@inline clausius_clapeyron(FT, Tₛ) = convert(FT, 611.2) * exp(convert(FT, 17.67) * Tₛ / (Tₛ + convert(FT, 243.5))) - -# Follows MITgcm, this is kind of a Placeholder for now. I ll check the literature for a correct parameterization -@kernel function _calculate_air_sea_fluxes!(Qˢ, Fˢ, τˣ, τʸ, ε, ρₒ, cₒ, - grid, clock, fields, ice_thickness, f::PrescribedAtmosphere) - - hᵀ = f.atmosphere_state_height - α = f.adiabatic_lapse_rate - uˢ, vˢ = f.atmosphere_velocities - - Tₐ = getflux(f.air_temperature, i, j, grid, clock, fields) - uₐ = getflux(uˢ, i, j, grid, clock, fields) - vₐ = getflux(vˢ, i, j, grid, clock, fields) - qₐ = getflux(f.air_humidity, i, j, grid, clock, fields) - ρₐ = getflux(f.air_density, i, j, grid, clock, fields) - p₀ = getflux(f.surface_pressure, i, j, grid, clock, fields) - - h = getflux(ice_thickness, i, j, grid, clock, fields) - ice_cell = (h == nothing) | (h > 0) - - @inbounds I₀ = solar_insolation[i, j, 1] - - FT = eltype(grid) - - speed = sqrt(uₐ^2 + vₐ^2) # speed m / s - γ = f.gamma_air - - # Physical constants - σ = convert(FT, σᴮ) # W/m²/K⁴ Stefan-Boltzmann constant - ℒ = convert(FT, ℒₑ) # J/kg Latent heat of evaporation - - Tₛ = fields.T[i, j, grid.Nz] - T₀ = Tₐ * (1 - γ * qₐ) - - # sea-air temperature difference - ΔT = T₀ - Tₛ + α*hᵀ - - # saturation vapour pressure (Pa) - eₛ = clausius_clapeyron(FT, Tₛ) - - # saturation air humidity (kg/m³) - qₛ = convert(FT, 0.622) * eₛ / (p₀ - eₛ) - - # air excess humidity - Δq = qₐ - qₛ - - # Turbulent heat transfer coefficients - Cᵀ, Cᵁ, Cq = turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) - - # sensible heat flux (W/m²) - H = ρₐ * speed * Cᵀ * Cᵁ * ΔT - - # latent heat flux (W/m²) - L = ρₐ * speed * Cq * Cᵁ * Δq * ℒ - - # net longwave radiation (W/m²) - Rₙ = ε * σ * (Tₛ + convert(FT, 273.15))^4 * (1 - f.cloud_cover_feedback) - - @inbounds begin - Qˢ[i, j, 1] = ifelse(ice_cell, zero(grid), (H + L + Rₙ + I₀ * ε) / (ρₒ * cₒ)) - # Fˢ[i, j, 1] = L / ℒ - τˣ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * speed * Cᵁ * uₐ / ρₒ) - τʸ[i, j, 1] = ifelse(ice_cell, zero(grid), ρₐ * speed * Cᵁ * vₐ / ρₒ) - end - - return nothing -end - -@inline turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) = (1e-3, 1e-3, 1e-3) - -#= -# Follows MITgcm (https://mitgcm.readthedocs.io/en/latest/phys_pkgs/bulk_force.html) -@inline function turbulent_heat_transfer_coefficients(FT, f, T₀, qₐ, uₛ, ΔT, Δq) - hᵀ = f.atmosphere_state_height - zᴿ = f.reference_height - λ = log(hᵀ / zᴿ) - κ = convert(FT, 0.4) # von Karman constant - - Cᵀ = Cᵁ = Cq = κ / log(zᴿ * 2) - u★ = Cᵁ * uₛ - T★ = Cᵀ * ΔT - q★ = Cq * Δq - - @unroll for iter in 1:5 - G = Γ(FT, u★, T★, q★, T₀, qₐ, f) - χ = sqrt(1 - 16 * G) - - ψˢ = ifelse(G > 0, -5G, 2 * log((1 + χ^2) / 2)) - ψᵐ = ifelse(G > 0, -5G, 2 * log((1 + χ) / 2) + ψˢ / 2 - 2 * atan(χ) + convert(FT, π/2)) - - Cᵁ = Cᵁ / (1 + Cᵁ * (λ - ψᵐ) / κ) - Cᵀ = Cᵀ / (1 + Cᵀ * (λ - ψˢ) / κ) - u★ = Cᵁ * uₛ - T★ = Cᵀ * ΔT - q★ = Cq * Δq - end - - return Cᵀ, Cᵁ, Cq -end -=# - -@inline Γ(FT, u★, T★, q★, T₀, qₐ, f) = convert(FT, 0.41) * convert(FT, 9.80655) * f.reference_height / u★^2 * - (T★ / T₀ - q★ / (1/f.gamma_air - qₐ)) - -end diff --git a/sandbox/one_degree_75S_75N.jl b/sandbox/one_degree_75S_75N.jl deleted file mode 100755 index 9d811165..00000000 --- a/sandbox/one_degree_75S_75N.jl +++ /dev/null @@ -1,333 +0,0 @@ -using ClimaOcean - -using Oceananigans -using Oceananigans.Units - -using Oceananigans.Operators: Δzᵃᵃᶜ -using Oceananigans.Architectures: on_architecture -using Oceananigans.Coriolis: HydrostaticSphericalCoriolis -using Oceananigans.Coriolis: WetCellEnstrophyConservingScheme -using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity, FluxTapering - -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: - CATKEVerticalDiffusivity, MixingLength - -using Statistics -using JLD2 -using Printf -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState -using CUDA: @allowscalar - -# 1 degree resolution -Nx = 360 -Ny = 150 -Nz = 48 - -arch = GPU() -reference_density = 1029.0 -reference_heat_capacity = 3991.0 -reference_salinity = 34.0 - -output_prefix = "./near_global_lat_lon_$(Nx)_$(Ny)_$(Nz)_fine" -pickup = false -save_interval = 5days - -##### -##### Load surface boundary conditions and inital conditions -##### from ECCO version 4: -##### https://ecco.jpl.nasa.gov/drive/files -##### -##### Bathymetry is interpolated from ETOPO1: -##### https://www.ngdc.noaa.gov/mgg/global/ -##### - -bathymetry_file = jldopen("bathymetry_360_150_75S_75N.jld2") -bathymetry = bathymetry_file["bathymetry"] -close(bathymetry_file) - -@info "Reading initial conditions..."; start=time_ns() -initial_conditions_file = jldopen("initial_conditions_360_150_48_75S_75N.jld2") -T_init = initial_conditions_file["T"] -S_init = initial_conditions_file["S"] -close(initial_conditions_file) -@info "... read initial conditions (" * prettytime(1e-9 * (time_ns() - start)) * ")" - -# Files contain 12 arrays of monthly-averaged data from 1992 -@info "Reading boundary conditions..."; start=time_ns() -boundary_conditions_file = jldopen("surface_boundary_conditions_360_150_75S_75N.jld2") -τˣ = - boundary_conditions_file["τˣ"] ./ reference_density -τʸ = - boundary_conditions_file["τʸ"] ./ reference_density -T★ = + boundary_conditions_file["Tₛ"] -S★ = + boundary_conditions_file["Sₛ"] -Q★ = - boundary_conditions_file["Qᶠ"] ./ reference_density ./ reference_heat_capacity -F★ = - boundary_conditions_file["Sᶠ"] ./ reference_density .* reference_salinity -close(boundary_conditions_file) -@info "... read boundary conditions (" * prettytime(1e-9 * (time_ns() - start)) * ")" - -# Convert boundary conditions arrays to GPU -τˣ = on_architecture(arch, τˣ) -τʸ = on_architecture(arch, τʸ) -target_sea_surface_temperature = T★ = on_architecture(arch, T★) -target_sea_surface_salinity = S★ = on_architecture(arch, S★) -surface_temperature_flux = Q★ = on_architecture(arch, Q★) -surface_salt_flux = F★ = on_architecture(arch, F★) - -# Stretched faces from ECCO Version 4 (49 levels in the vertical) -z_faces = ClimaOcean.VerticalGrids.z_49_levels_10_to_400_meter_spacing - -# A spherical domain -underlying_grid = LatitudeLongitudeGrid(arch, - size = (Nx, Ny, Nz), - longitude = (-180, 180), - latitude = (-75, 75), - halo = (5, 5, 5), - z = z_faces) - -grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bathymetry)) - -@info "Created $grid" - -##### -##### Physics and model setup -##### - -const surface_νz = 1e-2 -const background_νz = 1e-4 -const background_κz = 1e-5 - -@inline νz(x, y, z, t) = ifelse(z > -49, surface_νz, background_νz) - -horizontal_viscosity = HorizontalScalarDiffusivity(ν=5e4) -vertical_mixing = RiBasedVerticalDiffusivity() -vertical_viscosity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), - ν=νz, κ=background_κz) - -κ_skew = 900.0 # [m² s⁻¹] skew diffusivity -κ_symmetric = 900.0 # [m² s⁻¹] symmetric diffusivity - -gent_mcwilliams_diffusivity = IsopycnalSkewSymmetricDiffusivity(; κ_skew, κ_symmetric, - slope_limiter = FluxTapering(1e-2)) - -#closures = gent_mcwilliams_diffusivity - -closures = ( - vertical_viscosity, - horizontal_viscosity, - vertical_mixing, - gent_mcwilliams_diffusivity, -) - -##### -##### Boundary conditions / time-dependent fluxes -##### - -const Nyears = 2.0 -const Nmonths = 12 -const thirty_days = 30days - -@inline current_time_index(time, tot_months) = mod(unsafe_trunc(Int32, time / thirty_days), tot_months) + 1 -@inline next_time_index(time, tot_months) = mod(unsafe_trunc(Int32, time / thirty_days) + 1, tot_months) + 1 -@inline cyclic_interpolate(u₁::Number, u₂, time) = u₁ + mod(time / thirty_days, 1) * (u₂ - u₁) - -Δz_top = @allowscalar Δzᵃᵃᶜ(1, 1, grid.Nz, grid.underlying_grid) -Δz_bottom = @allowscalar Δzᵃᵃᶜ(1, 1, 1, grid.underlying_grid) - -@inline function surface_wind_stress(i, j, grid, clock, fields, τ) - time = clock.time - n₁ = current_time_index(time, Nmonths) - n₂ = next_time_index(time, Nmonths) - - @inbounds begin - τ₁ = τ[i, j, n₁] - τ₂ = τ[i, j, n₂] - end - - return cyclic_interpolate(τ₁, τ₂, time) -end - -Δz_top = @allowscalar grid.Δzᵃᵃᶜ[Nz] - -using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ - -# Linear bottom drag: -μ = 0.003 # Non dimensional - -@inline speedᶠᶜᶜ(i, j, k, grid, fields) = @inbounds sqrt(fields.u[i, j, k]^2 + ℑxyᶠᶜᵃ(i, j, k, grid, fields.v)^2) -@inline speedᶜᶠᶜ(i, j, k, grid, fields) = @inbounds sqrt(fields.v[i, j, k]^2 + ℑxyᶜᶠᵃ(i, j, k, grid, fields.u)^2) - -@inline u_bottom_drag(i, j, grid, clock, fields, μ) = @inbounds - μ * fields.u[i, j, 1] * speedᶠᶜᶜ(i, j, 1, grid, fields) -@inline v_bottom_drag(i, j, grid, clock, fields, μ) = @inbounds - μ * fields.v[i, j, 1] * speedᶜᶠᶜ(i, j, 1, grid, fields) - -@inline u_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.u[i, j, k] * speedᶠᶜᶜ(i, j, k, grid, fields) -@inline v_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.v[i, j, k] * speedᶜᶠᶜ(i, j, k, grid, fields) - -drag_u = FluxBoundaryCondition(u_immersed_bottom_drag, discrete_form=true, parameters = μ) -drag_v = FluxBoundaryCondition(v_immersed_bottom_drag, discrete_form=true, parameters = μ) - -no_slip_bc = ValueBoundaryCondition(0) - -u_immersed_bc = ImmersedBoundaryCondition(bottom = drag_u, - west = no_slip_bc, - east = no_slip_bc, - south = no_slip_bc, - north = no_slip_bc) - -v_immersed_bc = ImmersedBoundaryCondition(bottom = drag_v, - west = no_slip_bc, - east = no_slip_bc, - south = no_slip_bc, - north = no_slip_bc) - -u_bottom_drag_bc = FluxBoundaryCondition(u_bottom_drag, discrete_form = true, parameters = μ) -v_bottom_drag_bc = FluxBoundaryCondition(v_bottom_drag, discrete_form = true, parameters = μ) - -u_wind_stress_bc = FluxBoundaryCondition(surface_wind_stress, discrete_form = true, parameters = τˣ); -v_wind_stress_bc = FluxBoundaryCondition(surface_wind_stress, discrete_form = true, parameters = τʸ); - -@inline function surface_temperature_relaxation(i, j, grid, clock, fields, p) - time = clock.time - - n₁ = current_time_index(time, Nmonths) - n₂ = next_time_index(time, Nmonths) - - @inbounds begin - T★₁ = p.T★[i, j, n₁] - T★₂ = p.T★[i, j, n₂] - Q★₁ = p.Q★[i, j, n₁] - Q★₂ = p.Q★[i, j, n₂] - T_surface = fields.T[i, j, grid.Nz] - end - - T★ = cyclic_interpolate(T★₁, T★₂, time) - Q★ = cyclic_interpolate(Q★₁, Q★₂, time) - - return Q★ + p.λ * (T_surface - T★) -end - -@inline function surface_salinity_relaxation(i, j, grid, clock, fields, p) - time = clock.time - - n₁ = current_time_index(time, Nmonths) - n₂ = next_time_index(time, Nmonths) - - @inbounds begin - S★₁ = p.S★[i, j, n₁] - S★₂ = p.S★[i, j, n₂] - F★₁ = p.F★[i, j, n₁] - F★₂ = p.F★[i, j, n₂] - S_surface = fields.S[i, j, grid.Nz] - end - - S★ = cyclic_interpolate(S★₁, S★₂, time) - F★ = cyclic_interpolate(F★₁, F★₂, time) - - return - F★ + p.λ * (S_surface - S★) -end - -T_relaxation_parameters = (λ = Δz_top/30days, - T★ = target_sea_surface_temperature, - Q★ = surface_temperature_flux) - -S_relaxation_parameters = (λ = Δz_top/90days, - S★ = target_sea_surface_salinity, - F★ = surface_salt_flux) - -T_surface_relaxation_bc = FluxBoundaryCondition(surface_temperature_relaxation, - discrete_form = true, - parameters = T_relaxation_parameters) - -S_surface_relaxation_bc = FluxBoundaryCondition(surface_salinity_relaxation, - discrete_form = true, - parameters = S_relaxation_parameters) - -u_bcs = FieldBoundaryConditions(top = u_wind_stress_bc, - bottom = u_bottom_drag_bc, - immersed = u_immersed_bc) - -v_bcs = FieldBoundaryConditions(top = v_wind_stress_bc, - bottom = v_bottom_drag_bc, - immersed = v_immersed_bc) - -T_bcs = FieldBoundaryConditions(top = T_surface_relaxation_bc) -S_bcs = FieldBoundaryConditions(top = S_surface_relaxation_bc) - -equation_of_state = TEOS10EquationOfState(; reference_density) -#equation_of_state = LinearEquationOfState() -buoyancy = SeawaterBuoyancy(; equation_of_state) -coriolis = HydrostaticSphericalCoriolis(scheme = WetCellEnstrophyConservingScheme()) -free_surface = ImplicitFreeSurface() - -@info "Building a model..."; start=time_ns() - -model = HydrostaticFreeSurfaceModel(; grid, free_surface, buoyancy, coriolis, - momentum_advection = VectorInvariant(), - tracer_advection = WENO(underlying_grid), - closure = closures, - boundary_conditions = (u=u_bcs, v=v_bcs, T=T_bcs, S=S_bcs), - tracers = (:T, :S)) -@info "... built $model." -@info "Model building time: " * prettytime(1e-9 * (time_ns() - start)) - -##### -##### Initial condition: -##### - -set!(model, T=T_init, S=S_init) - -# Because JMC's forcing starts at Jan 15 -model.clock.time = 345days - -##### -##### Simulation setup -##### - -Δt = 20minutes -simulation = Simulation(model; Δt, stop_iteration=100) #stop_time=Nyears * years) - -start_time = [time_ns()] - -function progress(sim) - wall_time = (time_ns() - start_time[1]) * 1e-9 - - u = sim.model.velocities.u - w = sim.model.velocities.w - - intw = Array(interior(w)) - max_w = findmax(intw) - - mw = max_w[1] - iw = max_w[2] - - @info @sprintf("Time: % 12s, iteration: %d, max(|u|): %.2e ms⁻¹, wmax: %.2e , loc: (%d, %d, %d), wall time: %s", - prettytime(sim.model.clock.time), - sim.model.clock.iteration, maximum(abs, u), mw, iw[1], iw[2], iw[3], - prettytime(wall_time)) - - start_time[1] = time_ns() - - return nothing -end - -simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -u, v, w = model.velocities -T = model.tracers.T -S = model.tracers.S - -simulation.output_writers[:surface_fields] = - JLD2OutputWriter(model, (; u, v, w, T, S), - schedule = TimeInterval(save_interval), - filename = output_prefix * "_snapshots", - with_halos = true, - overwrite_existing = true) - -# Let's goo! -@info "Running a simulation with Δt = $(prettytime(simulation.Δt))" - -run!(simulation; pickup) - -@info """ - Simulation took $(prettytime(simulation.run_wall_time)) - Free surface: $(typeof(model.free_surface).name.wrapper) - Time step: $(prettytime(Δt)) -""" diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index e892089b..cd748869 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -3,6 +3,9 @@ module JRA55 using Oceananigans using Oceananigans.Units +using Oceananigans.Architectures: arch_array +using Oceananigans.DistributedComputations +using Oceananigans.DistributedComputations: child_architecture using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Grids: λnodes, φnodes, on_architecture using Oceananigans.Fields: interpolate! @@ -12,19 +15,21 @@ using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, TwoStreamDownwellingRadiation +using CUDA: @allowscalar + using NCDatasets using JLD2 using Dates -using Downloads: download import Oceananigans.Fields: set! -import Oceananigans.OutputReaders: new_backend +import Oceananigans.OutputReaders: new_backend, update_field_time_series! +using Downloads: download # A list of all variables provided in the JRA55 dataset: -JRA55_variable_names = (:freshwater_river_flux, +JRA55_variable_names = (:river_freshwater_flux, :rain_freshwater_flux, :snow_freshwater_flux, - :freshwater_iceberg_flux, + :iceberg_freshwater_flux, :specific_humidity, :sea_level_pressure, :relative_humidity, @@ -35,10 +40,10 @@ JRA55_variable_names = (:freshwater_river_flux, :northward_velocity) filenames = Dict( - :freshwater_river_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers + :river_freshwater_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall - :freshwater_iceberg_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs + :iceberg_freshwater_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity @@ -50,10 +55,10 @@ filenames = Dict( ) jra55_short_names = Dict( - :freshwater_river_flux => "friver", # Freshwater fluxes from rivers + :river_freshwater_flux => "friver", # Freshwater fluxes from rivers :rain_freshwater_flux => "prra", # Freshwater flux from rainfall :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall - :freshwater_iceberg_flux => "licalvf", # Freshwater flux from calving icebergs + :iceberg_freshwater_flux => "licalvf", # Freshwater flux from calving icebergs :specific_humidity => "huss", # Surface specific humidity :sea_level_pressure => "psl", # Sea level pressure :relative_humidity => "rhuss", # Surface relative humidity @@ -65,10 +70,10 @@ jra55_short_names = Dict( ) field_time_series_short_names = Dict( - :freshwater_river_flux => "Fri", # Freshwater fluxes from rivers + :river_freshwater_flux => "Fri", # Freshwater fluxes from rivers :rain_freshwater_flux => "Fra", # Freshwater flux from rainfall :snow_freshwater_flux => "Fsn", # Freshwater flux from snowfall - :freshwater_iceberg_flux => "Fic", # Freshwater flux from calving icebergs + :iceberg_freshwater_flux => "Fic", # Freshwater flux from calving icebergs :specific_humidity => "qa", # Surface specific humidity :sea_level_pressure => "pa", # Sea level pressure :relative_humidity => "rh", # Surface relative humidity @@ -83,7 +88,7 @@ urls = Dict( :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - :freshwater_river_flux => "https://www.dropbox.com/scl/fi/21ggl4p74k4zvbf04nb67/" * + :river_freshwater_flux => "https://www.dropbox.com/scl/fi/21ggl4p74k4zvbf04nb67/" * "RYF.friver.1990_1991.nc?rlkey=ny2qcjkk1cfijmwyqxsfm68fz&dl=0", :rain_freshwater_flux => "https://www.dropbox.com/scl/fi/5icl1gbd7f5hvyn656kjq/" * @@ -92,7 +97,7 @@ urls = Dict( :snow_freshwater_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * "RYF.prsn.1990_1991.nc?rlkey=auyqpwn060cvy4w01a2yskfah&dl=0", - :freshwater_iceberg_flux => "https://www.dropbox.com/scl/fi/44nc5y27ohvif7lkvpyv0/" * + :iceberg_freshwater_flux => "https://www.dropbox.com/scl/fi/44nc5y27ohvif7lkvpyv0/" * "RYF.licalvf.1990_1991.nc?rlkey=w7rqu48y2baw1efmgrnmym0jk&dl=0", :specific_humidity => "https://www.dropbox.com/scl/fi/66z6ymfr4ghkynizydc29/" * @@ -123,9 +128,11 @@ urls = Dict( compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds +# TODO: remove the allowscalar function compute_bounding_nodes(::Nothing, grid, LH, hnodes) hg = hnodes(grid, LH()) - h₁, h₂ = extrema(hg) + h₁ = @allowscalar minimum(hg) + h₂ = @allowscalar maximum(hg) return h₁, h₂ end @@ -168,7 +175,6 @@ function infer_longitudinal_topology(λbounds) return TX end - function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) λbounds = compute_bounding_nodes(longitude, grid, LX, λnodes) φbounds = compute_bounding_nodes(latitude, grid, LY, φnodes) @@ -232,8 +238,6 @@ function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) ti = time_indices(fts) ti = collect(ti) - native_times = ds["time"][ti] - times = jra55_times(native_times) data = ds[name][i₁:i₂, j₁:j₂, ti] close(ds) @@ -268,18 +272,18 @@ Ocean Modelling, 2020, https://doi.org/10.1016/j.ocemod.2019.101557. The `variable_name`s (and their `shortname`s used in NetCDF files) available from the JRA55-do are: - - `:freshwater_river_flux` ("friver") - - `:rain_freshwater_flux` ("prra") - - `:snow_freshwater_flux` ("prsn") - - `:freshwater_iceberg_flux` ("licalvf") - - `:specific_humidity` ("huss") - - `:sea_level_pressure` ("psl") - - `:relative_humidity` ("rhuss") - - `:downwelling_longwave_radiation` ("rlds") - - `:downwelling_shortwave_radiation` ("rsds") - - `:temperature` ("ras") - - `:eastward_velocity` ("uas") - - `:northward_velocity` ("vas") + - `:river_freshwater_flux` ("friver") + - `:rain_freshwater_flux` ("prra") + - `:snow_freshwater_flux` ("prsn") + - `:iceberg_freshwater_flux` ("licalvf") + - `:specific_humidity` ("huss") + - `:sea_level_pressure` ("psl") + - `:relative_humidity` ("rhuss") + - `:downwelling_longwave_radiation` ("rlds") + - `:downwelling_shortwave_radiation` ("rsds") + - `:temperature` ("ras") + - `:eastward_velocity` ("uas") + - `:northward_velocity` ("vas") Keyword arguments ================= @@ -326,7 +330,7 @@ function JRA55_field_time_series(variable_name; msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") throw(ArgumentError(msg)) end - + if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) variables_msg = prod(variable_strs) @@ -422,7 +426,7 @@ function JRA55_field_time_series(variable_name; # Probably with arguments that take latitude, longitude bounds. i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) - native_times = ds["time"][time_indices_in_memory] + native_times = ds["time"][time_indices] data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] φr = φn[j₁:j₂+1] @@ -466,9 +470,6 @@ function JRA55_field_time_series(variable_name; copyto!(interior(native_fts, :, :, 1, :), data) fill_halo_regions!(native_fts) - @show on_native_grid - @show totally_in_memory - if on_native_grid && totally_in_memory return native_fts @@ -480,27 +481,33 @@ function JRA55_field_time_series(variable_name; end end - @show totally_in_memory @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." + preprocessing_grid = on_native_grid ? JRA55_native_grid : grid on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid; - boundary_conditions, - backend = OnDisk(), - path = jld2_filename, - name = fts_name) + boundary_conditions, + backend = OnDisk(), + path = jld2_filename, + name = fts_name) # Re-open the dataset! ds = Dataset(filename) all_datetimes = ds["time"][time_indices] all_Nt = length(all_datetimes) - chunk = last(preprocess_chunk_size) - all_times = jra55_times(all_Nt) + + all_times = jra55_times(all_datetimes) # Save data to disk, one field at a time start_clock = time_ns() n = 1 # on disk m = 0 # in memory + + fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid; + backend, + path = jld2_filename, + name = fts_name) + while n <= all_Nt print(" ... processing time index $n of $all_Nt \r") @@ -528,7 +535,7 @@ function JRA55_field_time_series(variable_name; if !on_native_grid fts.times = new_times - interpolate!(fts, native_fts) + interpolate!(tmp_field, native_fts) end m = 1 # reset @@ -554,6 +561,9 @@ const AA = Oceananigans.Architectures.AbstractArchitecture JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = JRA55_prescribed_atmosphere(CPU(), time_indices; kw...) +JRA55_prescribed_atmosphere(arch::Distributed, time_indices=Colon(); kw...) = + JRA55_prescribed_atmosphere(child_architecture(arch), time_indices; kw...) + # TODO: allow the user to pass dates function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, @@ -580,29 +590,28 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); va = JRA55_field_time_series(:northward_velocity; kw...) Ta = JRA55_field_time_series(:temperature; kw...) qa = JRA55_field_time_series(:specific_humidity; kw...) + ra = JRA55_field_time_series(:relative_humidity; kw...) pa = JRA55_field_time_series(:sea_level_pressure; kw...) Fra = JRA55_field_time_series(:rain_freshwater_flux; kw...) Fsn = JRA55_field_time_series(:snow_freshwater_flux; kw...) + Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) + Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) - # NOTE: these have a different frequency than 3 hours so some changes are needed to - # JRA55_field_time_series to support them. - # Fv_JRA55 = JRA55_field_time_series(:freshwater_river_flux, grid; time_indices, architecture) - # Fi_JRA55 = JRA55_field_time_series(:freshwater_iceberg_flux, grid; time_indices, architecture) - times = ua.times velocities = (u = ua, v = va) tracers = (T = Ta, - q = qa) + q = qa, + r = ra) freshwater_flux = (rain = Fra, - snow = Fsn) - # rivers = Fv_JRA55, - # icebergs = Fi_JRA55) + snow = Fsn, + rivers = Fri, + icebergs = Fic) pressure = pa From b5da34b25fc9739a25f9e4ff6c7b48541eb6b125 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 23 Apr 2024 23:35:00 -0400 Subject: [PATCH 174/182] another fix --- src/DataWrangling/JRA55.jl | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index cd748869..07f68ac7 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -326,11 +326,6 @@ function JRA55_field_time_series(variable_name; preprocess_architecture = CPU(), time_indices = nothing) - if backend isa OnDisk - msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") - throw(ArgumentError(msg)) - end - if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) variables_msg = prod(variable_strs) @@ -369,9 +364,9 @@ function JRA55_field_time_series(variable_name; # In this case, the whole time series is in memory. # Either the time series is short, or we are doing a limited-area # simulation, like in a single column. So, we conservatively - # set a default `time_indices = 1:1`. - isnothing(time_indices) && (time_indices = 1:1) - time_indices_in_memory = time_indices + # set a default `time_indices = 1:2`. + isnothing(time_indices) && (time_indices = 1:2) + time_indices_in_memory = time_indices native_fts_architecture = architecture else # In this case, part or all of the time series will be stored in a file. @@ -485,12 +480,6 @@ function JRA55_field_time_series(variable_name; preprocessing_grid = on_native_grid ? JRA55_native_grid : grid - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid; - boundary_conditions, - backend = OnDisk(), - path = jld2_filename, - name = fts_name) - # Re-open the dataset! ds = Dataset(filename) all_datetimes = ds["time"][time_indices] @@ -498,15 +487,24 @@ function JRA55_field_time_series(variable_name; all_times = jra55_times(all_datetimes) + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid; + boundary_conditions, + times = all_times, + backend = OnDisk(), + path = jld2_filename, + name = fts_name) + # Save data to disk, one field at a time start_clock = time_ns() n = 1 # on disk m = 0 # in memory fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid; + boundary_conditions, backend, - path = jld2_filename, - name = fts_name) + times = all_times, + path = jld2_filename, + name = fts_name) while n <= all_Nt print(" ... processing time index $n of $all_Nt \r") From faaf418a4678c1d461c10f5040047ae6fb68c798 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:09:03 -0400 Subject: [PATCH 175/182] bugfix --- src/DataWrangling/JRA55.jl | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 07f68ac7..e4031cca 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -487,9 +487,8 @@ function JRA55_field_time_series(variable_name; all_times = jra55_times(all_datetimes) - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid; + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; boundary_conditions, - times = all_times, backend = OnDisk(), path = jld2_filename, name = fts_name) @@ -499,12 +498,11 @@ function JRA55_field_time_series(variable_name; n = 1 # on disk m = 0 # in memory - fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid; + fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; boundary_conditions, backend, - times = all_times, - path = jld2_filename, - name = fts_name) + path = jld2_filename, + name = fts_name) while n <= all_Nt print(" ... processing time index $n of $all_Nt \r") From 2f0d6793828308ecfd9d3a20206bae35feba3f80 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:09:41 -0400 Subject: [PATCH 176/182] OnDisk not possible for JRA55! --- src/DataWrangling/JRA55.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index e4031cca..ab3dd63f 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -326,6 +326,11 @@ function JRA55_field_time_series(variable_name; preprocess_architecture = CPU(), time_indices = nothing) + if backend isa OnDisk + msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") + throw(ArgumentError(msg)) + end + if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) variables_msg = prod(variable_strs) From 57de400a32dd2c7267f246916773a7259d2ad9c9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:10:53 -0400 Subject: [PATCH 177/182] comment why we cannot use OnDisk --- src/DataWrangling/JRA55.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index ab3dd63f..9af0664f 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -326,7 +326,9 @@ function JRA55_field_time_series(variable_name; preprocess_architecture = CPU(), time_indices = nothing) - if backend isa OnDisk + # OnDisk backends do not support time interpolation! + # Disallow OnDisk for JRA55 dataset loading + if backend isa OnDisk msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") throw(ArgumentError(msg)) end From c716cbd43e62babeb75c1de9630a4a1751717444 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:31:34 -0400 Subject: [PATCH 178/182] another bugfix --- src/DataWrangling/JRA55.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 9af0664f..4c37a54f 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -538,7 +538,7 @@ function JRA55_field_time_series(variable_name; if !on_native_grid fts.times = new_times - interpolate!(tmp_field, native_fts) + interpolate!(fts, native_fts) end m = 1 # reset From db6b8d422bf0cfb5daa2da0ec6ac7343477c80e9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:21:35 -0400 Subject: [PATCH 179/182] some changes --- src/DataWrangling/JRA55.jl | 22 +++++++++++++--------- test/runtests_setup.jl | 1 + test/test_jra55.jl | 8 ++++++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 4c37a54f..758ae72c 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -389,7 +389,8 @@ function JRA55_field_time_series(variable_name; time_indices_in_memory = 1:length(backend) native_fts_architecture = architecture else # then `time_indices_in_memory` refers to preprocessing - time_indices_in_memory = 1:preprocess_chunk_size + maximum_index = min(preprocess_chunk_size, length(time_indices)) + time_indices_in_memory = 1:maximum_index native_fts_architecture = preprocess_architecture end end @@ -505,9 +506,11 @@ function JRA55_field_time_series(variable_name; n = 1 # on disk m = 0 # in memory - fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; + times_in_memory = all_times[time_indices_in_memory] + + fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; boundary_conditions, - backend, + backend = InMemory(), path = jld2_filename, name = fts_name) @@ -527,24 +530,25 @@ function JRA55_field_time_series(variable_name; end # Re-compute times - Nt = length(time_indices_in_memory) - new_times = jra55_times(Nt, all_times[n₁]) + new_times = jra55_times(all_times[time_indices_in_memory], all_times[n₁]) native_fts.times = new_times # Re-compute data new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) + fts.times = new_times if !on_native_grid - fts.times = new_times + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) end m = 1 # reset end - set!(on_disk_fts, fts[m], n, all_times[n]) + set!(on_disk_fts, fts[m], n, on_disk_fts.times[m]) n += 1 end diff --git a/test/runtests_setup.jl b/test/runtests_setup.jl index 993f89a3..83e3f1d9 100644 --- a/test/runtests_setup.jl +++ b/test/runtests_setup.jl @@ -4,5 +4,6 @@ using CUDA using Test using Oceananigans.Architectures: architecture +using Oceananigans.OutputReaders: interpolate! test_architectures = [CPU()] diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 0ead54af..9af9dec0 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -38,15 +38,18 @@ include("runtests_setup.jl") @info "Testing loading preprocessed JRA55 data on $A..." in_memory_jra55_fts = ClimaOcean.JRA55.JRA55_field_time_series(test_name; + time_indices, architecture = arch, backend = InMemory(2)) @test in_memory_jra55_fts isa FieldTimeSeries + + @show in_memory_jra55_fts[1], jra55_fts[1] @test parent(in_memory_jra55_fts[1]) == parent(jra55_fts[1]) # Clean up rm(test_filename) - rm(on_disk_jra55_fts.path) + rm(in_memory_jra55_fts.path) @info "Testing interpolate_field_time_series! on $A..." # Make target grid and field @@ -69,7 +72,7 @@ include("runtests_setup.jl") times = jra55_fts.times boundary_conditions = jra55_fts.boundary_conditions target_fts = FieldTimeSeries{Center, Center, Nothing}(target_grid, times; boundary_conditions) - ClimaOcean.DataWrangling.interpolate_field_time_series!(target_fts, jra55_fts) + interpolate!(target_fts, jra55_fts) # Random regression test CUDA.@allowscalar begin @@ -92,6 +95,7 @@ include("runtests_setup.jl") # Test that we can load the data back Qswt = FieldTimeSeries(filepath, "Qsw") + @show size(Qswt.data), size(target_fts) @test parent(Qswt) == parent(target_fts) @test Qswt.times == target_fts.times rm(filepath) From 067c4a587df37c610d06903731f73cc9ca6bbbc1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:23:58 -0400 Subject: [PATCH 180/182] probably now it should work --- src/DataWrangling/JRA55.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 758ae72c..12440e26 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -534,7 +534,7 @@ function JRA55_field_time_series(variable_name; native_fts.times = new_times # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] fts.times = new_times if !on_native_grid @@ -548,7 +548,7 @@ function JRA55_field_time_series(variable_name; m = 1 # reset end - set!(on_disk_fts, fts[m], n, on_disk_fts.times[m]) + set!(on_disk_fts, fts[m], n, fts.times[m]) n += 1 end From ac9137fb2546ccb1e373edbffb5aa29f5cbbf9ac Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 26 Apr 2024 17:38:31 -0400 Subject: [PATCH 181/182] Update src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl Co-authored-by: Gregory L. Wagner --- .../CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 29e47274..224ef4d4 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -382,7 +382,7 @@ end return Δh, Δu, Δv, Δθ, Δq end -@inline function compute_similarity_theory_fluxes(roughness_lengths::ConstantRoughnessLength, +@inline function compute_similarity_theory_fluxes(roughness_lengths, surface_state, atmos_state, thermodynamics_parameters, From 12357acc2b470a7ef03b9dfb74147e85e5f64b94 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 23:11:40 -0400 Subject: [PATCH 182/182] fixed tests --- src/DataWrangling/JRA55.jl | 15 +++++++++++++++ test/test_jra55.jl | 3 +-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 12440e26..b83637be 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -514,6 +514,17 @@ function JRA55_field_time_series(variable_name; path = jld2_filename, name = fts_name) + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + + if !on_native_grid + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + end + while n <= all_Nt print(" ... processing time index $n of $all_Nt \r") @@ -548,6 +559,8 @@ function JRA55_field_time_series(variable_name; m = 1 # reset end + @show fts[m] + set!(on_disk_fts, fts[m], n, fts.times[m]) n += 1 @@ -560,6 +573,8 @@ function JRA55_field_time_series(variable_name; close(ds) user_fts = FieldTimeSeries(jld2_filename, fts_name; architecture, backend, time_indexing) + fill_halo_regions!(user_fts) + return user_fts end diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 9af9dec0..d13b3d4f 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -44,8 +44,7 @@ include("runtests_setup.jl") @test in_memory_jra55_fts isa FieldTimeSeries - @show in_memory_jra55_fts[1], jra55_fts[1] - @test parent(in_memory_jra55_fts[1]) == parent(jra55_fts[1]) + @test interior(in_memory_jra55_fts[1]) == interior(jra55_fts[1]) # Clean up rm(test_filename)