From 6891c57e25d67a8deac5f1d7c8bb6ea2d69e1faf Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 5 Oct 2023 12:12:22 -0400 Subject: [PATCH 001/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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/716] 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 99ec13e4350b58c6dc20127ef73f9aa0bddb3c3e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 16 Nov 2023 12:13:30 -0500 Subject: [PATCH 038/716] stuff --- examples/analyze_neverworld_simulation.jl | 43 ----- examples/animate_neverworld_simulation.jl | 152 ------------------ examples/run_decaying_med.jl | 47 ++++++ examples/run_neverworld_simulation.jl | 135 ---------------- src/DataWrangling/DataWrangling.jl | 1 + src/DataWrangling/ECCO2.jl | 17 +- src/InitialConditions.jl | 181 +++++++++++++++++++--- 7 files changed, 224 insertions(+), 352 deletions(-) delete mode 100644 examples/analyze_neverworld_simulation.jl delete mode 100644 examples/animate_neverworld_simulation.jl create mode 100644 examples/run_decaying_med.jl delete mode 100644 examples/run_neverworld_simulation.jl 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/run_decaying_med.jl b/examples/run_decaying_med.jl new file mode 100644 index 00000000..17be58c5 --- /dev/null +++ b/examples/run_decaying_med.jl @@ -0,0 +1,47 @@ +using GLMakie +using Oceananigans +using ClimaOcean.Bathymetry: regrid_bathymetry +using ClimaOcean.ECCO2: ecco2_field, ecco2_center_mask +using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching + +##### +##### Regional Mediterranean grid +##### + +# A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters +z = stretched_vertical_faces(minimum_depth = 5000, + surface_layer_Δz = 1.75, + stretching = PowerLawStretching(1.070), + surface_layer_height = 50) + +Nx = 25 * 50 +Ny = 55 * 50 +Nz = length(z) - 1 + +grid = LatitudeLongitudeGrid(CPU(); + size = (Nx, Ny, Nz), + latitude = (25, 50), + longitude = (-10, 45), + z, + halo = (7, 7, 7)) + +h = regrid_bathymetry(grid, height_above_water=1) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(h)) + +λ, φ, z = nodes(h) + +# Download ecco tracer fields +Tecco = ecco2_field(:temperature) +Secco = ecco2_field(:salinity) + +ecco_tracers = (; Tecco, Secco) + +# Make sure all values are extended properly before regridding +adjust_tracers!(ecco_tracers; mask = ecco2_center_mask()) + +Tnew = CenterField(grid) +S = CenterField(grid) + +regrid!(T, ecco_tracers.T) +regrid!(S, ecco_tracers.S) 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/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index 9ccbc324..10922e92 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -8,6 +8,7 @@ using Oceananigans.Architectures: architecture using Oceananigans.Grids: node using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Fields: interpolate +using Oceananigans: pretty_filesize using Oceananigans.Utils: launch! using KernelAbstractions: @kernel, @index diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index d5527d2b..991fcc58 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -112,14 +112,23 @@ function ecco2_field(variable_name; return field end -function ecco2_bottom_height_from_temperature() - Tᵢ = ecco2_field(:temperature) +function ecco2_center_mask(architecture = CPU(); missing_value = Float32(-1e23)) + Tᵢ = ecco2_field(:temperature; architecture) + mask = CenterField(Tᵢ.grid) + + # Set the mask with ones where T is defined + set!(mask, (!).(Tᵢ .== missing_value)) - missing_value = Float32(-9.9e22) + return mask +end + +function ecco2_bottom_height_from_temperature() + Tᵢ = ecco2_field(:temperature) + grid = Tᵢ.grid # Construct bottom_height depth by analyzing T Nx, Ny, Nz = size(Tᵢ) - bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) + bottom_height = ones(Nx, Ny) .* grid.Lz zf = znodes(Tᵢ.grid, Face()) for i = 1:Nx, j = 1:Ny diff --git a/src/InitialConditions.jl b/src/InitialConditions.jl index 42272758..680c5171 100644 --- a/src/InitialConditions.jl +++ b/src/InitialConditions.jl @@ -3,6 +3,7 @@ module InitialConditions export continue_downwards! using Oceananigans +using Oceananigans.Fields: OneField using Oceananigans.Grids: peripheral_node using Oceananigans.Utils: launch! using Oceananigans.Fields: instantiated_location, interior, CenterField @@ -11,22 +12,72 @@ using Oceananigans.Architectures: architecture, device, GPU using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll -function continue_downards!(field) +@kernel function _propagate_field!(field, tmp_field, Nx, Ny) + i, j, k = @index(Global, NTuple) + + @inbounds begin + nw = field[i - 1, j, k] + ns = field[i, j - 1, k] + ne = field[i + 1, j, k] + nn = field[i, j + 1, k] + nb = (nw, ne, nn, ns) + + counter = 0 + cumsum = 0.0 + + @unroll for n in nb + counter += ifelse(isnan(n), 0, 1) + cumsum += ifelse(isnan(n), 0, n) + end + + tmp_field[i, j, k] = ifelse(cumsum == 0, NaN, cumsum / counter) + end +end + +@kernel function _substitute_nans!(field, tmp_field) + i, j, k = @index(Global, NTuple) + @inbounds substitute = isnan(field[i, j, k]) + @inbounds field[i, j, k] = ifelse(substitute, tmp_field[i, j, k], field[i, j, k]) +end + +@kernel function _nans_in_mask!(field, mask) + i, j, k = @index(Global, NTuple) + @inbounds field[i, j, k] = ifelse(mask[i, j, k] == 0, NaN, field[i, j, k]) +end + +function propagate_horizontally!(field, mask) + passes = Ref(0) + grid = field.grid + arch = architecture(grid) + + tmp_field = deepcopy(field) + + launch!(arch, grid, :xyz, _nans_in_mask!, field, mask) + + while isnan(sum(parent(field))) + launch!(arch, grid, :xyz, _propagate_field!, field, tmp_field, grid.Nx, grid.Ny) + launch!(arch, grid, :xyz, _substitute_nans!, field, tmp_field) + passes[] += 1 + @debug "propagate pass $(passes[]) with sum $(sum(parent(field)))" + end + + return nothing +end + +function continue_downwards!(field, mask) arch = architecture(field) grid = field.grid - loc = instantiated_location(field) - launch!(arch, grid, :xy, _continue_downwards!, field, loc, grid) + launch!(arch, grid, :xy, _continue_downwards!, field, grid, mask) return nothing end -@kernel function _continue_downwards!(field, (LX, LY, LZ), grid) +@kernel function _continue_downwards!(field, grid, mask) i, j = @index(Global, NTuple) Nz = grid.Nz - active_surface = !peripheral_node(i, j, Nz, grid, LX, LY, LZ) @unroll for k = Nz-1 : -1 : 1 - fill_from_above = active_surface & peripheral_node(i, j, k, grid, LX, LY, LZ) + fill_from_above = mask[i, j, k] == 0 @inbounds field[i, j, k] = ifelse(fill_from_above, field[i, j, k+1], field[i, j, k]) end end @@ -34,14 +85,48 @@ end scale_to_diffusivity(vertical_scale) = vertical_scale^2 scale_to_diffusivity(vertical_scale::Function) = (x, y, z, t) -> vertical_scale(x, y, z, t)^2 -function diffuse_tracers!(grid; - tracers, - horizontal_scale = 0, - vertical_scale = 0, - fractional_time_step = 2e-2) +@kernel function _apply_tracer_mask!(tracer, initial_tracer, mask::AbstractArray) + i, j, k = @index(Global, NTuple) + @inbounds tracer[i, j, k] = ifelse(mask[i, j, k] == 1, initial_tracer[i, j, k], tracer[i, j, k]) +end + +@kernel function _apply_tracer_mask!(tracer, initial_tracer, mask::Function) + i, j, k = @index(Global, NTuple) + @inbounds tracer[i, j, k] = ifelse(mask(i, j, k, grid) == 1, initial_tracer[i, j, k], tracer[i, j, k]) +end + +function adjust_tracers!(tracers; + mask = OneField(grid)) + + for (name, tracer) in zip(keys(tracers), tracers) + @info "extending tracer $name" + continue_downwards!(tracer, mask) + propagate_horizontally!(tracer, mask) + end + + # Do we need this? + # diffuse_tracers(initial_tracers; + # horizontal_scale, + # vertical_scale, + # fractional_time_step, + # mask) + + return nothing +end + +@inline not_an_immersed_cell(i, j, k, grid) = !immersed_cell(i, j, k, grid) + +function diffuse_tracers(initial_tracers; + horizontal_scale = 0, + vertical_scale = 0, + fractional_time_step = 2e-2, + mask = not_an_immersed_cell) + + # Remake the grid + grid = initial_tracers[1].grid # Remake tracers without boundary conditions - tracers = NamedTuple(name => CenterField(grid; data=tracers[name].data) for name in keys(tracers)) + tracers = NamedTuple(name => CenterField(grid) for name in keys(initial_tracers)) # Horizontal diffusivities that mix up to t ∼ ℓ² / κ ∼ 1 κh = horizontal_scale^2 @@ -64,20 +149,80 @@ function diffuse_tracers!(grid; horizontal_smoothing = HorizontalScalarDiffusivity(κ=κh) smoothing_model = HydrostaticFreeSurfaceModel(; grid, tracers, - velocities = PrescribedVelocityFields(), - momentum_advection = nothing, - tracer_advection = nothing, - buoyancy = nothing, - closure = (horizontal_smoothing, vertical_smoothing)) + velocities = PrescribedVelocityFields(), + momentum_advection = nothing, + tracer_advection = nothing, + buoyancy = nothing, + closure = (horizontal_smoothing, vertical_smoothing)) + + set!(smoothing_model, (tracer[name] = initial_tracer[name] for name in keys(initial_tracers))...) Nt = ceil(Int, 1 / Δt) @info string("Smoothing tracers ", keys(tracers), " with ", Nt, " time steps") smoothing_simulation = Simulation(smoothing_model; Δt, stop_time=1) + + # Remove NaN checker pop!(smoothing_simulation.callbacks, :nan_checker) + + # Restore values to default in the masked region + function restore_values(sim) + grid = sim.model.grid + tracers = sim.model.tracers + for (tracer, initial_tracer) in zip(tracers, initial_tracers) + launch!(architecture(grid), grid, :xyz, _apply_tracer_mask!, tracer, initial_tracer, mask) + end + end + + # Add restoring to initial values + simulation.callbacks[:restoring] = Callback(restore_values, IterationInterval(1)) + run!(smoothing_simulation) - return nothing + return smoothing_model.tracers +end + +using Oceananigans.Fields: regrid! +using Oceananigans.Grids: cpu_face_constructor_x, cpu_face_constructor_y, cpu_face_constructor_z + +# Should we move this to grids?? +construct_grid(::Type{RectilinearGrid}, arch, size, extent, topology) = + RectilinearGrid(arch; size, x = extent[1], y = extent[2], z = extent[2], topology) + +construct_grid(::Type{LatitudeLongitudeGrid}, arch, size, extent, topology) = + LatitudeLongitudeGrid(arch; size, longitude = extent[1], latitude = extent[2], z = extent[2], topology) + +# Extend this to regrid automatically +function three_dimensional_regrid!(a, b) + target_grid = a.grid + source_grid = b.grid + + topo = topology(target_grid) + arch = architecture(target_grid) + + target_y = yt = cpu_face_constructor_y(target_grid) + target_z = zt = cpu_face_constructor_z(target_grid) + + target_size = Nt = size(target_grid) + + source_x = xs = cpu_face_constructor_x(source_grid) + source_y = ys = cpu_face_constructor_y(source_grid) + + source_size = Ns = size(source_size) + + # Start by regridding in z + zgrid = construct_grid(typeof(target_grid), arch, (Ns[1], Ns[2], Nt[3]), (xs, ys, zt), topo) + field_z = Field(location(b), zgrid) + regrid!(field_z, b) + + # regrid in y next + zgrid = construct_grid(typeof(target_grid), arch, (Ns[1], Nt[2], Nt[3]), (xs, yt, zt), topo) + field_y = Field(location(b), zgrid) + regrid!(field_y, field_z) + + # Finally regrid in x + regrid!(a, field_y) end + end # module From fad208006a209fb08d7287897ee0b6c668fe3109 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 16 Nov 2023 14:32:13 -0500 Subject: [PATCH 039/716] run decaying med --- ...g_med.jl => run_decaying_mediterraneum.jl} | 21 +++--- src/DataWrangling/ECCO2.jl | 4 +- src/InitialConditions.jl | 74 +++++++++++-------- 3 files changed, 56 insertions(+), 43 deletions(-) rename examples/{run_decaying_med.jl => run_decaying_mediterraneum.jl} (76%) diff --git a/examples/run_decaying_med.jl b/examples/run_decaying_mediterraneum.jl similarity index 76% rename from examples/run_decaying_med.jl rename to examples/run_decaying_mediterraneum.jl index 17be58c5..d11a4dad 100644 --- a/examples/run_decaying_med.jl +++ b/examples/run_decaying_mediterraneum.jl @@ -4,6 +4,8 @@ using ClimaOcean.Bathymetry: regrid_bathymetry using ClimaOcean.ECCO2: ecco2_field, ecco2_center_mask using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching +using ClimaOcean.InitialConditions: three_dimensional_regrid! + ##### ##### Regional Mediterranean grid ##### @@ -14,8 +16,8 @@ z = stretched_vertical_faces(minimum_depth = 5000, stretching = PowerLawStretching(1.070), surface_layer_height = 50) -Nx = 25 * 50 -Ny = 55 * 50 +Nx = 20 * 55 # 1 / 20th of a degree +Ny = 20 * 25 Nz = length(z) - 1 grid = LatitudeLongitudeGrid(CPU(); @@ -29,19 +31,18 @@ h = regrid_bathymetry(grid, height_above_water=1) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(h)) -λ, φ, z = nodes(h) - +# All this can be done in a `set_tracers_from_ecco!(model; )` # Download ecco tracer fields -Tecco = ecco2_field(:temperature) -Secco = ecco2_field(:salinity) +Tecco = ecco2_field(:temperature); +Secco = ecco2_field(:salinity); ecco_tracers = (; Tecco, Secco) # Make sure all values are extended properly before regridding adjust_tracers!(ecco_tracers; mask = ecco2_center_mask()) -Tnew = CenterField(grid) -S = CenterField(grid) +T = CenterField(grid); +S = CenterField(grid); -regrid!(T, ecco_tracers.T) -regrid!(S, ecco_tracers.S) +three_dimensional_regrid!(T, Tecco) +three_dimensional_regrid!(S, Secco) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 991fcc58..0b03deeb 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -112,12 +112,12 @@ function ecco2_field(variable_name; return field end -function ecco2_center_mask(architecture = CPU(); missing_value = Float32(-1e23)) +function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) Tᵢ = ecco2_field(:temperature; architecture) mask = CenterField(Tᵢ.grid) # Set the mask with ones where T is defined - set!(mask, (!).(Tᵢ .== missing_value)) + set!(mask, (!).(Tᵢ .< minimum_value)) return mask end diff --git a/src/InitialConditions.jl b/src/InitialConditions.jl index 680c5171..f4422fc3 100644 --- a/src/InitialConditions.jl +++ b/src/InitialConditions.jl @@ -3,6 +3,7 @@ module InitialConditions export continue_downwards! using Oceananigans +using Oceananigans.BoundaryConditions using Oceananigans.Fields: OneField using Oceananigans.Grids: peripheral_node using Oceananigans.Utils: launch! @@ -12,7 +13,7 @@ using Oceananigans.Architectures: architecture, device, GPU using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll -@kernel function _propagate_field!(field, tmp_field, Nx, Ny) +@kernel function _propagate_field!(field, tmp_field) i, j, k = @index(Global, NTuple) @inbounds begin @@ -34,36 +35,41 @@ using KernelAbstractions.Extras.LoopInfo: @unroll end end -@kernel function _substitute_nans!(field, tmp_field) +@kernel function _substitute_values!(field, tmp_field) i, j, k = @index(Global, NTuple) @inbounds substitute = isnan(field[i, j, k]) @inbounds field[i, j, k] = ifelse(substitute, tmp_field[i, j, k], field[i, j, k]) end -@kernel function _nans_in_mask!(field, mask) +@kernel function _nans_outside_mask!(field, mask) i, j, k = @index(Global, NTuple) @inbounds field[i, j, k] = ifelse(mask[i, j, k] == 0, NaN, field[i, j, k]) end -function propagate_horizontally!(field, mask) - passes = Ref(0) - grid = field.grid - arch = architecture(grid) +propagate_horizontally!(field, ::Nothing; kw...) = nothing + +function propagate_horizontally!(field, mask; max_iter = Inf) + iter = 0 + grid = field.grid + arch = architecture(grid) + launch!(arch, grid, :xyz, _nans_outside_mask!, field, mask) + fill_halo_regions!(field) + tmp_field = deepcopy(field) - - launch!(arch, grid, :xyz, _nans_in_mask!, field, mask) - while isnan(sum(parent(field))) - launch!(arch, grid, :xyz, _propagate_field!, field, tmp_field, grid.Nx, grid.Ny) - launch!(arch, grid, :xyz, _substitute_nans!, field, tmp_field) - passes[] += 1 - @debug "propagate pass $(passes[]) with sum $(sum(parent(field)))" + while isnan(sum(interior(field))) && iter < max_iter + launch!(arch, grid, :xyz, _propagate_field!, field, tmp_field) + launch!(arch, grid, :xyz, _substitute_values!, field, tmp_field) + iter += 1 + @debug "propagate pass $iter with sum $(sum(parent(field)))" end return nothing end +continue_downwards!(field, ::Nothing) = nothing + function continue_downwards!(field, mask) arch = architecture(field) grid = field.grid @@ -77,7 +83,7 @@ end Nz = grid.Nz @unroll for k = Nz-1 : -1 : 1 - fill_from_above = mask[i, j, k] == 0 + @inbounds fill_from_above = mask[i, j, k] == 0 @inbounds field[i, j, k] = ifelse(fill_from_above, field[i, j, k+1], field[i, j, k]) end end @@ -95,13 +101,12 @@ end @inbounds tracer[i, j, k] = ifelse(mask(i, j, k, grid) == 1, initial_tracer[i, j, k], tracer[i, j, k]) end -function adjust_tracers!(tracers; - mask = OneField(grid)) +function adjust_tracers!(tracers; mask = nothing, max_iter = Inf) for (name, tracer) in zip(keys(tracers), tracers) @info "extending tracer $name" continue_downwards!(tracer, mask) - propagate_horizontally!(tracer, mask) + propagate_horizontally!(tracer, mask; max_iter) end # Do we need this? @@ -181,20 +186,25 @@ function diffuse_tracers(initial_tracers; return smoothing_model.tracers end +# TODO: move all this to Oceananigans! + using Oceananigans.Fields: regrid! -using Oceananigans.Grids: cpu_face_constructor_x, cpu_face_constructor_y, cpu_face_constructor_z +using Oceananigans.Grids: cpu_face_constructor_x, + cpu_face_constructor_y, + cpu_face_constructor_z, + topology # Should we move this to grids?? -construct_grid(::Type{RectilinearGrid}, arch, size, extent, topology) = +construct_grid(::Type{<:RectilinearGrid}, arch, size, extent, topology) = RectilinearGrid(arch; size, x = extent[1], y = extent[2], z = extent[2], topology) -construct_grid(::Type{LatitudeLongitudeGrid}, arch, size, extent, topology) = - LatitudeLongitudeGrid(arch; size, longitude = extent[1], latitude = extent[2], z = extent[2], topology) +construct_grid(::Type{<:LatitudeLongitudeGrid}, arch, size, extent, topology) = + LatitudeLongitudeGrid(arch; size, longitude = extent[1], latitude = extent[2], z = extent[3], topology) # Extend this to regrid automatically function three_dimensional_regrid!(a, b) - target_grid = a.grid - source_grid = b.grid + target_grid = a.grid isa ImmersedBoundaryGrid ? a.grid.underlying_grid : a.grid + source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid topo = topology(target_grid) arch = architecture(target_grid) @@ -207,22 +217,24 @@ function three_dimensional_regrid!(a, b) source_x = xs = cpu_face_constructor_x(source_grid) source_y = ys = cpu_face_constructor_y(source_grid) - source_size = Ns = size(source_size) + source_size = Ns = size(source_grid) # Start by regridding in z + @info "Regridding in z" zgrid = construct_grid(typeof(target_grid), arch, (Ns[1], Ns[2], Nt[3]), (xs, ys, zt), topo) field_z = Field(location(b), zgrid) - regrid!(field_z, b) + regrid!(field_z, zgrid, source_grid, b) # regrid in y next - zgrid = construct_grid(typeof(target_grid), arch, (Ns[1], Nt[2], Nt[3]), (xs, yt, zt), topo) - field_y = Field(location(b), zgrid) - regrid!(field_y, field_z) + @info "Regridding in y" + ygrid = construct_grid(typeof(target_grid), arch, (Ns[1], Nt[2], Nt[3]), (xs, yt, zt), topo) + field_y = Field(location(b), ygrid); + regrid!(field_y, ygrid, zgrid, field_z); # Finally regrid in x - regrid!(a, field_y) + @info "Regridding in x" + regrid!(a, target_grid, ygrid, field_y) end - end # module From b8c915e00261d71a963ec84b20e2496f95560400 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 16 Nov 2023 14:52:51 -0500 Subject: [PATCH 040/716] some changes --- examples/freely_decaying_mediterraneum.jl | 88 +++++++++++++++++++++++ examples/run_decaying_mediterraneum.jl | 48 ------------- src/InitialConditions.jl | 8 ++- 3 files changed, 93 insertions(+), 51 deletions(-) create mode 100644 examples/freely_decaying_mediterraneum.jl delete mode 100644 examples/run_decaying_mediterraneum.jl diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl new file mode 100644 index 00000000..f7d49a70 --- /dev/null +++ b/examples/freely_decaying_mediterraneum.jl @@ -0,0 +1,88 @@ +using GLMakie +using Oceananigans +using ClimaOcean.Bathymetry: regrid_bathymetry +using ClimaOcean.ECCO2: ecco2_field, ecco2_center_mask +using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching +using ClimaOcean.InitialConditions: three_dimensional_regrid! +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity +using Oceananigans.Coriolis: ActiveCellEnstrophyConserving + +##### +##### Regional Mediterranean grid +##### + +function regrid_ecco_tracers_to_grid(grid) + Tecco = ecco2_field(:temperature); + Secco = ecco2_field(:salinity); + + ecco_tracers = (; Tecco, Secco) + + # Make sure all values are extended properly before regridding + adjust_tracers!(ecco_tracers; mask = ecco2_center_mask()) + + T = CenterField(grid); + S = CenterField(grid); + + three_dimensional_regrid!(T, Tecco); + three_dimensional_regrid!(S, Secco); + + return T, S +end + +# A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters +z = stretched_vertical_faces(minimum_depth = 5000, + surface_layer_Δz = 1.75, + stretching = PowerLawStretching(1.070), + surface_layer_height = 50) + +Nx = 20 * 55 # 1 / 20th of a degree +Ny = 20 * 25 +Nz = length(z) - 1 + +grid = LatitudeLongitudeGrid(CPU(); + size = (Nx, Ny, Nz), + latitude = (25, 50), + longitude = (0, 45), + z, + halo = (7, 7, 7)) + +h = regrid_bathymetry(grid, height_above_water=1) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(h)) + +T, S = regrid_ecco_tracers_to_grid(grid) + +mask_immersed_field!(T) +mask_immersed_field!(S) + +fig = Figure() +ax = Axis(fig[1, 1]) +heatmap!(ax, interior(T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) +ax = Axis(fig[1, 2]) +heatmap!(ax, interior(S, :, :, Nz), colorrange = (35, 40), colormap = :haline) + +# Correct oceananigans +import Oceananigans.Advection: nothing_to_default + +nothing_to_default(user_value; default) = isnothing(user_value) ? default : user_value + +# Construct the model and run it, will it run or we have to diffuse? +model = HydrostaticFreeSurfaceModel(; grid, + momentum_advection = WENOVectorInvariant(), + tracer_advection = WENO(grid; order = 7), + free_surface = SplitExplicitFreeSurface(; cfl = 0.75, grid), + closure = CATKEVerticalDiffusivity(), + buoyancy = SeawaterBuoyancy(), + tracers = (:T, :S, :e), + coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) + +set!(model, T = T, S = S) + +# Probably we'll need to diffuse? Probably not let's see now + +simulation = Simulation(model, Δt = 2minutes, stop_time = 10years) + +function progress(sim) + + + diff --git a/examples/run_decaying_mediterraneum.jl b/examples/run_decaying_mediterraneum.jl deleted file mode 100644 index d11a4dad..00000000 --- a/examples/run_decaying_mediterraneum.jl +++ /dev/null @@ -1,48 +0,0 @@ -using GLMakie -using Oceananigans -using ClimaOcean.Bathymetry: regrid_bathymetry -using ClimaOcean.ECCO2: ecco2_field, ecco2_center_mask -using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching - -using ClimaOcean.InitialConditions: three_dimensional_regrid! - -##### -##### Regional Mediterranean grid -##### - -# A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters -z = stretched_vertical_faces(minimum_depth = 5000, - surface_layer_Δz = 1.75, - stretching = PowerLawStretching(1.070), - surface_layer_height = 50) - -Nx = 20 * 55 # 1 / 20th of a degree -Ny = 20 * 25 -Nz = length(z) - 1 - -grid = LatitudeLongitudeGrid(CPU(); - size = (Nx, Ny, Nz), - latitude = (25, 50), - longitude = (-10, 45), - z, - halo = (7, 7, 7)) - -h = regrid_bathymetry(grid, height_above_water=1) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(h)) - -# All this can be done in a `set_tracers_from_ecco!(model; )` -# Download ecco tracer fields -Tecco = ecco2_field(:temperature); -Secco = ecco2_field(:salinity); - -ecco_tracers = (; Tecco, Secco) - -# Make sure all values are extended properly before regridding -adjust_tracers!(ecco_tracers; mask = ecco2_center_mask()) - -T = CenterField(grid); -S = CenterField(grid); - -three_dimensional_regrid!(T, Tecco) -three_dimensional_regrid!(S, Secco) diff --git a/src/InitialConditions.jl b/src/InitialConditions.jl index f4422fc3..6efd4ca8 100644 --- a/src/InitialConditions.jl +++ b/src/InitialConditions.jl @@ -13,6 +13,8 @@ using Oceananigans.Architectures: architecture, device, GPU using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll +# Maybe we can remove this propagate field in lieu of a diffusion, +# Still we'll need to do this a couple of steps on the original grid @kernel function _propagate_field!(field, tmp_field) i, j, k = @index(Global, NTuple) @@ -109,7 +111,7 @@ function adjust_tracers!(tracers; mask = nothing, max_iter = Inf) propagate_horizontally!(tracer, mask; max_iter) end - # Do we need this? + # Do we need this? Probably on the final grid # diffuse_tracers(initial_tracers; # horizontal_scale, # vertical_scale, @@ -186,7 +188,7 @@ function diffuse_tracers(initial_tracers; return smoothing_model.tracers end -# TODO: move all this to Oceananigans! +# TODO: move all the folowing to Oceananigans! using Oceananigans.Fields: regrid! using Oceananigans.Grids: cpu_face_constructor_x, @@ -225,7 +227,7 @@ function three_dimensional_regrid!(a, b) field_z = Field(location(b), zgrid) regrid!(field_z, zgrid, source_grid, b) - # regrid in y next + # regrid in y @info "Regridding in y" ygrid = construct_grid(typeof(target_grid), arch, (Ns[1], Nt[2], Nt[3]), (xs, yt, zt), topo) field_y = Field(location(b), ygrid); From f94d25edcc9257530125b6ab8efd099e890334cb Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 16 Nov 2023 14:54:21 -0500 Subject: [PATCH 041/716] some change --- src/InitialConditions.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/InitialConditions.jl b/src/InitialConditions.jl index 6efd4ca8..53407763 100644 --- a/src/InitialConditions.jl +++ b/src/InitialConditions.jl @@ -112,13 +112,13 @@ function adjust_tracers!(tracers; mask = nothing, max_iter = Inf) end # Do we need this? Probably on the final grid - # diffuse_tracers(initial_tracers; - # horizontal_scale, - # vertical_scale, - # fractional_time_step, - # mask) + # tracers = diffuse_tracers(tracers; + # horizontal_scale, + # vertical_scale, + # fractional_time_step, + # mask) - return nothing + return tracers end @inline not_an_immersed_cell(i, j, k, grid) = !immersed_cell(i, j, k, grid) From f6eece41de1b7af299a98ad77d102e7c62e2bd60 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 16 Nov 2023 15:06:44 -0500 Subject: [PATCH 042/716] try on tartarus --- examples/freely_decaying_mediterraneum.jl | 44 +++++++++++++++++------ 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index f7d49a70..7080cc1e 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -1,5 +1,6 @@ using GLMakie using Oceananigans +using Oceananigans.Utils: prettytime using ClimaOcean.Bathymetry: regrid_bathymetry using ClimaOcean.ECCO2: ecco2_field, ecco2_center_mask using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching @@ -12,19 +13,19 @@ using Oceananigans.Coriolis: ActiveCellEnstrophyConserving ##### function regrid_ecco_tracers_to_grid(grid) - Tecco = ecco2_field(:temperature); - Secco = ecco2_field(:salinity); + Tecco = ecco2_field(:temperature) + Secco = ecco2_field(:salinity) ecco_tracers = (; Tecco, Secco) # Make sure all values are extended properly before regridding adjust_tracers!(ecco_tracers; mask = ecco2_center_mask()) - T = CenterField(grid); - S = CenterField(grid); + T = CenterField(grid) + S = CenterField(grid) - three_dimensional_regrid!(T, Tecco); - three_dimensional_regrid!(S, Secco); + three_dimensional_regrid!(T, Tecco) + three_dimensional_regrid!(S, Secco) return T, S end @@ -39,7 +40,7 @@ Nx = 20 * 55 # 1 / 20th of a degree Ny = 20 * 25 Nz = length(z) - 1 -grid = LatitudeLongitudeGrid(CPU(); +grid = LatitudeLongitudeGrid(GPU(); size = (Nx, Ny, Nz), latitude = (25, 50), longitude = (0, 45), @@ -80,9 +81,32 @@ set!(model, T = T, S = S) # Probably we'll need to diffuse? Probably not let's see now -simulation = Simulation(model, Δt = 2minutes, stop_time = 10years) +simulation = Simulation(model, Δt = 20, stop_time = 2days) + +function progress(sim) + u, v, w = sim.model.velocities + T, S = sim.model.tracers + + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(T, S): %.2f, %.2f\n", + prettytime(sim.model.clock.time), + sim.model.clock.iteration, + prettytime(sim.Δt), + maximum(abs, u), maximum(abs, v), maximum(abs, w), + maximum(abs, T), maximum(abs, S)) +end + +simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) + +# warm up! +run!(simulation) + +simulation.stop_time = 10*365days + +wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 2minutes, max_change = 1.1) + +simulation.callbacks = Callback(wizard, IterationInterval(10)) + +run!(simulation) -function progress(sim) - From b2af7c13979f0a61bf27e9bf3afe977df800d38d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 16 Nov 2023 15:09:35 -0500 Subject: [PATCH 043/716] try it out on tartarus --- examples/freely_decaying_mediterraneum.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index 7080cc1e..871be804 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -36,14 +36,14 @@ z = stretched_vertical_faces(minimum_depth = 5000, stretching = PowerLawStretching(1.070), surface_layer_height = 50) -Nx = 20 * 55 # 1 / 20th of a degree -Ny = 20 * 25 +Nx = 20 * 42 # 1 / 20th of a degree +Ny = 20 * 15 # 1 / 20th of a degree Nz = length(z) - 1 -grid = LatitudeLongitudeGrid(GPU(); +grid = LatitudeLongitudeGrid(CPU(); size = (Nx, Ny, Nz), - latitude = (25, 50), - longitude = (0, 45), + latitude = (30, 45), + longitude = (0, 42), z, halo = (7, 7, 7)) From 3eab9e723c5a56b78f96c8d5c2616a9b126747c0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 16 Nov 2023 15:22:16 -0500 Subject: [PATCH 044/716] test it on GPU --- examples/freely_decaying_mediterraneum.jl | 27 ++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index 871be804..c3bdc085 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -1,5 +1,6 @@ using GLMakie using Oceananigans +using Oceananigans: architecture using Oceananigans.Utils: prettytime using ClimaOcean.Bathymetry: regrid_bathymetry using ClimaOcean.ECCO2: ecco2_field, ecco2_center_mask @@ -19,7 +20,7 @@ function regrid_ecco_tracers_to_grid(grid) ecco_tracers = (; Tecco, Secco) # Make sure all values are extended properly before regridding - adjust_tracers!(ecco_tracers; mask = ecco2_center_mask()) + adjust_tracers!(ecco_tracers; mask = ecco2_center_mask(architecture(grid))) T = CenterField(grid) S = CenterField(grid) @@ -40,7 +41,7 @@ Nx = 20 * 42 # 1 / 20th of a degree Ny = 20 * 15 # 1 / 20th of a degree Nz = length(z) - 1 -grid = LatitudeLongitudeGrid(CPU(); +grid = LatitudeLongitudeGrid(GPU(); size = (Nx, Ny, Nz), latitude = (30, 45), longitude = (0, 42), @@ -56,11 +57,11 @@ T, S = regrid_ecco_tracers_to_grid(grid) mask_immersed_field!(T) mask_immersed_field!(S) -fig = Figure() -ax = Axis(fig[1, 1]) -heatmap!(ax, interior(T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) -ax = Axis(fig[1, 2]) -heatmap!(ax, interior(S, :, :, Nz), colorrange = (35, 40), colormap = :haline) +# fig = Figure() +# ax = Axis(fig[1, 1]) +# heatmap!(ax, interior(T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) +# ax = Axis(fig[1, 2]) +# heatmap!(ax, interior(S, :, :, Nz), colorrange = (35, 40), colormap = :haline) # Correct oceananigans import Oceananigans.Advection: nothing_to_default @@ -72,9 +73,9 @@ model = HydrostaticFreeSurfaceModel(; grid, momentum_advection = WENOVectorInvariant(), tracer_advection = WENO(grid; order = 7), free_surface = SplitExplicitFreeSurface(; cfl = 0.75, grid), - closure = CATKEVerticalDiffusivity(), + closure = CATKEVerticalDiffusivity(), buoyancy = SeawaterBuoyancy(), - tracers = (:T, :S, :e), + tracers = (:T, :S, :e), coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) set!(model, T = T, S = S) @@ -84,7 +85,7 @@ set!(model, T = T, S = S) simulation = Simulation(model, Δt = 20, stop_time = 2days) function progress(sim) - u, v, w = sim.model.velocities + u, v, w = sim.model.velocities T, S = sim.model.tracers @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(T, S): %.2f, %.2f\n", @@ -106,6 +107,12 @@ wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 2minutes, max_change = 1.1) simulation.callbacks = Callback(wizard, IterationInterval(10)) +simulation.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); + indices = (:, :, Nz), + schedule = TimeInterval(1day), + overwrite_existing = true, + filename = "med_surface_field") + run!(simulation) From fe2e521124558f0c3e4b6e01602f857f7a26a159 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 16 Nov 2023 15:24:52 -0500 Subject: [PATCH 045/716] bugfix --- examples/freely_decaying_mediterraneum.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index c3bdc085..a32f7479 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -5,7 +5,7 @@ using Oceananigans.Utils: prettytime using ClimaOcean.Bathymetry: regrid_bathymetry using ClimaOcean.ECCO2: ecco2_field, ecco2_center_mask using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching -using ClimaOcean.InitialConditions: three_dimensional_regrid! +using ClimaOcean.InitialConditions: three_dimensional_regrid!, adjust_tracers! using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving From 29a61d450285b832d2c975015aa51de6f6b629b3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:40:40 -0500 Subject: [PATCH 046/716] bugfix --- examples/freely_decaying_mediterraneum.jl | 5 +++-- src/DataWrangling/ECCO2.jl | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index a32f7479..ac068612 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -13,7 +13,7 @@ using Oceananigans.Coriolis: ActiveCellEnstrophyConserving ##### Regional Mediterranean grid ##### -function regrid_ecco_tracers_to_grid(grid) +function regrid_ecco_tracers(grid) Tecco = ecco2_field(:temperature) Secco = ecco2_field(:salinity) @@ -25,6 +25,7 @@ function regrid_ecco_tracers_to_grid(grid) T = CenterField(grid) S = CenterField(grid) + # Regrid to our grid! three_dimensional_regrid!(T, Tecco) three_dimensional_regrid!(S, Secco) @@ -52,7 +53,7 @@ h = regrid_bathymetry(grid, height_above_water=1) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(h)) -T, S = regrid_ecco_tracers_to_grid(grid) +T, S = regrid_ecco_tracers(grid) mask_immersed_field!(T) mask_immersed_field!(S) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 0b03deeb..186f72d2 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -112,12 +112,17 @@ function ecco2_field(variable_name; return field end +@kernel function _set_ecco2_mask!(mask, Tᵢ, minimum_value) + i, j, k = @index(Global, NTuple) + @inbounds mask[i, j, k] = ifelse(Tᵢ[i, j, k] < minimum_value, 0, 1) +end + function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) Tᵢ = ecco2_field(:temperature; architecture) mask = CenterField(Tᵢ.grid) # Set the mask with ones where T is defined - set!(mask, (!).(Tᵢ .< minimum_value)) + launch!(architecture, Tᵢ.grid, _set_ecco2_mask!, mask, Tᵢ, minimum_value) return mask end From 9d90b08fdc86ff7f9a91180aff403857b0e966cc Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 17 Nov 2023 09:44:59 -0500 Subject: [PATCH 047/716] some changes --- examples/freely_decaying_mediterraneum.jl | 3 +- examples/generate_bathymetry.jl | 6 +- src/Bathymetry.jl | 102 +++++++++++++++++----- src/DataWrangling/ECCO2.jl | 1 + src/InitialConditions.jl | 5 ++ 5 files changed, 93 insertions(+), 24 deletions(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index ac068612..27fcf15f 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -8,6 +8,7 @@ using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching using ClimaOcean.InitialConditions: three_dimensional_regrid!, adjust_tracers! using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving +using Oceananigans.Units ##### ##### Regional Mediterranean grid @@ -42,7 +43,7 @@ Nx = 20 * 42 # 1 / 20th of a degree Ny = 20 * 15 # 1 / 20th of a degree Nz = length(z) - 1 -grid = LatitudeLongitudeGrid(GPU(); +grid = LatitudeLongitudeGrid(CPU(); size = (Nx, Ny, Nz), latitude = (30, 45), longitude = (0, 42), diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 64ebc579..a989069f 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -35,8 +35,12 @@ 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), diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 37ae85e5..c4232195 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -4,8 +4,13 @@ using ..DataWrangling: download_progress using Oceananigans using Oceananigans.Architectures: architecture -using Oceananigans.Grids: halo_size, λnodes -using Oceananigans.Utils: pretty_filesize +using Oceananigans.Grids: halo_size, λnodes, φnodes +using Oceananigans.Grids: x_domain, y_domain +using Oceananigans.Grids: topology +using Oceananigans.Utils: pretty_filesize, launch! +using Oceananigans.Fields: interpolate! +using Oceananigans.BoundaryConditions +using KernelAbstractions: @kernel, @index using NCDatasets using Downloads @@ -22,14 +27,38 @@ using Printf Regrid bathymetry associated with the NetCDF file at `path = joinpath(dir, filename)` to `target_grid`. If `path` does not exist, then a download is attempted from `joinpath(url, filename)`. -TODO: describe keyword arguments. +Arguments: +========== + +- target_grid: grid to interpolate onto + +Keyword Arguments: +================== + +- height_above_water: limits the maximum height of above-water topography (where h > 0). If + `nothing` the original topography is retained + +- minimum_depth: minimum depth for the shallow regions. `h > minimum_depth` will be considered land + +- dir: directory of the bathymetry-containing file + +- filename: file containing bathymetric data. Must be netcdf with fields: + (1) `lat` vector of latitude nodes + (2) `lon` vector of longitude nodes + (3) `z` matrix of depth values + +- interpolation_passes: regridding/interpolation passes. The bathymetry is interpolated in + `interpolation_passes - 1` intermediate steps. With more steps the + final bathymetry will be smoother. + """ function regrid_bathymetry(target_grid; height_above_water = nothing, minimum_depth = 0, dir = joinpath(@__DIR__, "..", "data"), url = "https://www.ngdc.noaa.gov/thredds/fileServer/global/ETOPO2022/60s/60s_surface_elev_netcdf", - filename = "ETOPO_2022_v1_60s_N90W180_surface.nc") + filename = "ETOPO_2022_v1_60s_N90W180_surface.nc", + interpolation_passes = 10) filepath = joinpath(dir, filename) @@ -106,8 +135,8 @@ function regrid_bathymetry(target_grid; end if minimum_depth > 0 - ocean = h_data .<= 0 - h_data[ocean] .= min.(-minimum_depth, h_data[ocean]) + shallow_ocean = h_data .> minimum_depth + h_data[shallow_ocean] .= height_above_water end # Build the "native" grid of the bathymetry and make a bathymetry field. @@ -125,28 +154,57 @@ function regrid_bathymetry(target_grid; native_h = Field{Center, Center, Nothing}(native_grid) set!(native_h, h_data) - Nxi = Nxt - Nyi = Nyn - Nzi = Nzn + # + target_h = interpolate_bathymetry_in_passes(native_h, target_grid; passes = interpolation_passes) - if parent(parent(λt)) isa StepRangeLen # longitude is equispaced - longitude = (λ₁, λ₂) - else - longitude = λnodes(target_grid, Face(), Center(), Center()) + return target_h +end + +# Here we can either use `regrid!` (three dimensional version) or `interpolate` +function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) + + Nλt, Nφt = Nt = size(target_grid) + Nλn, Nφn = Nn = size(native_h) + + if any(Nt .> Nn) # We are refining the grid (at least in one direction), more passes will not help! + new_h = Field{Center, Center, Nothing}(target_grid) + interpolate!(new_h, native_h) + return new_h end + + latitude = y_domain(target_grid) + longitude = x_domain(target_grid) + + ΔNλ = floor((Nλn - Nλt) / passes) + ΔNφ = floor((Nφn - Nφt) / passes) + + Nλ = [Nλn - ΔNλ * pass for pass in 1:passes-1] + Nφ = [Nφn - ΔNφ * pass for pass in 1:passes-1] - intermediate_grid = LatitudeLongitudeGrid(arch; - size = (Nxi, Nyi, Nzi), - latitude = (φ₁, φ₂), - longitude, - z = (0, 1), - halo = halo_size(target_grid)) + Nλ = Int[Nλ..., Nλt] + Nφ = Int[Nφ..., Nφt] - intermediate_h = Field{Center, Center, Nothing}(intermediate_grid) - regrid!(intermediate_h, native_h) + old_h = native_h + TX, TY, _ = topology(target_grid) + + for pass = 1:passes - 1 + new_size = (Nλ[pass], Nφ[pass], 1) + + @info "pass number $pass with size $new_size" + new_grid = LatitudeLongitudeGrid(size = new_size, + latitude = (latitude[1], latitude[2]), + longitude = (longitude[1], longitude[2]), + z = (0, 1), + topology = (TX, TY, Bounded)) + + new_h = Field{Center, Center, Nothing}(new_grid) + + interpolate!(new_h, old_h) + old_h = new_h + end target_h = Field{Center, Center, Nothing}(target_grid) - regrid!(target_h, intermediate_h) + interpolate!(target_h, old_h) return target_h end diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 186f72d2..71ee81eb 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -2,6 +2,7 @@ module ECCO2 using Oceananigans using Oceananigans.BoundaryConditions +using KernelAbstractions: @kernel, @index using NCDatasets temperature_filename = "THETA.1440x720x50.19920102.nc" diff --git a/src/InitialConditions.jl b/src/InitialConditions.jl index 53407763..774d38ed 100644 --- a/src/InitialConditions.jl +++ b/src/InitialConditions.jl @@ -50,6 +50,11 @@ end propagate_horizontally!(field, ::Nothing; kw...) = nothing +""" + propagate_horizontally!(field, mask; max_iter = Inf) + +propagate horizontally +""" function propagate_horizontally!(field, mask; max_iter = Inf) iter = 0 grid = field.grid From f10b9f1f94e653fd1572f461fa032de1b8a27dc1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 17 Nov 2023 09:49:12 -0500 Subject: [PATCH 048/716] change example --- examples/generate_bathymetry.jl | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index a989069f..e52d80ac 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -46,16 +46,21 @@ grid = LatitudeLongitudeGrid(CPU(); 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 = 10) +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(resolution=(2400, 1200)) +fig = Figure(resolution=(2400, 800)) 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 9f22cfdfb5e0a8d0558d93d3103d3e887323e7a8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 17 Nov 2023 09:55:50 -0500 Subject: [PATCH 049/716] some exports --- examples/freely_decaying_mediterraneum.jl | 6 ++---- src/Bathymetry.jl | 2 ++ src/ClimaOcean.jl | 6 ++++++ src/DataWrangling/ECCO2.jl | 2 ++ src/VerticalGrids.jl | 2 ++ 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index 27fcf15f..03d51a96 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -1,10 +1,8 @@ using GLMakie using Oceananigans using Oceananigans: architecture -using Oceananigans.Utils: prettytime -using ClimaOcean.Bathymetry: regrid_bathymetry -using ClimaOcean.ECCO2: ecco2_field, ecco2_center_mask -using ClimaOcean.VerticalGrids: stretched_vertical_faces, PowerLawStretching +using ClimaOcean +using ClimaOcean.ECCO2 using ClimaOcean.InitialConditions: three_dimensional_regrid!, adjust_tracers! using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index c4232195..7f6468f5 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -1,5 +1,7 @@ module Bathymetry +export regrid_bathymetry + using ..DataWrangling: download_progress using Oceananigans diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index d256bf13..e6361201 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -1,5 +1,11 @@ module ClimaOcean +export regrid_bathymetry +export stretched_vertical_faces +export PowerLawStretching, LinearStretching +export jra55_field_time_series +export ecco2_field + using Oceananigans using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ using DataDeps diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 71ee81eb..92a8b758 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -1,5 +1,7 @@ module ECCO2 +export ecco2_field, ecco2_center_mask + using Oceananigans using Oceananigans.BoundaryConditions using KernelAbstractions: @kernel, @index diff --git a/src/VerticalGrids.jl b/src/VerticalGrids.jl index e3c7d162..be42135a 100644 --- a/src/VerticalGrids.jl +++ b/src/VerticalGrids.jl @@ -1,5 +1,7 @@ module VerticalGrids +export stretched_vertical_faces, PowerLawStretching, LinearStretching + struct PowerLawStretching{T} power :: T end From 02112d1661ddad98e68b4e1fdb53a8bea00df832 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 17 Nov 2023 10:10:05 -0500 Subject: [PATCH 050/716] depth instead of minimum_depth --- src/ClimaOcean.jl | 3 +++ src/DataWrangling/ECCO2.jl | 3 ++- src/VerticalGrids.jl | 10 +++++----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index e6361201..de4fcee8 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -71,6 +71,9 @@ include("InitialConditions.jl") include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") +using .VerticalGrids +using .InitialConditions +using .Bathymetry using .DataWrangling: JRA55 using .DataWrangling: ECCO2 diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 92a8b758..b3858c1f 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -4,6 +4,7 @@ export ecco2_field, ecco2_center_mask using Oceananigans using Oceananigans.BoundaryConditions +using Oceananigans.Utils using KernelAbstractions: @kernel, @index using NCDatasets @@ -125,7 +126,7 @@ function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) mask = CenterField(Tᵢ.grid) # Set the mask with ones where T is defined - launch!(architecture, Tᵢ.grid, _set_ecco2_mask!, mask, Tᵢ, minimum_value) + launch!(architecture, Tᵢ.grid, :xyz, _set_ecco2_mask!, mask, Tᵢ, minimum_value) return mask end diff --git a/src/VerticalGrids.jl b/src/VerticalGrids.jl index be42135a..220d791c 100644 --- a/src/VerticalGrids.jl +++ b/src/VerticalGrids.jl @@ -27,12 +27,12 @@ end maximum_Δz = Inf, stretching = PowerLawStretching(1.02), rounding_digits = 1, - minimum_depth = 5000) + depth = 5000) Return an array of cell interfaces with `surface_layer_Δz` spacing in a surface layer of height `surface_layer_height`, and stretched according to -the function `stretching(Δz_above, z_above)` down to `minimum_depth`. -The interfaces extends from `Lz = -z[1]` to `0 = z[end]`, where `Lz ≥ minimum_depth`. +the function `stretching(Δz_above, z_above)` down to `depth`. +The interfaces extends from `Lz = -z[1]` to `0 = z[end]`, where `Lz ≥ depth`. The grid spacing `Δz` is limited to be less than `maximum_Δz`. The grid is also uniformly-spaced below `constant_bottom_spacing_depth`. @@ -45,7 +45,7 @@ function stretched_vertical_faces(; surface_layer_Δz = 5.0, maximum_Δz = Inf, stretching = PowerLawStretching(1.02), rounding_digits = 1, - minimum_depth = 5000) + depth = 5000) Δz₀ = surface_layer_Δz h₀ = surface_layer_height @@ -54,7 +54,7 @@ function stretched_vertical_faces(; surface_layer_Δz = 5.0, z = [-Δz₀ * (k-1) for k = 1:ceil(h₀ / Δz₀)] # Generate stretched interior grid - Lz₀ = minimum_depth + Lz₀ = depth while z[end] > - Lz₀ Δz_above = z[end-1] - z[end] From 1713ee13244b35e79baf11fdd1e672411be8120c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 20 Nov 2023 09:35:45 -0700 Subject: [PATCH 051/716] 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 052/716] 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 053/716] 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 054/716] 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 055/716] 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 59a39cf8b06d4b24d69c79555ed6c0a038261f62 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:23:51 -0500 Subject: [PATCH 056/716] works without diffusion? --- examples/freely_decaying_mediterraneum.jl | 65 ++++++++++------------- src/Bathymetry.jl | 20 +++---- src/DataWrangling/ECCO2.jl | 27 +++++++++- src/InitialConditions.jl | 6 +-- 4 files changed, 65 insertions(+), 53 deletions(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index 03d51a96..88e41b16 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -1,46 +1,32 @@ using GLMakie using Oceananigans using Oceananigans: architecture +using Oceananigans.Fields: interpolate! using ClimaOcean using ClimaOcean.ECCO2 using ClimaOcean.InitialConditions: three_dimensional_regrid!, adjust_tracers! +using Oceananigans.ImmersedBoundaries: mask_immersed_field! using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units +using Printf ##### ##### Regional Mediterranean grid ##### -function regrid_ecco_tracers(grid) - Tecco = ecco2_field(:temperature) - Secco = ecco2_field(:salinity) - - ecco_tracers = (; Tecco, Secco) - - # Make sure all values are extended properly before regridding - adjust_tracers!(ecco_tracers; mask = ecco2_center_mask(architecture(grid))) - - T = CenterField(grid) - S = CenterField(grid) - - # Regrid to our grid! - three_dimensional_regrid!(T, Tecco) - three_dimensional_regrid!(S, Secco) - - return T, S -end - # A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters -z = stretched_vertical_faces(minimum_depth = 5000, - surface_layer_Δz = 1.75, +z = stretched_vertical_faces(depth = 5000, + surface_layer_Δz = 2.5, stretching = PowerLawStretching(1.070), surface_layer_height = 50) -Nx = 20 * 42 # 1 / 20th of a degree -Ny = 20 * 15 # 1 / 20th of a degree +Nx = 4 * 42 # 1 / 4th of a degree +Ny = 4 * 15 # 1 / 4th of a degree Nz = length(z) - 1 +@info "grid size: ($Nx, $Ny, $Nz)" + grid = LatitudeLongitudeGrid(CPU(); size = (Nx, Ny, Nz), latitude = (30, 45), @@ -52,16 +38,23 @@ h = regrid_bathymetry(grid, height_above_water=1) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(h)) -T, S = regrid_ecco_tracers(grid) +Tecco, Secco = initial_ecco_tracers(architecture(grid)) + +T = CenterField(grid) +S = CenterField(grid) + +# Regrid to our grid! +three_dimensional_regrid!(T, Tecco) +three_dimensional_regrid!(S, Secco) mask_immersed_field!(T) mask_immersed_field!(S) -# fig = Figure() -# ax = Axis(fig[1, 1]) -# heatmap!(ax, interior(T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) -# ax = Axis(fig[1, 2]) -# heatmap!(ax, interior(S, :, :, Nz), colorrange = (35, 40), colormap = :haline) +fig = Figure() +ax = Axis(fig[1, 1]) +heatmap!(ax, interior(T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) +ax = Axis(fig[1, 2]) +heatmap!(ax, interior(S, :, :, Nz), colorrange = (35, 40), colormap = :haline) # Correct oceananigans import Oceananigans.Advection: nothing_to_default @@ -78,11 +71,9 @@ model = HydrostaticFreeSurfaceModel(; grid, tracers = (:T, :S, :e), coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) -set!(model, T = T, S = S) - -# Probably we'll need to diffuse? Probably not let's see now +set!(model, T = T, S = S, e = 1e-6) -simulation = Simulation(model, Δt = 20, stop_time = 2days) +simulation = Simulation(model, Δt = 20, stop_iteration = 100) function progress(sim) u, v, w = sim.model.velocities @@ -96,16 +87,16 @@ function progress(sim) maximum(abs, T), maximum(abs, S)) end -simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) +simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) -# warm up! +# warm up for 100 iterations! run!(simulation) simulation.stop_time = 10*365days -wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 2minutes, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 10minutes, max_change = 1.1) -simulation.callbacks = Callback(wizard, IterationInterval(10)) +simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) simulation.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); indices = (:, :, Nz), diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 7f6468f5..713b84df 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -86,15 +86,9 @@ function regrid_bathymetry(target_grid; close(dataset) # Diagnose target grid information - Nxt, Nyt, Nzt = size(target_grid) arch = architecture(target_grid) - λt, φt, zt = nodes(target_grid, Face(), Face(), Face()) - - λ₁ = λt[1] - λ₂ = λt[Nxt] - - φ₁ = φt[1] - φ₂ = φt[Nyt] + φ₁, φ₂ = y_domain(target_grid) + λ₁, λ₂ = x_domain(target_grid) # Calculate limiting indices on the bathymetry grid i₁ = searchsortedfirst(λ_data, λ₁) @@ -151,12 +145,11 @@ function regrid_bathymetry(target_grid; latitude = (φ₁, φ₂), longitude = (λ₁, λ₂), z = (0, 1), - halo = halo_size(target_grid)) + halo = (10, 10, 1)) native_h = Field{Center, Center, Nothing}(native_grid) set!(native_h, h_data) - # target_h = interpolate_bathymetry_in_passes(native_h, target_grid; passes = interpolation_passes) return target_h @@ -164,11 +157,10 @@ end # Here we can either use `regrid!` (three dimensional version) or `interpolate` function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) - Nλt, Nφt = Nt = size(target_grid) Nλn, Nφn = Nn = size(native_h) - if any(Nt .> Nn) # We are refining the grid (at least in one direction), more passes will not help! + if any(Nt[1:2] .> Nn[1:2]) # We are refining the grid (at least in one direction), more passes will not help! new_h = Field{Center, Center, Nothing}(target_grid) interpolate!(new_h, native_h) return new_h @@ -177,6 +169,9 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) latitude = y_domain(target_grid) longitude = x_domain(target_grid) + @show latitude, longitude + @show x_domain(native_h.grid), y_domain(native_h.grid) + ΔNλ = floor((Nλn - Nλt) / passes) ΔNφ = floor((Nφn - Nφt) / passes) @@ -191,6 +186,7 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) for pass = 1:passes - 1 new_size = (Nλ[pass], Nφ[pass], 1) + @show Nt, Nn, new_size @info "pass number $pass with size $new_size" new_grid = LatitudeLongitudeGrid(size = new_size, diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index b3858c1f..cb8c0093 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -1,6 +1,8 @@ module ECCO2 -export ecco2_field, ecco2_center_mask +export ecco2_field, ecco2_center_mask, initial_ecco_tracers + +using ClimaOcean.InitialConditions: adjust_tracers! using Oceananigans using Oceananigans.BoundaryConditions @@ -152,5 +154,28 @@ function ecco2_bottom_height_from_temperature() return bottom_height end +function initial_ecco_tracers(architecture; + overwrite_existing = true, + initial_condition_file = "../data/initial_ecco_tracers.nc") + + if overwrite_existing || !isfile(initial_condition_file) + T = ecco2_field(:temperature; architecture) + S = ecco2_field(:salinity; architecture) + + # Make sure all values are extended properly before regridding + adjust_tracers!((; T, S); mask = ecco2_center_mask(architecture)) + + nc = Dataset(initial_condition_file, "w") + nc["T"] = interior(Tecco) + nc["S"] = interior(Tecco) + else + nc = Dataset(initial_condition_file) + T = nc["T"] + S = nc["S"] + end + + return T, S +end + end # module diff --git a/src/InitialConditions.jl b/src/InitialConditions.jl index 774d38ed..94c628f1 100644 --- a/src/InitialConditions.jl +++ b/src/InitialConditions.jl @@ -227,19 +227,19 @@ function three_dimensional_regrid!(a, b) source_size = Ns = size(source_grid) # Start by regridding in z - @info "Regridding in z" + @debug "Regridding in z" zgrid = construct_grid(typeof(target_grid), arch, (Ns[1], Ns[2], Nt[3]), (xs, ys, zt), topo) field_z = Field(location(b), zgrid) regrid!(field_z, zgrid, source_grid, b) # regrid in y - @info "Regridding in y" + @debug "Regridding in y" ygrid = construct_grid(typeof(target_grid), arch, (Ns[1], Nt[2], Nt[3]), (xs, yt, zt), topo) field_y = Field(location(b), ygrid); regrid!(field_y, ygrid, zgrid, field_z); # Finally regrid in x - @info "Regridding in x" + @debug "Regridding in x" regrid!(a, target_grid, ygrid, field_y) end From 8f39ee184b29e4871c3bf9b463a13d9c3a4cfde5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:30:33 -0500 Subject: [PATCH 057/716] better --- src/Bathymetry.jl | 4 +++- src/ClimaOcean.jl | 2 +- src/InitialConditions.jl | 7 ------- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 713b84df..6b2a216a 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -79,9 +79,11 @@ function regrid_bathymetry(target_grid; dataset = Dataset(filepath) + FT = eltype(target_grid) + φ_data = dataset["lat"][:] λ_data = dataset["lon"][:] - h_data = dataset["z"][:, :] + h_data = convert.(FT, dataset["z"][:, :]) close(dataset) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index de4fcee8..778b4cf7 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -65,9 +65,9 @@ end @inline v_immersed_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) include("VerticalGrids.jl") +include("InitialConditions.jl") include("DataWrangling/DataWrangling.jl") include("Bathymetry.jl") -include("InitialConditions.jl") include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") diff --git a/src/InitialConditions.jl b/src/InitialConditions.jl index 94c628f1..65de3284 100644 --- a/src/InitialConditions.jl +++ b/src/InitialConditions.jl @@ -116,13 +116,6 @@ function adjust_tracers!(tracers; mask = nothing, max_iter = Inf) propagate_horizontally!(tracer, mask; max_iter) end - # Do we need this? Probably on the final grid - # tracers = diffuse_tracers(tracers; - # horizontal_scale, - # vertical_scale, - # fractional_time_step, - # mask) - return tracers end From a16c354880d6ff09560d846c637dfeae3b61972c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 21 Nov 2023 12:40:34 -0700 Subject: [PATCH 058/716] 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 9f2988293f1952238de7dc4073289a0a8b73380f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 14:48:19 -0500 Subject: [PATCH 059/716] little more "blackboxy" --- examples/freely_decaying_mediterraneum.jl | 26 ++---- src/DataWrangling/ECCO2.jl | 98 ++++++++++++++--------- src/InitialConditions.jl | 13 ++- 3 files changed, 79 insertions(+), 58 deletions(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index 88e41b16..a9c48766 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -38,24 +38,6 @@ h = regrid_bathymetry(grid, height_above_water=1) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(h)) -Tecco, Secco = initial_ecco_tracers(architecture(grid)) - -T = CenterField(grid) -S = CenterField(grid) - -# Regrid to our grid! -three_dimensional_regrid!(T, Tecco) -three_dimensional_regrid!(S, Secco) - -mask_immersed_field!(T) -mask_immersed_field!(S) - -fig = Figure() -ax = Axis(fig[1, 1]) -heatmap!(ax, interior(T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) -ax = Axis(fig[1, 2]) -heatmap!(ax, interior(S, :, :, Nz), colorrange = (35, 40), colormap = :haline) - # Correct oceananigans import Oceananigans.Advection: nothing_to_default @@ -71,7 +53,13 @@ model = HydrostaticFreeSurfaceModel(; grid, tracers = (:T, :S, :e), coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) -set!(model, T = T, S = S, e = 1e-6) +initialize!(model, T = :ecco2_temperature, S = :ecco2_salinity, e = 1e-6) + +fig = Figure() +ax = Axis(fig[1, 1]) +heatmap!(ax, interior(model.tracers.T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) +ax = Axis(fig[1, 2]) +heatmap!(ax, interior(model.tracers.S, :, :, Nz), colorrange = (35, 40), colormap = :haline) simulation = Simulation(model, Δt = 20, stop_iteration = 100) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index cb8c0093..edad45e7 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -1,8 +1,8 @@ module ECCO2 -export ecco2_field, ecco2_center_mask, initial_ecco_tracers +export ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! -using ClimaOcean.InitialConditions: adjust_tracers! +using ClimaOcean.InitialConditions: adjust_tracer!, three_dimensional_regrid using Oceananigans using Oceananigans.BoundaryConditions @@ -14,6 +14,12 @@ temperature_filename = "THETA.1440x720x50.19920102.nc" salinity_filename = "SALT.1440x720x50.19920102.nc" effective_ice_thickness_filename = "SIheff.1440x720.19920102.nc" +ecco2_tracer_fields = Dict( + :ecco2_temperature => :temperature, + :ecco2_salinity => :salinity, + :ecco_2_effective_ice_thickness => :effective_ice_thickness +) + ecco2_short_names = Dict( :temperature => "THETA", :salinity => "SALT", @@ -110,8 +116,10 @@ function ecco2_field(variable_name; grid = LatitudeLongitudeGrid(architecture; halo, size = N, topology = (TX, TY, TZ), longitude, latitude, z) + FT = eltype(grid) field = Field{Center, Center, LZ}(grid) - + data = convert.(FT, data) + set!(field, data) fill_halo_regions!(field) @@ -133,48 +141,66 @@ function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) return mask end -function ecco2_bottom_height_from_temperature() - Tᵢ = ecco2_field(:temperature) - grid = Tᵢ.grid - - # Construct bottom_height depth by analyzing T - Nx, Ny, Nz = size(Tᵢ) - bottom_height = ones(Nx, Ny) .* grid.Lz - zf = znodes(Tᵢ.grid, Face()) +function adjusted_ecco_field(variable_name; + architecture = CPU(), + overwrite_existing = true, + filename = "./data/initial_ecco_tracers.nc") - 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 + if overwrite_existing || !isfile(filename) + f = ecco2_field(variable_name; architecture) + + # Make sure all values are extended properly + adjust_tracer!(f; mask = ecco2_center_mask(architecture)) + + ds = Dataset(filename, "c") + defVar(ds, string(variable_name), f, ("lat", "lon", "z")) + else + ds = Dataset(filename) + + if haskey(ds, string(variable_name)) + f = ds[variable_name][:, :, :] + else + f = ecco2_field(variable_name; architecture) + # Make sure all values are extended properly + adjust_tracer!(f; mask = ecco2_center_mask(architecture)) + + defVar(ds, string(variable_name), f, ("lat", "lon", "z")) end end - return bottom_height + return f end -function initial_ecco_tracers(architecture; - overwrite_existing = true, - initial_condition_file = "../data/initial_ecco_tracers.nc") - - if overwrite_existing || !isfile(initial_condition_file) - T = ecco2_field(:temperature; architecture) - S = ecco2_field(:salinity; architecture) - - # Make sure all values are extended properly before regridding - adjust_tracers!((; T, S); mask = ecco2_center_mask(architecture)) +function initialize!(model; + overwrite_existing = true, + filename = "./data/initial_ecco_tracers.nc", + kwargs...) - nc = Dataset(initial_condition_file, "w") - nc["T"] = interior(Tecco) - nc["S"] = interior(Tecco) - else - nc = Dataset(initial_condition_file) - T = nc["T"] - S = nc["S"] + arch = architecture(model) + + ordinary_fields = Dict() + ecco2_fields = Dict() + + for (fldname, value) in kwargs + if value ∈ keys(ecco2_tracer_fields) + ecco2_fields[fldname] = value + else + ordinary_fields[fldname] = value + end end - return T, S + # Additional tracers not present in the ECCO dataset + set!(model; ordinary_fields...) + + # Set tracers from ecco2 + for fldname in keys(ecco2_fields) + f = adjusted_ecco_field(fldname; + architecture = arch, + overwrite_existing, + filename) + + set!(model; variable_name => f) + end end end # module diff --git a/src/InitialConditions.jl b/src/InitialConditions.jl index 65de3284..46872a3e 100644 --- a/src/InitialConditions.jl +++ b/src/InitialConditions.jl @@ -108,17 +108,24 @@ end @inbounds tracer[i, j, k] = ifelse(mask(i, j, k, grid) == 1, initial_tracer[i, j, k], tracer[i, j, k]) end -function adjust_tracers!(tracers; mask = nothing, max_iter = Inf) +function adjust_tracer!(tracers::NamedTuple; mask = nothing, max_iter = Inf) for (name, tracer) in zip(keys(tracers), tracers) @info "extending tracer $name" - continue_downwards!(tracer, mask) - propagate_horizontally!(tracer, mask; max_iter) + adjust_tracer!(tracer; mask, max_iter) end return tracers end +function adjust_tracer!(tracer; mask = nothing, max_iter = Inf) + + continue_downwards!(tracer, mask) + propagate_horizontally!(tracer, mask; max_iter) + + return tracer +end + @inline not_an_immersed_cell(i, j, k, grid) = !immersed_cell(i, j, k, grid) function diffuse_tracers(initial_tracers; From 9790836b7423c0db26097fb771c1c34e4ae7355a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 14:50:14 -0500 Subject: [PATCH 060/716] forgot to regrid --- src/DataWrangling/ECCO2.jl | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index edad45e7..ce1b0691 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -2,7 +2,7 @@ module ECCO2 export ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! -using ClimaOcean.InitialConditions: adjust_tracer!, three_dimensional_regrid +using ClimaOcean.InitialConditions: adjust_tracer!, three_dimensional_regrid! using Oceananigans using Oceananigans.BoundaryConditions @@ -26,6 +26,12 @@ ecco2_short_names = Dict( :effective_ice_thickness => "SIheff" ) +ecco2_location = Dict( + :temperature => (Center, Center, Center), + :salinity => (Center, Center, Center), + :effective_ice_thickness => (Center, Center, Nothing) +) + ecco2_depth_names = Dict( :temperature => "DEPTH_T", :salinity => "DEPTH_T", @@ -198,8 +204,11 @@ function initialize!(model; architecture = arch, overwrite_existing, filename) + + f_grid = Field(ecco2_location[variable_name], model.grid) + three_dimensional_regrid!(f_grid, f) - set!(model; variable_name => f) + set!(model; variable_name => f_grid) end end From aa7c2d8b2c921d53b40908717401eecaadfe77b5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:04:31 -0500 Subject: [PATCH 061/716] works --- examples/freely_decaying_mediterraneum.jl | 11 ++++-- src/DataWrangling/ECCO2.jl | 47 +++++++++++++++-------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterraneum.jl index a9c48766..66d7b063 100644 --- a/examples/freely_decaying_mediterraneum.jl +++ b/examples/freely_decaying_mediterraneum.jl @@ -1,11 +1,8 @@ using GLMakie using Oceananigans using Oceananigans: architecture -using Oceananigans.Fields: interpolate! using ClimaOcean using ClimaOcean.ECCO2 -using ClimaOcean.InitialConditions: three_dimensional_regrid!, adjust_tracers! -using Oceananigans.ImmersedBoundaries: mask_immersed_field! using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units @@ -43,7 +40,7 @@ import Oceananigans.Advection: nothing_to_default nothing_to_default(user_value; default) = isnothing(user_value) ? default : user_value -# Construct the model and run it, will it run or we have to diffuse? +# Construct the model and run it model = HydrostaticFreeSurfaceModel(; grid, momentum_advection = WENOVectorInvariant(), tracer_advection = WENO(grid; order = 7), @@ -53,6 +50,12 @@ model = HydrostaticFreeSurfaceModel(; grid, tracers = (:T, :S, :e), coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) +# Initializing the model +# +# the model can be initialized with custom values or with ecco2 fields. +# In this case, our ECCO2 dataset has access to a temperature and a salinity +# field, so we initialize T and S from ECCO2. We initialize TKE (:e) with a +# constant value of 1e-6 m²/s² throughout the domain initialize!(model, T = :ecco2_temperature, S = :ecco2_salinity, e = 1e-6) fig = Figure() diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index ce1b0691..3830b19d 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -5,6 +5,7 @@ export ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.InitialConditions: adjust_tracer!, three_dimensional_regrid! using Oceananigans +using Oceananigans: architecture using Oceananigans.BoundaryConditions using Oceananigans.Utils using KernelAbstractions: @kernel, @index @@ -150,13 +151,14 @@ end function adjusted_ecco_field(variable_name; architecture = CPU(), overwrite_existing = true, - filename = "./data/initial_ecco_tracers.nc") + filename = "./data/initial_ecco_tracers.nc", + mask = ecco2_center_mask(architecture)) if overwrite_existing || !isfile(filename) f = ecco2_field(variable_name; architecture) # Make sure all values are extended properly - adjust_tracer!(f; mask = ecco2_center_mask(architecture)) + adjust_tracer!(f; mask) ds = Dataset(filename, "c") defVar(ds, string(variable_name), f, ("lat", "lon", "z")) @@ -168,7 +170,7 @@ function adjusted_ecco_field(variable_name; else f = ecco2_field(variable_name; architecture) # Make sure all values are extended properly - adjust_tracer!(f; mask = ecco2_center_mask(architecture)) + adjust_tracer!(f; mask) defVar(ds, string(variable_name), f, ("lat", "lon", "z")) end @@ -182,34 +184,45 @@ function initialize!(model; filename = "./data/initial_ecco_tracers.nc", kwargs...) - arch = architecture(model) - + grid = model.grid + arch = architecture(grid) + ordinary_fields = Dict() ecco2_fields = Dict() + # Differentiate between custom initialization and ECCO2 initialization for (fldname, value) in kwargs if value ∈ keys(ecco2_tracer_fields) - ecco2_fields[fldname] = value + ecco2_fields[fldname] = ecco2_tracer_fields[value] else ordinary_fields[fldname] = value end end # Additional tracers not present in the ECCO dataset - set!(model; ordinary_fields...) + if !isempty(ordinary_fields) + set!(model; ordinary_fields...) + end # Set tracers from ecco2 - for fldname in keys(ecco2_fields) - f = adjusted_ecco_field(fldname; - architecture = arch, - overwrite_existing, - filename) - - f_grid = Field(ecco2_location[variable_name], model.grid) - three_dimensional_regrid!(f_grid, f) - - set!(model; variable_name => f_grid) + if !isempty(ecco2_fields) + mask = ecco2_center_mask(architecture(grid)) + + for (fldname, variable_name) in ecco2_fields + f = adjusted_ecco_field(variable_name; + architecture = arch, + overwrite_existing, + filename, + mask) + + f_grid = Field(ecco2_location[variable_name], grid) + three_dimensional_regrid!(f_grid, f) + + set!(model; fldname => f_grid) + end end + + return nothing end end # module From be3bff814c6390907336a3f52b64056e321d5d26 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:07:26 -0500 Subject: [PATCH 062/716] take away show --- src/Bathymetry.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 6b2a216a..4c93da4c 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -188,9 +188,8 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) for pass = 1:passes - 1 new_size = (Nλ[pass], Nφ[pass], 1) - @show Nt, Nn, new_size - @info "pass number $pass with size $new_size" + @debug "pass number $pass with size $new_size" new_grid = LatitudeLongitudeGrid(size = new_size, latitude = (latitude[1], latitude[2]), longitude = (longitude[1], longitude[2]), From 351debc7132af73e89e588352960d546ccfd6842 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:07:37 -0500 Subject: [PATCH 063/716] take away show --- src/Bathymetry.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 4c93da4c..ca1d35d4 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -171,9 +171,6 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) latitude = y_domain(target_grid) longitude = x_domain(target_grid) - @show latitude, longitude - @show x_domain(native_h.grid), y_domain(native_h.grid) - ΔNλ = floor((Nλn - Nλt) / passes) ΔNφ = floor((Nφn - Nφt) / passes) From 75dbdf79d714a09ad53c90717fbade8a8fb88073 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:17:32 -0500 Subject: [PATCH 064/716] some changes --- src/DataWrangling/ECCO2.jl | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 3830b19d..0e9f7257 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -150,7 +150,7 @@ end function adjusted_ecco_field(variable_name; architecture = CPU(), - overwrite_existing = true, + overwrite_existing = false, filename = "./data/initial_ecco_tracers.nc", mask = ecco2_center_mask(architecture)) @@ -162,6 +162,8 @@ function adjusted_ecco_field(variable_name; ds = Dataset(filename, "c") defVar(ds, string(variable_name), f, ("lat", "lon", "z")) + + close(ds) else ds = Dataset(filename) @@ -174,37 +176,39 @@ function adjusted_ecco_field(variable_name; defVar(ds, string(variable_name), f, ("lat", "lon", "z")) end + + close(ds) end return f end function initialize!(model; - overwrite_existing = true, + overwrite_existing = false, filename = "./data/initial_ecco_tracers.nc", kwargs...) grid = model.grid arch = architecture(grid) - ordinary_fields = Dict() - ecco2_fields = Dict() + custom_fields = Dict() + ecco2_fields = Dict() # Differentiate between custom initialization and ECCO2 initialization for (fldname, value) in kwargs if value ∈ keys(ecco2_tracer_fields) ecco2_fields[fldname] = ecco2_tracer_fields[value] else - ordinary_fields[fldname] = value + custom_fields[fldname] = value end end # Additional tracers not present in the ECCO dataset - if !isempty(ordinary_fields) - set!(model; ordinary_fields...) + if !isempty(custom_fields) + set!(model; custom_fields...) end - # Set tracers from ecco2 + # Set tracers from ECCO2 if !isempty(ecco2_fields) mask = ecco2_center_mask(architecture(grid)) From a2aff1adfd83cd0691640698a6228d81969a92b0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:21:10 -0500 Subject: [PATCH 065/716] name change --- ...decaying_mediterraneum.jl => freely_decaying_mediterranean.jl} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{freely_decaying_mediterraneum.jl => freely_decaying_mediterranean.jl} (100%) diff --git a/examples/freely_decaying_mediterraneum.jl b/examples/freely_decaying_mediterranean.jl similarity index 100% rename from examples/freely_decaying_mediterraneum.jl rename to examples/freely_decaying_mediterranean.jl From fc59ff83d74d3d9166d9d5c73f4b257c1685a43c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:01:53 -0500 Subject: [PATCH 066/716] this works! --- src/DataWrangling/ECCO2.jl | 115 ++++++++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 27 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 0e9f7257..08b76af6 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -78,53 +78,78 @@ function construct_vertical_interfaces(ds, depth_name) return zf end -function ecco2_field(variable_name; - architecture = CPU(), - horizontal_halo = (1, 1), - url = ecco2_urls[variable_name], - filename = ecco2_file_names[variable_name], - short_name = ecco2_short_names[variable_name]) - - isfile(filename) || download(url, filename) - - ds = Dataset(filename) +function empty_ecco2_field(variable_name; architecture = CPU(), horizontal_halo = (1, 1)) + location = ecco2_location[variable_name] longitude = (0, 360) latitude = (-90, 90) TX, TY = (Periodic, Bounded) + filename = ecco2_file_names[variable_name] + + ds = Dataset(filename) + if variable_is_three_dimensional[variable_name] - data = ds[short_name][:, :, :, 1] depth_name = ecco2_depth_names[variable_name] - - # The surface layer in three-dimensional ECCO fields is at `k = 1` - data = reverse(data, dims = 3) - z = construct_vertical_interfaces(ds, depth_name) - N = size(data) - # add vertical halo for 3D fields halo = (horizontal_halo..., 1) - LZ = Center TZ = Bounded + N = (1440, 720, 50) else - data = ds[short_name][:, :, 1] - N = size(data) z = nothing halo = horizontal_halo LZ = Nothing TZ = Flat + N = (1440, 720) end - close(ds) - # Flat in z if the variable is two-dimensional grid = LatitudeLongitudeGrid(architecture; halo, size = N, topology = (TX, TY, TZ), longitude, latitude, z) - FT = eltype(grid) - field = Field{Center, Center, LZ}(grid) + return Field{location...}(grid) +end + +""" + ecco2_field(variable_name; + architecture = CPU(), + horizontal_halo = (1, 1), + user_data = nothing, + url = ecco2_urls[variable_name], + filename = ecco2_file_names[variable_name], + short_name = ecco2_short_names[variable_name]) + +Retrieve the ecco2 field corresponding the `variable_name`, stored in +`filename` or dowloaded from `url` +""" +function ecco2_field(variable_name; + architecture = CPU(), + horizontal_halo = (1, 1), + user_data = nothing, + url = ecco2_urls[variable_name], + filename = ecco2_file_names[variable_name], + short_name = ecco2_short_names[variable_name]) + + isfile(filename) || download(url, filename) + + if user_data isa Nothing + ds = Dataset(filename) + + if variable_is_three_dimensional[variable_name] + data = ds[short_name][:, :, :, 1] + # The surface layer in three-dimensional ECCO fields is at `k = 1` + data = reverse(data, dims = 3) + else + data = ds[short_name][:, :, 1] + end + else + data = user_data + end + + field = empty_ecco2_field(variable_name; architecture, horizontal_halo) + FT = eltype(field) data = convert.(FT, data) set!(field, data) @@ -138,6 +163,12 @@ end @inbounds mask[i, j, k] = ifelse(Tᵢ[i, j, k] < minimum_value, 0, 1) end +""" + ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) + +An integer field where 0 represents a missing value in the ECCO2 :temperature +dataset and 1 represents a valid value +""" function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) Tᵢ = ecco2_field(:temperature; architecture) mask = CenterField(Tᵢ.grid) @@ -148,6 +179,34 @@ function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) return mask end +""" + adjusted_ecco_field(variable_name; + architecture = CPU(), + filename = "./data/initial_ecco_tracers.nc", + overwrite_existing = false, + mask = ecco2_center_mask(architecture)) + +Retrieve the ECCO2 field corresponding to `variable_name` adjusted to fill all the +missing values in the original dataset + +Arguments: +========== + +- `variable_name`: the variable name corresponding to the Dataset + +Keyword Arguments: +================== + +- `architecture`: either `CPU()` or `GPU()` + +- `filename`: the path where to retrieve the data from. If the file does not exist, + the data will be retrived from the ECCO2 dataset, it will be adjusted and + saved down in `filename` + +- `overwrite_existing`: If true, even if data exists in `filename`, the file will we overwritten + +- `mask`: the mask used to extend the field (see `adjust_tracer!`) +""" function adjusted_ecco_field(variable_name; architecture = CPU(), overwrite_existing = false, @@ -165,10 +224,11 @@ function adjusted_ecco_field(variable_name; close(ds) else - ds = Dataset(filename) + ds = Dataset(filename, "a") if haskey(ds, string(variable_name)) - f = ds[variable_name][:, :, :] + data = ds[variable_name][:, :, :] + f = ecco2_field(variable_name; architecture, user_data = data) else f = ecco2_field(variable_name; architecture) # Make sure all values are extended properly @@ -219,7 +279,8 @@ function initialize!(model; filename, mask) - f_grid = Field(ecco2_location[variable_name], grid) + f_grid = Field(ecco2_location[variable_name], grid) + three_dimensional_regrid!(f_grid, f) set!(model; fldname => f_grid) From c3d145be7ec6e1786f94dc7cc6c5f8afaea064f6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:02:30 -0500 Subject: [PATCH 067/716] fine --- src/DataWrangling/ECCO2.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 08b76af6..731fd944 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -210,7 +210,7 @@ Keyword Arguments: function adjusted_ecco_field(variable_name; architecture = CPU(), overwrite_existing = false, - filename = "./data/initial_ecco_tracers.nc", + filename = "./data/adjusted_ecco_tracers.nc", mask = ecco2_center_mask(architecture)) if overwrite_existing || !isfile(filename) @@ -245,7 +245,7 @@ end function initialize!(model; overwrite_existing = false, - filename = "./data/initial_ecco_tracers.nc", + filename = "./data/adjusted_ecco_tracers.nc", kwargs...) grid = model.grid From 0a04d6a4dd1c1b4701ce20e36536e01b79366401 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:17:03 -0500 Subject: [PATCH 068/716] some comments --- examples/freely_decaying_mediterranean.jl | 4 ++-- src/Bathymetry.jl | 3 ++- src/DataWrangling/ECCO2.jl | 13 +++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 66d7b063..6dc915c4 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -64,7 +64,7 @@ heatmap!(ax, interior(model.tracers.T, :, :, Nz), colorrange = (10, 20), colorma ax = Axis(fig[1, 2]) heatmap!(ax, interior(model.tracers.S, :, :, Nz), colorrange = (35, 40), colormap = :haline) -simulation = Simulation(model, Δt = 20, stop_iteration = 100) +simulation = Simulation(model, Δt = 20, stop_iteration = 100, stop_time = 10*365days) function progress(sim) u, v, w = sim.model.velocities @@ -83,7 +83,7 @@ simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) # warm up for 100 iterations! run!(simulation) -simulation.stop_time = 10*365days +simulation.stop_iteration = Inf wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 10minutes, max_change = 1.1) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index ca1d35d4..42ec632a 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -187,7 +187,8 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) new_size = (Nλ[pass], Nφ[pass], 1) @debug "pass number $pass with size $new_size" - new_grid = LatitudeLongitudeGrid(size = new_size, + new_grid = LatitudeLongitudeGrid(architecture(target_grid), + size = new_size, latitude = (latitude[1], latitude[2]), longitude = (longitude[1], longitude[2]), z = (0, 1), diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 731fd944..0dedfe42 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -243,6 +243,19 @@ function adjusted_ecco_field(variable_name; return f end +""" + initialize!(model; + overwrite_existing = false, + filename = "./data/adjusted_ecco_tracers.nc", + kwargs...) + +Initialize `model`. The keyword arguments `kwargs...` take the form `name=data`, +where `name` refers to one of the fields of `model.velocities` or `model.tracers`, +and the `data` may be + (1) an array + (2) a function with arguments `(x, y, z)` for 3D fields, `(x, y)` for 2D fields and `(x)` for 1D fields + (3) a symbol corresponding to a fldname of `ecco2_tracer_fields` +""" function initialize!(model; overwrite_existing = false, filename = "./data/adjusted_ecco_tracers.nc", From 7caf63553fe0299a7e3d79cd988b264b93f92874 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:38:15 -0500 Subject: [PATCH 069/716] some changes --- examples/freely_decaying_mediterranean.jl | 48 ++++++++++++++++------- src/DataWrangling/ECCO2.jl | 23 ++++++----- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 6dc915c4..4ffa57ff 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -12,39 +12,56 @@ using Printf ##### Regional Mediterranean grid ##### +# Domain and Grid size +# +# We construct a grid that represents the Mediterranean sea, +# with a resolution of 1/10th of a degree (roughly 10 km resolution) +λ₁, λ₂ = ( 0, 42) # domain in longitude +φ₂, φ₂ = (30, 45) # domain in latitude # A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters -z = stretched_vertical_faces(depth = 5000, +z_face = stretched_vertical_faces(depth = 5000, surface_layer_Δz = 2.5, stretching = PowerLawStretching(1.070), surface_layer_height = 50) -Nx = 4 * 42 # 1 / 4th of a degree -Ny = 4 * 15 # 1 / 4th of a degree +Nx = 4 * 42 # 1 / 4th of a degree resolution +Ny = 4 * 15 # 1 / 4th of a degree resolution Nz = length(z) - 1 -@info "grid size: ($Nx, $Ny, $Nz)" - grid = LatitudeLongitudeGrid(CPU(); size = (Nx, Ny, Nz), - latitude = (30, 45), - longitude = (0, 42), - z, + latitude = (φ₁, φ₂), + longitude = (λ₁, λ₂), + z = z_face, halo = (7, 7, 7)) -h = regrid_bathymetry(grid, height_above_water=1) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(h)) +# Interpolating the bathymetry onto the grid +# +# We regrid the bathymetry onto the grid we constructed. +# we allow a minimum depth of 10 meters (all shallower regions are +# considered land) and we use 5 intermediate grids (interpolation_passes = 5) +# Note that more interpolation passes will smooth the bathymetry +heigth = regrid_bathymetry(grid, + height_above_water = 1, + minimum_depth = 10, + interpolation_passes = 5) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(height)) # Correct oceananigans import Oceananigans.Advection: nothing_to_default nothing_to_default(user_value; default) = isnothing(user_value) ? default : user_value -# Construct the model and run it +# Constructing the model +# +# We construct the model with three tracers, temperature (:T), salinity (:S) and TKE (:e). +# The latter is used as a prognostic variable for the micro-scale turbulence closure: `CATKEVerticalDiffusivity` +# We select a linear equation of state for buoyancy calculation, and WENO schemes for both tracer and momentum advection. +# The free surface utilizes a split-explicit formulation with a barotropic CFL of 0.75 based on wave speed. model = HydrostaticFreeSurfaceModel(; grid, - momentum_advection = WENOVectorInvariant(), - tracer_advection = WENO(grid; order = 7), - free_surface = SplitExplicitFreeSurface(; cfl = 0.75, grid), + momentum_advection = WENOVectorInvariant(), + tracer_advection = WENO(grid; order = 7), + free_surface = SplitExplicitFreeSurface(; cfl = 0.75, grid), closure = CATKEVerticalDiffusivity(), buoyancy = SeawaterBuoyancy(), tracers = (:T, :S, :e), @@ -56,6 +73,7 @@ model = HydrostaticFreeSurfaceModel(; grid, # In this case, our ECCO2 dataset has access to a temperature and a salinity # field, so we initialize T and S from ECCO2. We initialize TKE (:e) with a # constant value of 1e-6 m²/s² throughout the domain +@info "initializing model from ECCO2 fields" initialize!(model, T = :ecco2_temperature, S = :ecco2_salinity, e = 1e-6) fig = Figure() diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 0dedfe42..dad03a8a 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -181,10 +181,9 @@ end """ adjusted_ecco_field(variable_name; - architecture = CPU(), - filename = "./data/initial_ecco_tracers.nc", - overwrite_existing = false, - mask = ecco2_center_mask(architecture)) + architecture = CPU(), + filename = "./data/initial_ecco_tracers.nc", + mask = ecco2_center_mask(architecture)) Retrieve the ECCO2 field corresponding to `variable_name` adjusted to fill all the missing values in the original dataset @@ -203,24 +202,22 @@ Keyword Arguments: the data will be retrived from the ECCO2 dataset, it will be adjusted and saved down in `filename` -- `overwrite_existing`: If true, even if data exists in `filename`, the file will we overwritten - - `mask`: the mask used to extend the field (see `adjust_tracer!`) """ function adjusted_ecco_field(variable_name; architecture = CPU(), - overwrite_existing = false, filename = "./data/adjusted_ecco_tracers.nc", mask = ecco2_center_mask(architecture)) - if overwrite_existing || !isfile(filename) + if !isfile(filename) f = ecco2_field(variable_name; architecture) # Make sure all values are extended properly + @info "in-painting ecco field $variable_name and saving it in $filename" adjust_tracer!(f; mask) ds = Dataset(filename, "c") - defVar(ds, string(variable_name), f, ("lat", "lon", "z")) + defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) close(ds) else @@ -232,9 +229,10 @@ function adjusted_ecco_field(variable_name; else f = ecco2_field(variable_name; architecture) # Make sure all values are extended properly + @info "in-painting ecco field $variable_name and saving it in $filename" adjust_tracer!(f; mask) - defVar(ds, string(variable_name), f, ("lat", "lon", "z")) + defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) end close(ds) @@ -245,7 +243,6 @@ end """ initialize!(model; - overwrite_existing = false, filename = "./data/adjusted_ecco_tracers.nc", kwargs...) @@ -255,9 +252,11 @@ and the `data` may be (1) an array (2) a function with arguments `(x, y, z)` for 3D fields, `(x, y)` for 2D fields and `(x)` for 1D fields (3) a symbol corresponding to a fldname of `ecco2_tracer_fields` + +The keyword argument `filename` is the path to a netcdf file containing the adjusted ecco fields. +If the file does not exist it will be created """ function initialize!(model; - overwrite_existing = false, filename = "./data/adjusted_ecco_tracers.nc", kwargs...) From a611a27dec1f394f056787f9dbe375f09492cdd2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:47:57 -0500 Subject: [PATCH 070/716] some comments --- src/DataWrangling/ECCO2.jl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index dad03a8a..57aa342d 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -113,16 +113,17 @@ function empty_ecco2_field(variable_name; architecture = CPU(), horizontal_halo end """ - ecco2_field(variable_name; - architecture = CPU(), - horizontal_halo = (1, 1), - user_data = nothing, - url = ecco2_urls[variable_name], - filename = ecco2_file_names[variable_name], - short_name = ecco2_short_names[variable_name]) + ecco2_field(variable_name; + architecture = CPU(), + horizontal_halo = (1, 1), + user_data = nothing, + url = ecco2_urls[variable_name], + filename = ecco2_file_names[variable_name], + short_name = ecco2_short_names[variable_name]) Retrieve the ecco2 field corresponding the `variable_name`, stored in -`filename` or dowloaded from `url` +`filename` or dowloaded from `url`. If `user_data` is provided, the +field is set with `user_data` """ function ecco2_field(variable_name; architecture = CPU(), @@ -287,7 +288,6 @@ function initialize!(model; for (fldname, variable_name) in ecco2_fields f = adjusted_ecco_field(variable_name; architecture = arch, - overwrite_existing, filename, mask) From 0f9ec228124bd010d3d0b414570b24dcbe945571 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:49:23 -0500 Subject: [PATCH 071/716] comment --- src/DataWrangling/ECCO2.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 57aa342d..7da60577 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -121,9 +121,10 @@ end filename = ecco2_file_names[variable_name], short_name = ecco2_short_names[variable_name]) -Retrieve the ecco2 field corresponding the `variable_name`, stored in -`filename` or dowloaded from `url`. If `user_data` is provided, the -field is set with `user_data` +Retrieve the ecco2 field corresponding to `variable_name`. The data is either: +(1) retrieved from `filename` +(2) dowloaded from `url` if `filename` does not exists +(3) filled from `user_data` if `user_data` is provided """ function ecco2_field(variable_name; architecture = CPU(), From aae87fd04ae3823a849ca37a2f3145c422fc5f08 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:52:32 -0500 Subject: [PATCH 072/716] bugfix --- examples/freely_decaying_mediterranean.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 4ffa57ff..05f7d44e 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -17,7 +17,7 @@ using Printf # We construct a grid that represents the Mediterranean sea, # with a resolution of 1/10th of a degree (roughly 10 km resolution) λ₁, λ₂ = ( 0, 42) # domain in longitude -φ₂, φ₂ = (30, 45) # domain in latitude +φ₁, φ₂ = (30, 45) # domain in latitude # A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters z_face = stretched_vertical_faces(depth = 5000, surface_layer_Δz = 2.5, From 90ec6f859d6c6b91cbe62112879b354bb1a92c54 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:16:01 -0500 Subject: [PATCH 073/716] more restructuring --- examples/freely_decaying_mediterranean.jl | 10 +- src/ClimaOcean.jl | 4 +- src/DataWrangling/DataWrangling.jl | 1 + src/DataWrangling/ECCO2.jl | 66 +---------- src/DataWrangling/fill_missing_values.jl | 100 +++++++++++++++++ .../InitialConditions.jl | 105 +----------------- src/InitialConditions/initialize_model.jl | 72 ++++++++++++ 7 files changed, 187 insertions(+), 171 deletions(-) create mode 100644 src/DataWrangling/fill_missing_values.jl rename src/{ => InitialConditions}/InitialConditions.jl (65%) create mode 100644 src/InitialConditions/initialize_model.jl diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 05f7d44e..5cdafd45 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -41,11 +41,11 @@ grid = LatitudeLongitudeGrid(CPU(); # we allow a minimum depth of 10 meters (all shallower regions are # considered land) and we use 5 intermediate grids (interpolation_passes = 5) # Note that more interpolation passes will smooth the bathymetry -heigth = regrid_bathymetry(grid, - height_above_water = 1, - minimum_depth = 10, - interpolation_passes = 5) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(height)) +bottom_height = regrid_bathymetry(grid, + height_above_water = 1, + minimum_depth = 10, + interpolation_passes = 5) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) # Correct oceananigans import Oceananigans.Advection: nothing_to_default diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 778b4cf7..bc36b883 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -65,16 +65,16 @@ end @inline v_immersed_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) include("VerticalGrids.jl") -include("InitialConditions.jl") include("DataWrangling/DataWrangling.jl") +include("InitialConditions/InitialConditions.jl") include("Bathymetry.jl") include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") using .VerticalGrids -using .InitialConditions using .Bathymetry using .DataWrangling: JRA55 using .DataWrangling: ECCO2 +using .InitialConditions end # module diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index 10922e92..67c6e4f7 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -108,6 +108,7 @@ function save_field_time_series!(fts; path, name, overwrite_existing=false) return nothing end +include("fill_missing_values.jl") include("JRA55.jl") include("ECCO2.jl") diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 7da60577..22ec0c6d 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -2,7 +2,7 @@ module ECCO2 export ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! -using ClimaOcean.InitialConditions: adjust_tracer!, three_dimensional_regrid! +using ClimaOcean.DataWrangling: fill_missing_values! using Oceananigans using Oceananigans: architecture @@ -216,7 +216,7 @@ function adjusted_ecco_field(variable_name; # Make sure all values are extended properly @info "in-painting ecco field $variable_name and saving it in $filename" - adjust_tracer!(f; mask) + fill_missing_values!(f; mask) ds = Dataset(filename, "c") defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) @@ -232,7 +232,7 @@ function adjusted_ecco_field(variable_name; f = ecco2_field(variable_name; architecture) # Make sure all values are extended properly @info "in-painting ecco field $variable_name and saving it in $filename" - adjust_tracer!(f; mask) + fill_missing_values!(f; mask) defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) end @@ -243,65 +243,5 @@ function adjusted_ecco_field(variable_name; return f end -""" - initialize!(model; - filename = "./data/adjusted_ecco_tracers.nc", - kwargs...) - -Initialize `model`. The keyword arguments `kwargs...` take the form `name=data`, -where `name` refers to one of the fields of `model.velocities` or `model.tracers`, -and the `data` may be - (1) an array - (2) a function with arguments `(x, y, z)` for 3D fields, `(x, y)` for 2D fields and `(x)` for 1D fields - (3) a symbol corresponding to a fldname of `ecco2_tracer_fields` - -The keyword argument `filename` is the path to a netcdf file containing the adjusted ecco fields. -If the file does not exist it will be created -""" -function initialize!(model; - filename = "./data/adjusted_ecco_tracers.nc", - kwargs...) - - grid = model.grid - arch = architecture(grid) - - custom_fields = Dict() - ecco2_fields = Dict() - - # Differentiate between custom initialization and ECCO2 initialization - for (fldname, value) in kwargs - if value ∈ keys(ecco2_tracer_fields) - ecco2_fields[fldname] = ecco2_tracer_fields[value] - else - custom_fields[fldname] = value - end - end - - # Additional tracers not present in the ECCO dataset - if !isempty(custom_fields) - set!(model; custom_fields...) - end - - # Set tracers from ECCO2 - if !isempty(ecco2_fields) - mask = ecco2_center_mask(architecture(grid)) - - for (fldname, variable_name) in ecco2_fields - f = adjusted_ecco_field(variable_name; - architecture = arch, - filename, - mask) - - f_grid = Field(ecco2_location[variable_name], grid) - - three_dimensional_regrid!(f_grid, f) - - set!(model; fldname => f_grid) - end - end - - return nothing -end - end # module diff --git a/src/DataWrangling/fill_missing_values.jl b/src/DataWrangling/fill_missing_values.jl new file mode 100644 index 00000000..7951f90c --- /dev/null +++ b/src/DataWrangling/fill_missing_values.jl @@ -0,0 +1,100 @@ +using Oceananigans +using Oceananigans.BoundaryConditions +using Oceananigans.Fields: OneField +using Oceananigans.Grids: peripheral_node +using Oceananigans.Utils: launch! +using Oceananigans.Fields: instantiated_location, interior, CenterField +using Oceananigans.Architectures: architecture, device, GPU + +using KernelAbstractions: @kernel, @index +using KernelAbstractions.Extras.LoopInfo: @unroll + +# Maybe we can remove this propagate field in lieu of a diffusion, +# Still we'll need to do this a couple of steps on the original grid +@kernel function _propagate_field!(field, tmp_field) + i, j, k = @index(Global, NTuple) + + @inbounds begin + nw = field[i - 1, j, k] + ns = field[i, j - 1, k] + ne = field[i + 1, j, k] + nn = field[i, j + 1, k] + nb = (nw, ne, nn, ns) + + counter = 0 + cumsum = 0.0 + + @unroll for n in nb + counter += ifelse(isnan(n), 0, 1) + cumsum += ifelse(isnan(n), 0, n) + end + + tmp_field[i, j, k] = ifelse(cumsum == 0, NaN, cumsum / counter) + end +end + +@kernel function _substitute_values!(field, tmp_field) + i, j, k = @index(Global, NTuple) + @inbounds substitute = isnan(field[i, j, k]) + @inbounds field[i, j, k] = ifelse(substitute, tmp_field[i, j, k], field[i, j, k]) +end + +@kernel function _nans_outside_mask!(field, mask) + i, j, k = @index(Global, NTuple) + @inbounds field[i, j, k] = ifelse(mask[i, j, k] == 0, NaN, field[i, j, k]) +end + +propagate_horizontally!(field, ::Nothing; kw...) = nothing + +""" + propagate_horizontally!(field, mask; max_iter = Inf) + +propagate horizontally +""" +function propagate_horizontally!(field, mask; max_iter = Inf) + iter = 0 + grid = field.grid + arch = architecture(grid) + + launch!(arch, grid, :xyz, _nans_outside_mask!, field, mask) + fill_halo_regions!(field) + + tmp_field = deepcopy(field) + + while isnan(sum(interior(field))) && iter < max_iter + launch!(arch, grid, :xyz, _propagate_field!, field, tmp_field) + launch!(arch, grid, :xyz, _substitute_values!, field, tmp_field) + iter += 1 + @debug "propagate pass $iter with sum $(sum(parent(field)))" + end + + return nothing +end + +continue_downwards!(field, ::Nothing) = nothing + +function continue_downwards!(field, mask) + arch = architecture(field) + grid = field.grid + launch!(arch, grid, :xy, _continue_downwards!, field, grid, mask) + return nothing +end + +@kernel function _continue_downwards!(field, grid, mask) + i, j = @index(Global, NTuple) + + Nz = grid.Nz + + @unroll for k = Nz-1 : -1 : 1 + @inbounds fill_from_above = mask[i, j, k] == 0 + @inbounds field[i, j, k] = ifelse(fill_from_above, field[i, j, k+1], field[i, j, k]) + end +end + +function fill_missing_values!(tracer; mask = nothing, max_iter = Inf) + + continue_downwards!(tracer, mask) + propagate_horizontally!(tracer, mask; max_iter) + + return tracer +end \ No newline at end of file diff --git a/src/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl similarity index 65% rename from src/InitialConditions.jl rename to src/InitialConditions/InitialConditions.jl index 46872a3e..9fe6472d 100644 --- a/src/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -12,88 +12,7 @@ using Oceananigans.Architectures: architecture, device, GPU using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll - -# Maybe we can remove this propagate field in lieu of a diffusion, -# Still we'll need to do this a couple of steps on the original grid -@kernel function _propagate_field!(field, tmp_field) - i, j, k = @index(Global, NTuple) - - @inbounds begin - nw = field[i - 1, j, k] - ns = field[i, j - 1, k] - ne = field[i + 1, j, k] - nn = field[i, j + 1, k] - nb = (nw, ne, nn, ns) - - counter = 0 - cumsum = 0.0 - - @unroll for n in nb - counter += ifelse(isnan(n), 0, 1) - cumsum += ifelse(isnan(n), 0, n) - end - - tmp_field[i, j, k] = ifelse(cumsum == 0, NaN, cumsum / counter) - end -end - -@kernel function _substitute_values!(field, tmp_field) - i, j, k = @index(Global, NTuple) - @inbounds substitute = isnan(field[i, j, k]) - @inbounds field[i, j, k] = ifelse(substitute, tmp_field[i, j, k], field[i, j, k]) -end - -@kernel function _nans_outside_mask!(field, mask) - i, j, k = @index(Global, NTuple) - @inbounds field[i, j, k] = ifelse(mask[i, j, k] == 0, NaN, field[i, j, k]) -end - -propagate_horizontally!(field, ::Nothing; kw...) = nothing - -""" - propagate_horizontally!(field, mask; max_iter = Inf) - -propagate horizontally -""" -function propagate_horizontally!(field, mask; max_iter = Inf) - iter = 0 - grid = field.grid - arch = architecture(grid) - - launch!(arch, grid, :xyz, _nans_outside_mask!, field, mask) - fill_halo_regions!(field) - - tmp_field = deepcopy(field) - - while isnan(sum(interior(field))) && iter < max_iter - launch!(arch, grid, :xyz, _propagate_field!, field, tmp_field) - launch!(arch, grid, :xyz, _substitute_values!, field, tmp_field) - iter += 1 - @debug "propagate pass $iter with sum $(sum(parent(field)))" - end - - return nothing -end - -continue_downwards!(field, ::Nothing) = nothing - -function continue_downwards!(field, mask) - arch = architecture(field) - grid = field.grid - launch!(arch, grid, :xy, _continue_downwards!, field, grid, mask) - return nothing -end - -@kernel function _continue_downwards!(field, grid, mask) - i, j = @index(Global, NTuple) - - Nz = grid.Nz - - @unroll for k = Nz-1 : -1 : 1 - @inbounds fill_from_above = mask[i, j, k] == 0 - @inbounds field[i, j, k] = ifelse(fill_from_above, field[i, j, k+1], field[i, j, k]) - end -end +using JLD2 scale_to_diffusivity(vertical_scale) = vertical_scale^2 scale_to_diffusivity(vertical_scale::Function) = (x, y, z, t) -> vertical_scale(x, y, z, t)^2 @@ -108,24 +27,6 @@ end @inbounds tracer[i, j, k] = ifelse(mask(i, j, k, grid) == 1, initial_tracer[i, j, k], tracer[i, j, k]) end -function adjust_tracer!(tracers::NamedTuple; mask = nothing, max_iter = Inf) - - for (name, tracer) in zip(keys(tracers), tracers) - @info "extending tracer $name" - adjust_tracer!(tracer; mask, max_iter) - end - - return tracers -end - -function adjust_tracer!(tracer; mask = nothing, max_iter = Inf) - - continue_downwards!(tracer, mask) - propagate_horizontally!(tracer, mask; max_iter) - - return tracer -end - @inline not_an_immersed_cell(i, j, k, grid) = !immersed_cell(i, j, k, grid) function diffuse_tracers(initial_tracers; @@ -193,7 +94,7 @@ function diffuse_tracers(initial_tracers; return smoothing_model.tracers end -# TODO: move all the folowing to Oceananigans! +# TODO: move all the following to Oceananigans! using Oceananigans.Fields: regrid! using Oceananigans.Grids: cpu_face_constructor_x, @@ -243,5 +144,7 @@ function three_dimensional_regrid!(a, b) regrid!(a, target_grid, ygrid, field_y) end +include("initialize_model.jl") + end # module diff --git a/src/InitialConditions/initialize_model.jl b/src/InitialConditions/initialize_model.jl new file mode 100644 index 00000000..db4dda80 --- /dev/null +++ b/src/InitialConditions/initialize_model.jl @@ -0,0 +1,72 @@ +using ClimaOcean.ECCO2: ecco2_tracer_fields, adjusted_ecco_field, ecco2_location + +""" + initialize!(model; + filename = "./data/adjusted_ecco_tracers.nc", + kwargs...) + +Initialize `model`. The keyword arguments `kwargs...` take the form `name=data`, +where `name` refers to one of the fields of `model.velocities` or `model.tracers`, +and the `data` may be + (1) an array + (2) a function with arguments `(x, y, z)` for 3D fields, `(x, y)` for 2D fields and `(x)` for 1D fields + (3) a symbol corresponding to a fldname of `ecco2_tracer_fields` + (4) a checkpoint path containing the checkpointed field +The keyword argument `filename` is the path to a netcdf file containing the adjusted ecco fields. +If the file does not exist it will be created +""" +function initialize!(model; + filename = "./data/adjusted_ecco_tracers.nc", + kwargs...) + + grid = model.grid + arch = architecture(grid) + + custom_fields = Dict() + ecco2_fields = Dict() + checkpoint_fields = Dict() + + # Differentiate between custom initialization and ECCO2 initialization + for (fldname, value) in kwargs + if value ∈ keys(ecco2_tracer_fields) + ecco2_fields[fldname] = ecco2_tracer_fields[value] + elseif value isa String + checkpoint_fields[fldname] = value + else + custom_fields[fldname] = value + end + end + + # Custom fields not present in the ECCO dataset + if !isempty(custom_fields) + set!(model; custom_fields...) + end + + # Fields initialized from checkpointer + if isempty!(checkpoint_fields) + for (fldname, path) in checkpoint_fields + data = jldopen(path)[string(fldname) * "/data"] + set!(model, fldname => data) + end + end + + # Fields initialized from ECCO2 + if !isempty(ecco2_fields) + mask = ecco2_center_mask(architecture(grid)) + + for (fldname, variable_name) in ecco2_fields + f = adjusted_ecco_field(variable_name; + architecture = arch, + filename, + mask) + + f_grid = Field(ecco2_location[variable_name], grid) + + three_dimensional_regrid!(f_grid, f) + + set!(model; fldname => f_grid) + end + end + + return nothing +end From 7a81f63cbc2ff33d3d3ddea70ed714a04c374c0b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:38:20 -0500 Subject: [PATCH 074/716] more cleanup --- examples/freely_decaying_mediterranean.jl | 59 +++++--- examples/generate_bathymetry.jl | 2 +- .../run_neverworld_simulation.jl | 141 ------------------ .../run_neverworld_simulation.jl | 135 ----------------- src/ClimaOcean.jl | 1 + src/InitialConditions/InitialConditions.jl | 2 +- src/InitialConditions/initialize_model.jl | 5 +- 7 files changed, 43 insertions(+), 302 deletions(-) delete mode 100644 experiments/catke_partial_cells/run_neverworld_simulation.jl delete mode 100644 experiments/ri_based_partial_cells/run_neverworld_simulation.jl diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 5cdafd45..99a16913 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -16,36 +16,38 @@ using Printf # # We construct a grid that represents the Mediterranean sea, # with a resolution of 1/10th of a degree (roughly 10 km resolution) -λ₁, λ₂ = ( 0, 42) # domain in longitude -φ₁, φ₂ = (30, 45) # domain in latitude +λ₁, λ₂ = ( 0, 42) # domain in longitude +φ₁, φ₂ = (30, 45) # domain in latitude # A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters -z_face = stretched_vertical_faces(depth = 5000, +z_faces = stretched_vertical_faces(depth = 5000, surface_layer_Δz = 2.5, stretching = PowerLawStretching(1.070), surface_layer_height = 50) -Nx = 4 * 42 # 1 / 4th of a degree resolution -Ny = 4 * 15 # 1 / 4th of a degree resolution -Nz = length(z) - 1 +Nx = 15 * 42 # 1 / 15th of a degree resolution +Ny = 15 * 15 # 1 / 15th of a degree resolution +Nz = length(z_faces) - 1 grid = LatitudeLongitudeGrid(CPU(); size = (Nx, Ny, Nz), latitude = (φ₁, φ₂), longitude = (λ₁, λ₂), - z = z_face, + z = z_faces, halo = (7, 7, 7)) # Interpolating the bathymetry onto the grid # -# We regrid the bathymetry onto the grid we constructed. +# We regrid the bathymetry onto the grid. # we allow a minimum depth of 10 meters (all shallower regions are -# considered land) and we use 5 intermediate grids (interpolation_passes = 5) +# considered land) and we use 25 intermediate grids (interpolation_passes = 25) # Note that more interpolation passes will smooth the bathymetry bottom_height = regrid_bathymetry(grid, height_above_water = 1, minimum_depth = 10, - interpolation_passes = 5) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + interpolation_passes = 25) + +# Let's use an active cell map to elide computation in inactive cells +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) # Correct oceananigans import Oceananigans.Advection: nothing_to_default @@ -54,27 +56,25 @@ nothing_to_default(user_value; default) = isnothing(user_value) ? default : user # Constructing the model # -# We construct the model with three tracers, temperature (:T), salinity (:S) and TKE (:e). -# The latter is used as a prognostic variable for the micro-scale turbulence closure: `CATKEVerticalDiffusivity` +# We construct the model with three tracers, temperature (:T), salinity (:S) +# We do not have convection since the simulation is just slumping to equilibrium so we do not need a turbulence closure # We select a linear equation of state for buoyancy calculation, and WENO schemes for both tracer and momentum advection. # The free surface utilizes a split-explicit formulation with a barotropic CFL of 0.75 based on wave speed. model = HydrostaticFreeSurfaceModel(; grid, momentum_advection = WENOVectorInvariant(), tracer_advection = WENO(grid; order = 7), free_surface = SplitExplicitFreeSurface(; cfl = 0.75, grid), - closure = CATKEVerticalDiffusivity(), buoyancy = SeawaterBuoyancy(), - tracers = (:T, :S, :e), + tracers = (:T, :S), coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) # Initializing the model # # the model can be initialized with custom values or with ecco2 fields. # In this case, our ECCO2 dataset has access to a temperature and a salinity -# field, so we initialize T and S from ECCO2. We initialize TKE (:e) with a -# constant value of 1e-6 m²/s² throughout the domain +# field, so we initialize T and S from ECCO2. @info "initializing model from ECCO2 fields" -initialize!(model, T = :ecco2_temperature, S = :ecco2_salinity, e = 1e-6) +initialize!(model, T = :ecco2_temperature, S = :ecco2_salinity) fig = Figure() ax = Axis(fig[1, 1]) @@ -82,7 +82,7 @@ heatmap!(ax, interior(model.tracers.T, :, :, Nz), colorrange = (10, 20), colorma ax = Axis(fig[1, 2]) heatmap!(ax, interior(model.tracers.S, :, :, Nz), colorrange = (35, 40), colormap = :haline) -simulation = Simulation(model, Δt = 20, stop_iteration = 100, stop_time = 10*365days) +simulation = Simulation(model, Δt = 10minutes, stop_time = 10*365days) function progress(sim) u, v, w = sim.model.velocities @@ -98,15 +98,28 @@ end simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) -# warm up for 100 iterations! +# Simulation warm up! +# +# We have regridded from a coarse solution (1/4er of a degree) to a +# fine grid (1/15th of a degree). Also, the bathymetry has little mismatches +# that might crash our simulation. We warm up the simulation with a little +# time step for few iterations to allow the solution to adjust to the new_grid +# bathymetry +simulation.Δt = 10 +simulation.stop_iteration = 1000 run!(simulation) -simulation.stop_iteration = Inf - +# Run the real simulation +# +# Now that the solution has adjusted to the bathymetry we can ramp up the time +# step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.2 wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 10minutes, max_change = 1.1) simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +# Let's reset the maximum number of iterations +simulation.stop_iteration = Inf + simulation.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); indices = (:, :, Nz), schedule = TimeInterval(1day), @@ -117,3 +130,5 @@ run!(simulation) + + diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index e52d80ac..78d83b01 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -46,7 +46,7 @@ grid = LatitudeLongitudeGrid(CPU(); z = (0, 1), halo = (4, 4, 4)) -h_smooth = regrid_bathymetry(grid, height_above_water=1, interpolation_passes = 10) +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_smooth) 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/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) - diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index bc36b883..fc66dc95 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -5,6 +5,7 @@ export stretched_vertical_faces export PowerLawStretching, LinearStretching export jra55_field_time_series export ecco2_field +export initialize! using Oceananigans using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 9fe6472d..aab65e19 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -1,6 +1,6 @@ module InitialConditions -export continue_downwards! +export initialize! using Oceananigans using Oceananigans.BoundaryConditions diff --git a/src/InitialConditions/initialize_model.jl b/src/InitialConditions/initialize_model.jl index db4dda80..a618b6cf 100644 --- a/src/InitialConditions/initialize_model.jl +++ b/src/InitialConditions/initialize_model.jl @@ -1,4 +1,5 @@ -using ClimaOcean.ECCO2: ecco2_tracer_fields, adjusted_ecco_field, ecco2_location +using ClimaOcean.DataWrangling.ECCO2: ecco2_tracer_fields, adjusted_ecco_field, ecco2_location +using ClimaOcean.DataWrangling.ECCO2: ecco2_center_mask """ initialize!(model; @@ -10,7 +11,7 @@ where `name` refers to one of the fields of `model.velocities` or `model.tracers and the `data` may be (1) an array (2) a function with arguments `(x, y, z)` for 3D fields, `(x, y)` for 2D fields and `(x)` for 1D fields - (3) a symbol corresponding to a fldname of `ecco2_tracer_fields` + (3) a symbol corresponding to a fldname contained in `ecco2_tracer_fields` (4) a checkpoint path containing the checkpointed field The keyword argument `filename` is the path to a netcdf file containing the adjusted ecco fields. If the file does not exist it will be created From 84ae45dbea01e350f385e91e5aee8bbc24686955 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:43:24 -0500 Subject: [PATCH 075/716] small bugfix --- src/InitialConditions/initialize_model.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/InitialConditions/initialize_model.jl b/src/InitialConditions/initialize_model.jl index a618b6cf..74e7b0cb 100644 --- a/src/InitialConditions/initialize_model.jl +++ b/src/InitialConditions/initialize_model.jl @@ -44,7 +44,7 @@ function initialize!(model; end # Fields initialized from checkpointer - if isempty!(checkpoint_fields) + if !isempty(checkpoint_fields) for (fldname, path) in checkpoint_fields data = jldopen(path)[string(fldname) * "/data"] set!(model, fldname => data) From 1923c2d3805a47904a6c885d825c07c94ae25bd0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:45:25 -0500 Subject: [PATCH 076/716] organize a bit --- src/InitialConditions/InitialConditions.jl | 81 +--------------------- src/InitialConditions/diffuse_tracers.jl | 80 +++++++++++++++++++++ 2 files changed, 81 insertions(+), 80 deletions(-) create mode 100644 src/InitialConditions/diffuse_tracers.jl diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index aab65e19..22a92b87 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -14,86 +14,6 @@ using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll using JLD2 -scale_to_diffusivity(vertical_scale) = vertical_scale^2 -scale_to_diffusivity(vertical_scale::Function) = (x, y, z, t) -> vertical_scale(x, y, z, t)^2 - -@kernel function _apply_tracer_mask!(tracer, initial_tracer, mask::AbstractArray) - i, j, k = @index(Global, NTuple) - @inbounds tracer[i, j, k] = ifelse(mask[i, j, k] == 1, initial_tracer[i, j, k], tracer[i, j, k]) -end - -@kernel function _apply_tracer_mask!(tracer, initial_tracer, mask::Function) - i, j, k = @index(Global, NTuple) - @inbounds tracer[i, j, k] = ifelse(mask(i, j, k, grid) == 1, initial_tracer[i, j, k], tracer[i, j, k]) -end - -@inline not_an_immersed_cell(i, j, k, grid) = !immersed_cell(i, j, k, grid) - -function diffuse_tracers(initial_tracers; - horizontal_scale = 0, - vertical_scale = 0, - fractional_time_step = 2e-2, - mask = not_an_immersed_cell) - - # Remake the grid - grid = initial_tracers[1].grid - - # Remake tracers without boundary conditions - tracers = NamedTuple(name => CenterField(grid) for name in keys(initial_tracers)) - - # Horizontal diffusivities that mix up to t ∼ ℓ² / κ ∼ 1 - κh = horizontal_scale^2 - κz = scale_to_diffusivity(vertical_scale) - - # Determine stable time-step - Nx, Ny, Nz = size(grid) - ϵ = fractional_time_step - Az = minimum(grid.Azᶜᶜᵃ[1:Ny]) - - if κh == 0 - Δt = fractional_time_step - else - Δt = ϵ * Az / κh - end - @show Nt = ceil(Int, 1 / Δt) - - vitd = VerticallyImplicitTimeDiscretization() - vertical_smoothing = VerticalScalarDiffusivity(vitd, κ=κz) - horizontal_smoothing = HorizontalScalarDiffusivity(κ=κh) - - smoothing_model = HydrostaticFreeSurfaceModel(; grid, tracers, - velocities = PrescribedVelocityFields(), - momentum_advection = nothing, - tracer_advection = nothing, - buoyancy = nothing, - closure = (horizontal_smoothing, vertical_smoothing)) - - set!(smoothing_model, (tracer[name] = initial_tracer[name] for name in keys(initial_tracers))...) - - Nt = ceil(Int, 1 / Δt) - @info string("Smoothing tracers ", keys(tracers), " with ", Nt, " time steps") - smoothing_simulation = Simulation(smoothing_model; Δt, stop_time=1) - - # Remove NaN checker - pop!(smoothing_simulation.callbacks, :nan_checker) - - # Restore values to default in the masked region - function restore_values(sim) - grid = sim.model.grid - tracers = sim.model.tracers - for (tracer, initial_tracer) in zip(tracers, initial_tracers) - launch!(architecture(grid), grid, :xyz, _apply_tracer_mask!, tracer, initial_tracer, mask) - end - end - - # Add restoring to initial values - simulation.callbacks[:restoring] = Callback(restore_values, IterationInterval(1)) - - run!(smoothing_simulation) - - return smoothing_model.tracers -end - # TODO: move all the following to Oceananigans! using Oceananigans.Fields: regrid! @@ -144,6 +64,7 @@ function three_dimensional_regrid!(a, b) regrid!(a, target_grid, ygrid, field_y) end +include("diffuse_tracers.jl") include("initialize_model.jl") end # module diff --git a/src/InitialConditions/diffuse_tracers.jl b/src/InitialConditions/diffuse_tracers.jl new file mode 100644 index 00000000..b906ad11 --- /dev/null +++ b/src/InitialConditions/diffuse_tracers.jl @@ -0,0 +1,80 @@ + +scale_to_diffusivity(vertical_scale) = vertical_scale^2 +scale_to_diffusivity(vertical_scale::Function) = (x, y, z, t) -> vertical_scale(x, y, z, t)^2 + +@kernel function _apply_tracer_mask!(tracer, initial_tracer, mask::AbstractArray) + i, j, k = @index(Global, NTuple) + @inbounds tracer[i, j, k] = ifelse(mask[i, j, k] == 1, initial_tracer[i, j, k], tracer[i, j, k]) +end + +@kernel function _apply_tracer_mask!(tracer, initial_tracer, mask::Function) + i, j, k = @index(Global, NTuple) + @inbounds tracer[i, j, k] = ifelse(mask(i, j, k, grid) == 1, initial_tracer[i, j, k], tracer[i, j, k]) +end + +@inline not_an_immersed_cell(i, j, k, grid) = !immersed_cell(i, j, k, grid) + +function diffuse_tracers(initial_tracers; + horizontal_scale = 0, + vertical_scale = 0, + fractional_time_step = 2e-2, + mask = not_an_immersed_cell) + + # Remake the grid + grid = initial_tracers[1].grid + + # Remake tracers without boundary conditions + tracers = NamedTuple(name => CenterField(grid) for name in keys(initial_tracers)) + + # Horizontal diffusivities that mix up to t ∼ ℓ² / κ ∼ 1 + κh = horizontal_scale^2 + κz = scale_to_diffusivity(vertical_scale) + + # Determine stable time-step + Nx, Ny, Nz = size(grid) + ϵ = fractional_time_step + Az = minimum(grid.Azᶜᶜᵃ[1:Ny]) + + if κh == 0 + Δt = fractional_time_step + else + Δt = ϵ * Az / κh + end + @show Nt = ceil(Int, 1 / Δt) + + vitd = VerticallyImplicitTimeDiscretization() + vertical_smoothing = VerticalScalarDiffusivity(vitd, κ=κz) + horizontal_smoothing = HorizontalScalarDiffusivity(κ=κh) + + smoothing_model = HydrostaticFreeSurfaceModel(; grid, tracers, + velocities = PrescribedVelocityFields(), + momentum_advection = nothing, + tracer_advection = nothing, + buoyancy = nothing, + closure = (horizontal_smoothing, vertical_smoothing)) + + set!(smoothing_model, (tracer[name] = initial_tracer[name] for name in keys(initial_tracers))...) + + Nt = ceil(Int, 1 / Δt) + @info string("Smoothing tracers ", keys(tracers), " with ", Nt, " time steps") + smoothing_simulation = Simulation(smoothing_model; Δt, stop_time=1) + + # Remove NaN checker + pop!(smoothing_simulation.callbacks, :nan_checker) + + # Restore values to default in the masked region + function restore_values(sim) + grid = sim.model.grid + tracers = sim.model.tracers + for (tracer, initial_tracer) in zip(tracers, initial_tracers) + launch!(architecture(grid), grid, :xyz, _apply_tracer_mask!, tracer, initial_tracer, mask) + end + end + + # Add restoring to initial values + simulation.callbacks[:restoring] = Callback(restore_values, IterationInterval(1)) + + run!(smoothing_simulation) + + return smoothing_model.tracers +end From 6822280a0cde1ff9196ae8f0d86adb96aced708f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:45:57 -0500 Subject: [PATCH 077/716] comment --- examples/freely_decaying_mediterranean.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 99a16913..52cb6152 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -56,7 +56,7 @@ nothing_to_default(user_value; default) = isnothing(user_value) ? default : user # Constructing the model # -# We construct the model with three tracers, temperature (:T), salinity (:S) +# We construct a model that evolves two tracers, temperature (:T), salinity (:S) # We do not have convection since the simulation is just slumping to equilibrium so we do not need a turbulence closure # We select a linear equation of state for buoyancy calculation, and WENO schemes for both tracer and momentum advection. # The free surface utilizes a split-explicit formulation with a barotropic CFL of 0.75 based on wave speed. From a81496e15942f1ad0519df5afb6e5a8689f75a9a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:59:57 -0500 Subject: [PATCH 078/716] finished --- examples/freely_decaying_mediterranean.jl | 50 +++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 52cb6152..ffff5b3c 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -128,7 +128,51 @@ simulation.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model run!(simulation) +# Record a video +# +# Let's read the data and record a video of the Mediterranean Sea's surface +# (1) Zonal velocity (u) +# (2) Meridional velocity (v) +# (3) Temperature (T) +# (4) Salinity (S) +u_series = FieldTimeSeries("med_surface_field.jld2", "u") +v_series = FieldTimeSeries("med_surface_field.jld2", "v") +T_series = FieldTimeSeries("med_surface_field.jld2", "T") +S_series = FieldTimeSeries("med_surface_field.jld2", "S") +iter = Observable(1) + +u = @lift begin + f = interior(u_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end +v = @lift begin + f = interior(v_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end +T = @lift begin + f = interior(T_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end +S = @lift begin + f = interior(S_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end - - - +fig = Figure() +ax = Axis(fig[1, 1], title = "surface zonal velocity ms⁻¹") +heatmap!(u) +ax = Axis(fig[1, 2], title = "surface meridional velocity ms⁻¹") +heatmap!(v) +ax = Axis(fig[2, 1], title = "surface temperature ᵒC") +heatmap!(T) +ax = Axis(fig[2, 2], title = "surface salinity psu") +heatmap!(S) + +GLMakie.record(fig, "mediterranean_video.mp4", 1:length(u_series.times); framerate = 5) do i + @info "recording iteration $i" + iter[] = i +end \ No newline at end of file From 7c52982855cc018c2c1a02c7ab3b676d5c409c65 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:41:59 -0500 Subject: [PATCH 079/716] freely decaying med simpler set! --- examples/freely_decaying_mediterranean.jl | 9 ++- src/DataWrangling/ECCO2.jl | 43 +++++++++++-- src/DataWrangling/fill_missing_values.jl | 11 +++- src/InitialConditions/initialize_model.jl | 73 ----------------------- 4 files changed, 53 insertions(+), 83 deletions(-) delete mode 100644 src/InitialConditions/initialize_model.jl diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index ffff5b3c..220eaaea 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -65,7 +65,7 @@ model = HydrostaticFreeSurfaceModel(; grid, tracer_advection = WENO(grid; order = 7), free_surface = SplitExplicitFreeSurface(; cfl = 0.75, grid), buoyancy = SeawaterBuoyancy(), - tracers = (:T, :S), + tracers = (:T, :S, :c), coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) # Initializing the model @@ -73,8 +73,11 @@ model = HydrostaticFreeSurfaceModel(; grid, # the model can be initialized with custom values or with ecco2 fields. # In this case, our ECCO2 dataset has access to a temperature and a salinity # field, so we initialize T and S from ECCO2. -@info "initializing model from ECCO2 fields" -initialize!(model, T = :ecco2_temperature, S = :ecco2_salinity) +# We initialize our passive tracer with a surface blob near to the coasts of Libia +@info "initializing model" +libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 + +set!(model, T = ECCO2Field(:temperature), S = ECCO2Field(:salinity), c = libia_blob) fig = Figure() ax = Axis(fig[1, 1]) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 22ec0c6d..390477a4 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -1,6 +1,6 @@ module ECCO2 -export ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! +export ECCO2Field, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.DataWrangling: fill_missing_values! @@ -11,10 +11,23 @@ using Oceananigans.Utils using KernelAbstractions: @kernel, @index using NCDatasets +import Oceananigans.Fields: set! + temperature_filename = "THETA.1440x720x50.19920102.nc" salinity_filename = "SALT.1440x720x50.19920102.nc" effective_ice_thickness_filename = "SIheff.1440x720.19920102.nc" +# Ecco field used to set model's initial conditions +struct ECCO2Field + name :: Symbol + year :: Int + month :: Int + day :: Int +end + +# We only have 1992 at the moment +ECCO2Field(name::Symbol) = ECCO2Field(name, 1992, 1, 2) + ecco2_tracer_fields = Dict( :ecco2_temperature => :temperature, :ecco2_salinity => :salinity, @@ -206,10 +219,10 @@ Keyword Arguments: - `mask`: the mask used to extend the field (see `adjust_tracer!`) """ -function adjusted_ecco_field(variable_name; - architecture = CPU(), - filename = "./data/adjusted_ecco_tracers.nc", - mask = ecco2_center_mask(architecture)) +function adjusted_ecco2_field(variable_name; + architecture = CPU(), + filename = "./data/adjusted_ecco_tracers.nc", + mask = ecco2_center_mask(architecture)) if !isfile(filename) f = ecco2_field(variable_name; architecture) @@ -243,5 +256,25 @@ function adjusted_ecco_field(variable_name; return f end +function set!(field, ecco2::ECCO2Field; filename = "./data/adjusted_ecco_tracers.nc") + # Fields initialized from ECCO2 + grid = field.grid + + mask = ecco2_center_mask(architecture(grid)) + + f = adjusted_ecco2_field(ecco2.name; + architecture = arch, + filename, + mask) + + f_grid = Field(ecco2_location[ecco2.name], grid) + + three_dimensional_regrid!(f_grid, f) + + set!(field, f_grid) + + return field +end + end # module diff --git a/src/DataWrangling/fill_missing_values.jl b/src/DataWrangling/fill_missing_values.jl index 7951f90c..e7198016 100644 --- a/src/DataWrangling/fill_missing_values.jl +++ b/src/DataWrangling/fill_missing_values.jl @@ -49,7 +49,8 @@ propagate_horizontally!(field, ::Nothing; kw...) = nothing """ propagate_horizontally!(field, mask; max_iter = Inf) -propagate horizontally +propagate horizontally a field with missing values outside of a `mask`. +Grid cells where `mask == 1` will be preserved """ function propagate_horizontally!(field, mask; max_iter = Inf) iter = 0 @@ -73,7 +74,13 @@ end continue_downwards!(field, ::Nothing) = nothing -function continue_downwards!(field, mask) +""" + continue_downwards!(field, mask) + +continue downwards a field with missing values outside of a `mask`. +Grid cells where `mask == 1` will be preserved +""" +function (field, mask) arch = architecture(field) grid = field.grid launch!(arch, grid, :xy, _continue_downwards!, field, grid, mask) diff --git a/src/InitialConditions/initialize_model.jl b/src/InitialConditions/initialize_model.jl deleted file mode 100644 index 74e7b0cb..00000000 --- a/src/InitialConditions/initialize_model.jl +++ /dev/null @@ -1,73 +0,0 @@ -using ClimaOcean.DataWrangling.ECCO2: ecco2_tracer_fields, adjusted_ecco_field, ecco2_location -using ClimaOcean.DataWrangling.ECCO2: ecco2_center_mask - -""" - initialize!(model; - filename = "./data/adjusted_ecco_tracers.nc", - kwargs...) - -Initialize `model`. The keyword arguments `kwargs...` take the form `name=data`, -where `name` refers to one of the fields of `model.velocities` or `model.tracers`, -and the `data` may be - (1) an array - (2) a function with arguments `(x, y, z)` for 3D fields, `(x, y)` for 2D fields and `(x)` for 1D fields - (3) a symbol corresponding to a fldname contained in `ecco2_tracer_fields` - (4) a checkpoint path containing the checkpointed field -The keyword argument `filename` is the path to a netcdf file containing the adjusted ecco fields. -If the file does not exist it will be created -""" -function initialize!(model; - filename = "./data/adjusted_ecco_tracers.nc", - kwargs...) - - grid = model.grid - arch = architecture(grid) - - custom_fields = Dict() - ecco2_fields = Dict() - checkpoint_fields = Dict() - - # Differentiate between custom initialization and ECCO2 initialization - for (fldname, value) in kwargs - if value ∈ keys(ecco2_tracer_fields) - ecco2_fields[fldname] = ecco2_tracer_fields[value] - elseif value isa String - checkpoint_fields[fldname] = value - else - custom_fields[fldname] = value - end - end - - # Custom fields not present in the ECCO dataset - if !isempty(custom_fields) - set!(model; custom_fields...) - end - - # Fields initialized from checkpointer - if !isempty(checkpoint_fields) - for (fldname, path) in checkpoint_fields - data = jldopen(path)[string(fldname) * "/data"] - set!(model, fldname => data) - end - end - - # Fields initialized from ECCO2 - if !isempty(ecco2_fields) - mask = ecco2_center_mask(architecture(grid)) - - for (fldname, variable_name) in ecco2_fields - f = adjusted_ecco_field(variable_name; - architecture = arch, - filename, - mask) - - f_grid = Field(ecco2_location[variable_name], grid) - - three_dimensional_regrid!(f_grid, f) - - set!(model; fldname => f_grid) - end - end - - return nothing -end From 333a15bb29ec9d35604befbee66aef9ba760d015 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:43:28 -0500 Subject: [PATCH 080/716] bugfix --- src/InitialConditions/InitialConditions.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 22a92b87..189b7095 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -65,7 +65,6 @@ function three_dimensional_regrid!(a, b) end include("diffuse_tracers.jl") -include("initialize_model.jl") end # module From 2ca7a89960d530cf468b8f7cf706580b1bb708cd Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:49:49 -0500 Subject: [PATCH 081/716] return a value --- src/InitialConditions/InitialConditions.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 189b7095..78cd6634 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -62,6 +62,8 @@ function three_dimensional_regrid!(a, b) # Finally regrid in x @debug "Regridding in x" regrid!(a, target_grid, ygrid, field_y) + + return a end include("diffuse_tracers.jl") From a4f7e1d380d93df2057509d7ef52b82166061208 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:03:03 -0500 Subject: [PATCH 082/716] some changes --- src/DataWrangling/ECCO2.jl | 31 +++++++++++++++++++------------ test/test_ecco2.jl | 11 ++++++++++- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 390477a4..854b26da 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -1,6 +1,6 @@ module ECCO2 -export ECCO2Field, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! +export ECCO2Data, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.DataWrangling: fill_missing_values! @@ -13,12 +13,8 @@ using NCDatasets import Oceananigans.Fields: set! -temperature_filename = "THETA.1440x720x50.19920102.nc" -salinity_filename = "SALT.1440x720x50.19920102.nc" -effective_ice_thickness_filename = "SIheff.1440x720.19920102.nc" - # Ecco field used to set model's initial conditions -struct ECCO2Field +struct ECCO2Data name :: Symbol year :: Int month :: Int @@ -26,7 +22,9 @@ struct ECCO2Field end # We only have 1992 at the moment -ECCO2Field(name::Symbol) = ECCO2Field(name, 1992, 1, 2) +ECCO2Data(name::Symbol) = ECCO2Data(name, 1992, 1, 2) + +filename(data::ECCO2Data) = "ecco2_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).nc" ecco2_tracer_fields = Dict( :ecco2_temperature => :temperature, @@ -91,7 +89,11 @@ function construct_vertical_interfaces(ds, depth_name) return zf end -function empty_ecco2_field(variable_name; architecture = CPU(), horizontal_halo = (1, 1)) +function empty_ecco2_field(data::ECCO2Data; architecture = CPU(), + horizontal_halo = (1, 1)) + + variable_name = data.name + location = ecco2_location[variable_name] longitude = (0, 360) @@ -143,10 +145,15 @@ function ecco2_field(variable_name; architecture = CPU(), horizontal_halo = (1, 1), user_data = nothing, - url = ecco2_urls[variable_name], + year = 1992, + month = 1, + day = 2, + url = ecco2_urls[variable_name], filename = ecco2_file_names[variable_name], short_name = ecco2_short_names[variable_name]) + ecco2_data = ECCO2Data(variable_name, year, month, day) + isfile(filename) || download(url, filename) if user_data isa Nothing @@ -163,7 +170,7 @@ function ecco2_field(variable_name; data = user_data end - field = empty_ecco2_field(variable_name; architecture, horizontal_halo) + field = empty_ecco2_field(ecco2_data; architecture, horizontal_halo) FT = eltype(field) data = convert.(FT, data) @@ -256,14 +263,14 @@ function adjusted_ecco2_field(variable_name; return f end -function set!(field, ecco2::ECCO2Field; filename = "./data/adjusted_ecco_tracers.nc") +function set!(field::Field, ecco2::ECCO2Data; filename = "./data/adjusted_ecco_tracers.nc") # Fields initialized from ECCO2 grid = field.grid mask = ecco2_center_mask(architecture(grid)) f = adjusted_ecco2_field(ecco2.name; - architecture = arch, + architecture = architecture(grid), filename, mask) diff --git a/test/test_ecco2.jl b/test/test_ecco2.jl index 3e482675..5fe6c8c0 100644 --- a/test/test_ecco2.jl +++ b/test/test_ecco2.jl @@ -38,4 +38,13 @@ using Oceananigans.Grids: topology @test Ny == 720 @test Nz == 1 end -end \ No newline at end of file +end + +@testset "setting a field with ECCO2" begin + for arch in test_architectures + grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (-5, 5), z = (-200, 0)) + field = CenterField(grid) + set!(field, ECCO2Field(:temperature)) + set!(field, ECCO2Field(:salinity)) + end +end From a4a7185ff879994b3b23c5945099d13d3f68321b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:06:46 -0500 Subject: [PATCH 083/716] test it out --- examples/freely_decaying_mediterranean.jl | 10 +++++++++- test/test_ecco2.jl | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 220eaaea..7102e39c 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -77,7 +77,7 @@ model = HydrostaticFreeSurfaceModel(; grid, @info "initializing model" libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 -set!(model, T = ECCO2Field(:temperature), S = ECCO2Field(:salinity), c = libia_blob) +set!(model, T = ECCO2Data(:temperature), S = ECCO2Data(:salinity), c = libia_blob) fig = Figure() ax = Axis(fig[1, 1]) @@ -142,6 +142,7 @@ u_series = FieldTimeSeries("med_surface_field.jld2", "u") v_series = FieldTimeSeries("med_surface_field.jld2", "v") T_series = FieldTimeSeries("med_surface_field.jld2", "T") S_series = FieldTimeSeries("med_surface_field.jld2", "S") +c_series = FieldTimeSeries("med_surface_field.jld2", "c") iter = Observable(1) u = @lift begin @@ -164,6 +165,11 @@ S = @lift begin f[f .== 0] .= NaN f end +c = @lift begin + f = interior(c_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end fig = Figure() ax = Axis(fig[1, 1], title = "surface zonal velocity ms⁻¹") @@ -174,6 +180,8 @@ ax = Axis(fig[2, 1], title = "surface temperature ᵒC") heatmap!(T) ax = Axis(fig[2, 2], title = "surface salinity psu") heatmap!(S) +ax = Axis(fig[2, 3], title = "passive tracer -") +heatmap!(c) GLMakie.record(fig, "mediterranean_video.mp4", 1:length(u_series.times); framerate = 5) do i @info "recording iteration $i" diff --git a/test/test_ecco2.jl b/test/test_ecco2.jl index 5fe6c8c0..a3a13dbe 100644 --- a/test/test_ecco2.jl +++ b/test/test_ecco2.jl @@ -44,7 +44,7 @@ end for arch in test_architectures grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (-5, 5), z = (-200, 0)) field = CenterField(grid) - set!(field, ECCO2Field(:temperature)) - set!(field, ECCO2Field(:salinity)) + set!(field, ECCO2Data(:temperature)) + set!(field, ECCO2Data(:salinity)) end end From cb1c451eebca71c1ebc401980c678af5fafe6405 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:07:55 -0500 Subject: [PATCH 084/716] bugfix --- src/ClimaOcean.jl | 2 +- src/DataWrangling/ECCO2.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index fc66dc95..49c56a95 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -66,8 +66,8 @@ end @inline v_immersed_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) include("VerticalGrids.jl") -include("DataWrangling/DataWrangling.jl") include("InitialConditions/InitialConditions.jl") +include("DataWrangling/DataWrangling.jl") include("Bathymetry.jl") include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 854b26da..0f3f62d9 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -3,6 +3,7 @@ module ECCO2 export ECCO2Data, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.DataWrangling: fill_missing_values! +using ClimaOcean.InitialConditions: three_dimensional_regrid! using Oceananigans using Oceananigans: architecture From bd517595832564a8651ceec67b4d27fad8fa0078 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 30 Nov 2023 13:42:18 -0700 Subject: [PATCH 085/716] 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 086/716] 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 087/716] 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 088/716] 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 089/716] 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 090/716] 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 091/716] 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 9ab3093bafb19962c63122f8bbefc278b8a9a4af Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:16:18 -0500 Subject: [PATCH 092/716] probably ready to go? --- examples/freely_decaying_mediterranean.jl | 2 +- src/DataWrangling/ECCO2.jl | 14 +++++++------- test/test_ecco2.jl | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 7102e39c..83b719c4 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -77,7 +77,7 @@ model = HydrostaticFreeSurfaceModel(; grid, @info "initializing model" libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 -set!(model, T = ECCO2Data(:temperature), S = ECCO2Data(:salinity), c = libia_blob) +set!(model, T = ECCO2Metadata(:temperature), S = ECCO2Metadata(:salinity), c = libia_blob) fig = Figure() ax = Axis(fig[1, 1]) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 0f3f62d9..2c924c8b 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -1,6 +1,6 @@ module ECCO2 -export ECCO2Data, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! +export ECCO2Metadata, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.DataWrangling: fill_missing_values! using ClimaOcean.InitialConditions: three_dimensional_regrid! @@ -15,7 +15,7 @@ using NCDatasets import Oceananigans.Fields: set! # Ecco field used to set model's initial conditions -struct ECCO2Data +struct ECCO2Metadata name :: Symbol year :: Int month :: Int @@ -23,9 +23,9 @@ struct ECCO2Data end # We only have 1992 at the moment -ECCO2Data(name::Symbol) = ECCO2Data(name, 1992, 1, 2) +ECCO2Metadata(name::Symbol) = ECCO2Metadata(name, 1992, 1, 2) -filename(data::ECCO2Data) = "ecco2_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).nc" +filename(data::ECCO2Metadata) = "ecco2_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).nc" ecco2_tracer_fields = Dict( :ecco2_temperature => :temperature, @@ -90,7 +90,7 @@ function construct_vertical_interfaces(ds, depth_name) return zf end -function empty_ecco2_field(data::ECCO2Data; architecture = CPU(), +function empty_ecco2_field(data::ECCO2Metadata; architecture = CPU(), horizontal_halo = (1, 1)) variable_name = data.name @@ -153,7 +153,7 @@ function ecco2_field(variable_name; filename = ecco2_file_names[variable_name], short_name = ecco2_short_names[variable_name]) - ecco2_data = ECCO2Data(variable_name, year, month, day) + ecco2_data = ECCO2Metadata(variable_name, year, month, day) isfile(filename) || download(url, filename) @@ -264,7 +264,7 @@ function adjusted_ecco2_field(variable_name; return f end -function set!(field::Field, ecco2::ECCO2Data; filename = "./data/adjusted_ecco_tracers.nc") +function set!(field::Field, ecco2::ECCO2Metadata; filename = "./data/adjusted_ecco_tracers.nc") # Fields initialized from ECCO2 grid = field.grid diff --git a/test/test_ecco2.jl b/test/test_ecco2.jl index a3a13dbe..4d589532 100644 --- a/test/test_ecco2.jl +++ b/test/test_ecco2.jl @@ -44,7 +44,7 @@ end for arch in test_architectures grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (-5, 5), z = (-200, 0)) field = CenterField(grid) - set!(field, ECCO2Data(:temperature)) - set!(field, ECCO2Data(:salinity)) + set!(field, ECCO2Metadata(:temperature)) + set!(field, ECCO2Metadata(:salinity)) end end From abf3b2526da7a485903b1fa45d5bacf6dddf596d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:22:38 -0500 Subject: [PATCH 093/716] fixes CI --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8d7f30c..830bf6b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,8 @@ jobs: - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v2 + with: + file: lcov.info - name: Install dependencies run: | julia --color=yes --project -e 'using Pkg; Pkg.instantiate()' @@ -55,6 +57,4 @@ jobs: julia --color=yes --project -e 'using Pkg; Pkg.test()' env: TEST_GROUP: "downloading" - with: - file: lcov.info From 01c1a519dbac8d685c26a44c31997a85f42792ac Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 13 Dec 2023 11:14:45 -0700 Subject: [PATCH 094/716] 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 48109caa827ec375f0a8356254e11d84a17cc4a0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:55:41 -0500 Subject: [PATCH 095/716] fiox download test --- test/test_downloading.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_downloading.jl b/test/test_downloading.jl index 60d0cddf..905c44a7 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.JRA55.jra55_variable_names + for name in ClimaOcean.JRA55.jra55_short_names fts = ClimaOcean.JRA55.jra55_field_time_series(name; time_indices=1:1) end end From 9ce454ba5825bb8af4712f032d53773d59574c97 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 19 Dec 2023 11:04:27 +0100 Subject: [PATCH 096/716] small fix --- src/DataWrangling/JRA55.jl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 95e90930..efd03dd5 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -7,17 +7,17 @@ using NCDatasets # A list of all variables provided in the JRA55 dataset: jra55_short_names = (:freshwater_river_flux, - :freshwater_rain_flux, - :freshwater_snow_flux, - :freshwater_iceberg_flux, - :specific_humidity, - :sea_level_pressure, - :relative_humidity, - :downwelling_longwave_radiation, - :downwelling_shortwave_radiation, - :atmospheric_temperature, - :atmospheric_eastward_velocity, - :atmospheric_northward_velocity) + :freshwater_rain_flux, + :freshwater_snow_flux, + :freshwater_iceberg_flux, + :specific_humidity, + :sea_level_pressure, + :relative_humidity, + :downwelling_longwave_radiation, + :downwelling_shortwave_radiation, + :atmospheric_temperature, + :atmospheric_eastward_velocity, + :atmospheric_northward_velocity) file_names = Dict( :freshwater_river_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers From 29e0b352ededa6614bc7a7256b2710c731b576e8 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 8 Jan 2024 07:59:10 -0700 Subject: [PATCH 097/716] 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 098/716] 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 099/716] 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 100/716] 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 101/716] 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 102/716] 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 103/716] 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 104/716] 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 105/716] 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 106/716] 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 107/716] 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 108/716] 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 109/716] 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 60393b9a3539e7fbc88cdbeb1853fc1153147cc5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Jan 2024 19:43:30 -0500 Subject: [PATCH 110/716] tests should pass --- Manifest.toml | 16 ++++++++-------- src/ClimaOcean.jl | 2 +- src/DataWrangling/fill_missing_values.jl | 2 +- src/InitialConditions/InitialConditions.jl | 5 +++-- test/test_ecco2.jl | 3 ++- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index ee804eb2..79be6308 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-beta3" +julia_version = "1.10.0" manifest_format = "2.0" -project_hash = "b7533e038510e895b3ed88ff9988c4cfa7400e76" +project_hash = "b0de2c0b9b63c5f2aa2406aac544be6c8761c819" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -476,7 +476,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"] @@ -638,11 +638,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 = "0e87d4ffcd1ff8fb423659bab04e2581c76f0d95" -repo-rev = "glw/better-interpolate" +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.2" +version = "0.90.5" [deps.Oceananigans.extensions] OceananigansEnzymeCoreExt = "EnzymeCore" @@ -975,9 +975,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.TOML]] deps = ["Dates"] diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 49c56a95..21913645 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -4,7 +4,7 @@ export regrid_bathymetry export stretched_vertical_faces export PowerLawStretching, LinearStretching export jra55_field_time_series -export ecco2_field +export ecco2_field, ECCO2Metadata export initialize! using Oceananigans diff --git a/src/DataWrangling/fill_missing_values.jl b/src/DataWrangling/fill_missing_values.jl index e7198016..591a5298 100644 --- a/src/DataWrangling/fill_missing_values.jl +++ b/src/DataWrangling/fill_missing_values.jl @@ -80,7 +80,7 @@ continue_downwards!(field, ::Nothing) = nothing continue downwards a field with missing values outside of a `mask`. Grid cells where `mask == 1` will be preserved """ -function (field, mask) +function continue_downwards!(field, mask) arch = architecture(field) grid = field.grid launch!(arch, grid, :xy, _continue_downwards!, field, grid, mask) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 78cd6634..9edc1e7b 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -14,7 +14,8 @@ using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll using JLD2 -# TODO: move all the following to Oceananigans! +# Implementation of 3-dimensional regridding +# TODO: move all the following to Oceananigans! using Oceananigans.Fields: regrid! using Oceananigans.Grids: cpu_face_constructor_x, @@ -29,7 +30,7 @@ construct_grid(::Type{<:RectilinearGrid}, arch, size, extent, topology) = construct_grid(::Type{<:LatitudeLongitudeGrid}, arch, size, extent, topology) = LatitudeLongitudeGrid(arch; size, longitude = extent[1], latitude = extent[2], z = extent[3], topology) -# Extend this to regrid automatically +# Regrid a field in three dimensions function three_dimensional_regrid!(a, b) target_grid = a.grid isa ImmersedBoundaryGrid ? a.grid.underlying_grid : a.grid source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid diff --git a/test/test_ecco2.jl b/test/test_ecco2.jl index 4d589532..278dc2bf 100644 --- a/test/test_ecco2.jl +++ b/test/test_ecco2.jl @@ -1,6 +1,7 @@ include("runtests_setup.jl") -using ClimaOcean: ECCO2 +using ClimaOcean +using ClimaOcean.ECCO2 using Oceananigans.Grids: topology @testset "ECCO2 fields utilities" begin From 6efc2756e0568608c42cde70b380dff07338cf18 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jan 2024 09:09:28 -0500 Subject: [PATCH 111/716] comment on interpolation passes --- src/Bathymetry.jl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 42ec632a..5aacf141 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -52,7 +52,14 @@ Keyword Arguments: - interpolation_passes: regridding/interpolation passes. The bathymetry is interpolated in `interpolation_passes - 1` intermediate steps. With more steps the final bathymetry will be smoother. - + Example: interpolating from a 400x200 grid to a 100x100 grid in 4 passes will involve + - 400x200 -> 325x175 + - 325x175 -> 250x150 + - 250x150 -> 175x125 + - 175x125 -> 100x100 + If _coarsening_ the original grid, linear interpolation in passes is equivalent to a + smoothing gaussian filter, with more passes increasing the strength of the filter. + If _refining_ the original grid, additional passes will not help smoothing. """ function regrid_bathymetry(target_grid; height_above_water = nothing, @@ -60,7 +67,7 @@ function regrid_bathymetry(target_grid; dir = joinpath(@__DIR__, "..", "data"), url = "https://www.ngdc.noaa.gov/thredds/fileServer/global/ETOPO2022/60s/60s_surface_elev_netcdf", filename = "ETOPO_2022_v1_60s_N90W180_surface.nc", - interpolation_passes = 10) + interpolation_passes = 1) filepath = joinpath(dir, filename) From 38449700a7fe8d71bbe7bbf4cf23f8c75a6205fe Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jan 2024 09:10:09 -0500 Subject: [PATCH 112/716] comment --- src/Bathymetry.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 5aacf141..dd02f4c0 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -57,8 +57,8 @@ Keyword Arguments: - 325x175 -> 250x150 - 250x150 -> 175x125 - 175x125 -> 100x100 - If _coarsening_ the original grid, linear interpolation in passes is equivalent to a - smoothing gaussian filter, with more passes increasing the strength of the filter. + If _coarsening_ the original grid, linear interpolation in passes is equivalent to + applying a smoothing filter, with more passes increasing the strength of the filter. If _refining_ the original grid, additional passes will not help smoothing. """ function regrid_bathymetry(target_grid; From dbb725625789ac8d76623047449fad73fc92071d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jan 2024 09:11:04 -0500 Subject: [PATCH 113/716] comment --- src/Bathymetry.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index dd02f4c0..d47af1d5 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -59,7 +59,8 @@ Keyword Arguments: - 175x125 -> 100x100 If _coarsening_ the original grid, linear interpolation in passes is equivalent to applying a smoothing filter, with more passes increasing the strength of the filter. - If _refining_ the original grid, additional passes will not help smoothing. + If _refining_ the original grid, additional passes will not help and no intermediate + steps will be performed. """ function regrid_bathymetry(target_grid; height_above_water = nothing, From 1cfe3f97cd53b347eb2eab5ae460dc8d165fab16 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jan 2024 09:12:15 -0500 Subject: [PATCH 114/716] better name --- src/Bathymetry.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index d47af1d5..b38470a3 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -171,9 +171,9 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) Nλn, Nφn = Nn = size(native_h) if any(Nt[1:2] .> Nn[1:2]) # We are refining the grid (at least in one direction), more passes will not help! - new_h = Field{Center, Center, Nothing}(target_grid) - interpolate!(new_h, native_h) - return new_h + target_h = Field{Center, Center, Nothing}(target_grid) + interpolate!(target_h, native_h) + return target_h end latitude = y_domain(target_grid) From bff00b05de317e13ba8ff4a17fb94190e4392433 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 24 Jan 2024 13:13:05 -0700 Subject: [PATCH 115/716] 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 116/716] 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 117/716] 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 118/716] 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 119/716] 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 120/716] 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 121/716] 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 122/716] 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 123/716] 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 124/716] 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 125/716] 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 126/716] 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 127/716] 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 128/716] 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 129/716] 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 130/716] 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 131/716] 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 132/716] 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 133/716] 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 134/716] 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 135/716] 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 136/716] 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 137/716] 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 138/716] 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 139/716] 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 140/716] 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 141/716] 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 142/716] 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 143/716] 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 144/716] =?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 145/716] =?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 146/716] 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 147/716] 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 148/716] 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 149/716] 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 150/716] 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 151/716] 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 152/716] 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 153/716] 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 154/716] 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 155/716] 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 156/716] 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 157/716] 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 158/716] 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 159/716] 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 160/716] 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 161/716] 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 162/716] 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 163/716] 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 164/716] 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 165/716] 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 166/716] 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 167/716] 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 168/716] 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 169/716] 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 170/716] 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 171/716] 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 172/716] 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 173/716] 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 174/716] 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 175/716] 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 176/716] 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 177/716] 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 178/716] 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 179/716] 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 180/716] 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 181/716] 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 182/716] 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 183/716] 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 184/716] 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 185/716] 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 186/716] 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 187/716] 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 188/716] 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 189/716] 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 190/716] 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 191/716] 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 192/716] 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 193/716] 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 194/716] 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 195/716] 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 196/716] 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 197/716] 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 198/716] 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 199/716] 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 c3551c0fbb8a842c6cbebcfc4631d405cdfffc48 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:45:17 -0500 Subject: [PATCH 200/716] add the manifest --- Manifest.toml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index b46af48f..79bba00a 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,11 +2,7 @@ julia_version = "1.10.0" manifest_format = "2.0" -<<<<<<< HEAD project_hash = "b0de2c0b9b63c5f2aa2406aac544be6c8761c819" -======= -project_hash = "bcfc95e502c18276c6e7315f722ad6f48d7698c2" ->>>>>>> origin/glw-ss/ice-ocean-model [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -745,19 +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"] -<<<<<<< HEAD -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.5" -======= 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" ->>>>>>> origin/glw-ss/ice-ocean-model [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -1125,8 +1113,6 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.1+1" -<<<<<<< HEAD -======= [[deps.SurfaceFluxes]] deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] @@ -1135,7 +1121,6 @@ repo-rev = "glw/generalize-parameters" repo-url = "https://github.com/glwagner/SurfaceFluxes.jl.git" uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" version = "0.8.1" ->>>>>>> origin/glw-ss/ice-ocean-model [[deps.TOML]] deps = ["Dates"] From 2318c75f11649056d5271f118017ee399db9f432 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:47:55 -0500 Subject: [PATCH 201/716] simplify ecco --- Manifest.toml | 10 +- experiments/twelth_degree_latlong.jl | 132 +++++++++++++++++++++++++++ src/DataWrangling/ECCO2.jl | 38 -------- 3 files changed, 137 insertions(+), 43 deletions(-) create mode 100644 experiments/twelth_degree_latlong.jl diff --git a/Manifest.toml b/Manifest.toml index 79bba00a..42726cd3 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.1" manifest_format = "2.0" -project_hash = "b0de2c0b9b63c5f2aa2406aac544be6c8761c819" +project_hash = "bcfc95e502c18276c6e7315f722ad6f48d7698c2" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -211,7 +211,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" @@ -741,7 +741,7 @@ 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" +git-tree-sha1 = "e9da32d6e239182ca7623a73cc92ea518cfec0e4" repo-rev = "ss-glw/time-bcs" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" @@ -765,7 +765,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"] diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl new file mode 100644 index 00000000..b09d6e80 --- /dev/null +++ b/experiments/twelth_degree_latlong.jl @@ -0,0 +1,132 @@ +using Oceananigans +using Oceananigans: architecture +using ClimaOcean +using ClimaOcean.ECCO2 +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity +using Oceananigans.Coriolis: ActiveCellEnstrophyConserving +using Oceananigans.Units +using Printf + +##### +##### Regional Mediterranean grid +##### + +# Domain and Grid size +# +# We construct a grid that represents the Mediterranean sea, +# with a resolution of 1/10th of a degree (roughly 10 km resolution) +λ₁, λ₂ = ( 0, 42) # domain in longitude +φ₁, φ₂ = (30, 45) # domain in latitude +# A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters +z_faces = stretched_vertical_faces(depth = 5000, + surface_layer_Δz = 2.5, + stretching = PowerLawStretching(1.070), + surface_layer_height = 50) + +Nx = 15 * 42 # 1 / 15th of a degree resolution +Ny = 15 * 15 # 1 / 15th of a degree resolution +Nz = length(z_faces) - 1 + +grid = LatitudeLongitudeGrid(CPU(); + size = (Nx, Ny, Nz), + latitude = (φ₁, φ₂), + longitude = (λ₁, λ₂), + z = z_faces, + halo = (7, 7, 7)) + +# Interpolating the bathymetry onto the grid +# +# We regrid the bathymetry onto the grid. +# we allow a minimum depth of 10 meters (all shallower regions are +# considered land) and we use 25 intermediate grids (interpolation_passes = 25) +# Note that more interpolation passes will smooth the bathymetry +bottom_height = regrid_bathymetry(grid, + height_above_water = 1, + minimum_depth = 10, + interpolation_passes = 25) + +# Let's use an active cell map to elide computation in inactive cells +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) + +# Correct oceananigans +import Oceananigans.Advection: nothing_to_default + +nothing_to_default(user_value; default) = isnothing(user_value) ? default : user_value + +# Constructing the model +# +# We construct a model that evolves two tracers, temperature (:T), salinity (:S) +# We do not have convection since the simulation is just slumping to equilibrium so we do not need a turbulence closure +# We select a linear equation of state for buoyancy calculation, and WENO schemes for both tracer and momentum advection. +# The free surface utilizes a split-explicit formulation with a barotropic CFL of 0.75 based on wave speed. +model = HydrostaticFreeSurfaceModel(; grid, + momentum_advection = WENOVectorInvariant(), + tracer_advection = WENO(grid; order = 7), + free_surface = SplitExplicitFreeSurface(; cfl = 0.75, grid), + buoyancy = SeawaterBuoyancy(), + tracers = (:T, :S, :c), + coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) + +# Initializing the model +# +# the model can be initialized with custom values or with ecco2 fields. +# In this case, our ECCO2 dataset has access to a temperature and a salinity +# field, so we initialize T and S from ECCO2. +# We initialize our passive tracer with a surface blob near to the coasts of Libia +@info "initializing model" +libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 + +set!(model, T = ECCO2Metadata(:temperature), S = ECCO2Metadata(:salinity), c = libia_blob) + +fig = Figure() +ax = Axis(fig[1, 1]) +heatmap!(ax, interior(model.tracers.T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) +ax = Axis(fig[1, 2]) +heatmap!(ax, interior(model.tracers.S, :, :, Nz), colorrange = (35, 40), colormap = :haline) + +simulation = Simulation(model, Δt = 10minutes, stop_time = 10*365days) + +function progress(sim) + u, v, w = sim.model.velocities + T, S = sim.model.tracers + + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(T, S): %.2f, %.2f\n", + prettytime(sim.model.clock.time), + sim.model.clock.iteration, + prettytime(sim.Δt), + maximum(abs, u), maximum(abs, v), maximum(abs, w), + maximum(abs, T), maximum(abs, S)) +end + +simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +# Simulation warm up! +# +# We have regridded from a coarse solution (1/4er of a degree) to a +# fine grid (1/15th of a degree). Also, the bathymetry has little mismatches +# that might crash our simulation. We warm up the simulation with a little +# time step for few iterations to allow the solution to adjust to the new_grid +# bathymetry +simulation.Δt = 10 +simulation.stop_iteration = 1000 +run!(simulation) + +# Run the real simulation +# +# Now that the solution has adjusted to the bathymetry we can ramp up the time +# step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.2 +wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 10minutes, max_change = 1.1) + +simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) + +# Let's reset the maximum number of iterations +simulation.stop_iteration = Inf + +simulation.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); + indices = (:, :, Nz), + schedule = TimeInterval(1day), + overwrite_existing = true, + filename = "med_surface_field") + +run!(simulation) + diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index aaa0fe2b..8d70e1a2 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -92,15 +92,6 @@ const ECCO2_z = [ 0.0, ] -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", -) - ecco2_location = Dict( :temperature => (Center, Center, Center), :salinity => (Center, Center, Center), @@ -112,35 +103,6 @@ ecco2_depth_names = Dict( :salinity => "DEPTH_T", ) -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_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", :salinity => "SALT", From ac268274f3fde691626718769f3ea50c6d4a0468 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:48:29 -0500 Subject: [PATCH 202/716] back to correct ecco --- src/DataWrangling/ECCO2.jl | 119 +++++++++++++++---------------------- 1 file changed, 47 insertions(+), 72 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 8d70e1a2..9906c41b 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -33,64 +33,11 @@ ecco2_tracer_fields = Dict( :ecco_2_effective_ice_thickness => :effective_ice_thickness ) -const ECCO2_Nx = 1440 -const ECCO2_Ny = 720 -const ECCO2_Nz = 50 - -# Vertical coordinate -const ECCO2_z = [ - -6128.75, - -5683.75, - -5250.25, - -4839.75, - -4452.25, - -4087.75, - -3746.25, - -3427.75, - -3132.25, - -2859.75, - -2610.25, - -2383.74, - -2180.13, - -1999.09, - -1839.64, - -1699.66, - -1575.64, - -1463.12, - -1357.68, - -1255.87, - -1155.72, - -1056.53, - -958.45, - -862.10, - -768.43, - -678.57, - -593.72, - -515.09, - -443.70, - -380.30, - -325.30, - -278.70, - -240.09, - -208.72, - -183.57, - -163.43, - -147.11, - -133.45, - -121.51, - -110.59, - -100.20, - -90.06, - -80.01, - -70.0, - -60.0, - -50.0, - -40.0, - -30.0, - -20.0, - -10.0, - 0.0, -] +ecco2_short_names = Dict( + :temperature => "THETA", + :salinity => "SALT", + :effective_ice_thickness => "SIheff" +) ecco2_location = Dict( :temperature => (Center, Center, Center), @@ -103,15 +50,45 @@ ecco2_depth_names = Dict( :salinity => "DEPTH_T", ) -shortnames = Dict( - :temperature => "THETA", - :salinity => "SALT", - :sea_ice_thickness => "SIheff", - :sea_ice_area_fraction => "SIarea", - :u_velocity => "UVEL", - :v_velocity => "VVEL", +variable_is_three_dimensional = Dict( + :temperature => true, + :salinity => true, + :effective_ice_thickness => false, +) + +ecco2_file_names = Dict( + :temperature => "ecco2_temperature_19920102.nc", + :salinity => "ecco2_salinity_19920102.nc", + :effective_ice_thickness => "ecco2_effective_ice_thickness_19920102.nc", +) + +# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N + +ecco2_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", + + :effective_ice_thickness => "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/" * + "SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am&dl=0" ) +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)) @@ -120,13 +97,9 @@ function empty_ecco2_field(data::ECCO2Metadata; architecture = CPU(), 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] @@ -313,3 +286,5 @@ end end # module + + From c3d60c3f1c57c2689c9a8738f4ceec38d09d7b82 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:21:31 -0500 Subject: [PATCH 203/716] starting --- experiments/twelth_degree_latlong.jl | 97 ++++-------- src/OceanSimulations/OceanSimulations.jl | 27 +++- .../load_balanced_ocean_grid.jl | 142 ++++++++++++++++++ src/VerticalGrids.jl | 15 ++ 4 files changed, 207 insertions(+), 74 deletions(-) create mode 100644 src/OceanSimulations/load_balanced_ocean_grid.jl diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index b09d6e80..51c7380f 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -5,86 +5,51 @@ using ClimaOcean.ECCO2 using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units +using ClimaOcean.OceanSimulations +using ClimaOcean.VerticalGrids: exponential_z_faces +using ClimaOcean.JRA55 using Printf ##### -##### Regional Mediterranean grid +##### Global Ocean at 1/12th of a degree ##### -# Domain and Grid size -# -# We construct a grid that represents the Mediterranean sea, -# with a resolution of 1/10th of a degree (roughly 10 km resolution) -λ₁, λ₂ = ( 0, 42) # domain in longitude -φ₁, φ₂ = (30, 45) # domain in latitude -# A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters -z_faces = stretched_vertical_faces(depth = 5000, - surface_layer_Δz = 2.5, - stretching = PowerLawStretching(1.070), - surface_layer_height = 50) - -Nx = 15 * 42 # 1 / 15th of a degree resolution -Ny = 15 * 15 # 1 / 15th of a degree resolution +# 100 vertical levels +z_faces = exponential_z_faces(100, 6000) + +Nx = 4320 +Ny = 1800 Nz = length(z_faces) - 1 -grid = LatitudeLongitudeGrid(CPU(); - size = (Nx, Ny, Nz), - latitude = (φ₁, φ₂), - longitude = (λ₁, λ₂), - z = z_faces, +arch = Distributed(GPU(), partition = Partition(8)) + +grid = LoadBalancedOceanGrid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + latitude = (-75, 75), + longitude = (0, 360), halo = (7, 7, 7)) + +##### +##### The Ocean component +##### -# Interpolating the bathymetry onto the grid -# -# We regrid the bathymetry onto the grid. -# we allow a minimum depth of 10 meters (all shallower regions are -# considered land) and we use 25 intermediate grids (interpolation_passes = 25) -# Note that more interpolation passes will smooth the bathymetry -bottom_height = regrid_bathymetry(grid, - height_above_water = 1, - minimum_depth = 10, - interpolation_passes = 25) +simulation = ocean_simulation(grid) -# Let's use an active cell map to elide computation in inactive cells -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) +model = simulation.model -# Correct oceananigans -import Oceananigans.Advection: nothing_to_default +# Initializing the model +set!(model, T = ECCO2Metadata(:temperature), S = ECCO2Metadata(:salinity), e = 1e-6) -nothing_to_default(user_value; default) = isnothing(user_value) ? default : user_value +##### +##### The atmosphere +##### -# Constructing the model -# -# We construct a model that evolves two tracers, temperature (:T), salinity (:S) -# We do not have convection since the simulation is just slumping to equilibrium so we do not need a turbulence closure -# We select a linear equation of state for buoyancy calculation, and WENO schemes for both tracer and momentum advection. -# The free surface utilizes a split-explicit formulation with a barotropic CFL of 0.75 based on wave speed. -model = HydrostaticFreeSurfaceModel(; grid, - momentum_advection = WENOVectorInvariant(), - tracer_advection = WENO(grid; order = 7), - free_surface = SplitExplicitFreeSurface(; cfl = 0.75, grid), - buoyancy = SeawaterBuoyancy(), - tracers = (:T, :S, :c), - coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) +backend = JRA55NetCDFBackend(8) # InMemory(8) +atmosphere = JRA55_prescribed_atmosphere(arch, 1:56; backend) +radiation = Radiation() -# Initializing the model -# -# the model can be initialized with custom values or with ecco2 fields. -# In this case, our ECCO2 dataset has access to a temperature and a salinity -# field, so we initialize T and S from ECCO2. -# We initialize our passive tracer with a surface blob near to the coasts of Libia -@info "initializing model" -libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 - -set!(model, T = ECCO2Metadata(:temperature), S = ECCO2Metadata(:salinity), c = libia_blob) - -fig = Figure() -ax = Axis(fig[1, 1]) -heatmap!(ax, interior(model.tracers.T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) -ax = Axis(fig[1, 2]) -heatmap!(ax, interior(model.tracers.S, :, :, Nz), colorrange = (35, 40), colormap = :haline) - -simulation = Simulation(model, Δt = 10minutes, stop_time = 10*365days) +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) function progress(sim) u, v, w = sim.model.velocities diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 5e995a45..0d6007f4 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -1,5 +1,9 @@ module OceanSimulations +export LoadBalancedOceanGrid, ocean_simulation + +using Oceananigans.Advection: TracerAdvection + using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity, MixingLength, @@ -10,6 +14,8 @@ using SeawaterPolynomials.TEOS10: TEOS10EquationOfState using Oceananigans.BuoyancyModels: g_Earth using Oceananigans.Coriolis: Ω_Earth +include("load_balanced_ocean_grid.jl") + # Some defualts default_free_surface(grid) = SplitExplicitFreeSurface(cfl=0.7; grid) @@ -19,6 +25,14 @@ function default_ocean_closure() return CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) end +default_momentum_advection() = VectorInvariant(; vorticity_scheme = WENO(; order = 9), + vertical_scheme = Centered(), + divergence_scheme = WENO()) + +default_tracer_advection() = TracerAdvection(; x = WENO(; order = 7), + y = WENO(; order = 7), + z = Centered()) + # 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; @@ -26,7 +40,9 @@ function ocean_simulation(grid; free_surface = default_free_surface(grid), reference_density = 1020, rotation_rate = Ω_Earth, - gravitational_acceleration = g_Earth) + gravitational_acceleration = g_Earth, + momentum_advection = default_momentum_advection(), + tracer_advection = default_tracer_advection()) # Set up boundary conditions using Field top_zonal_momentum_flux = Jᵘ = Field{Face, Center, Nothing}(grid) @@ -44,21 +60,16 @@ function ocean_simulation(grid; buoyancy = SeawaterBuoyancy(; gravitational_acceleration, equation_of_state=teos10) # Minor simplifications for single column grids - Nx, Ny, Nz = size(grid) + Nx, Ny, _ = 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) + tracer_advection = (; T = tracer_advection, S = tracer_advection, e = nothing) end coriolis = HydrostaticSphericalCoriolis(; rotation_rate) diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl new file mode 100644 index 00000000..76e4a5d7 --- /dev/null +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -0,0 +1,142 @@ +using Oceananigans.DistributedComputations +using Oceananigans.DistributedComputations: Sizes +using Oceananigans.ImmersedBoundaries: immersed_cell +using KernelAbstractions: @index, @kernel + +function LoadBalancedOceanGrid(arch; + size, + latitude, + longitude, + z, + halo = (3, 3, 3), + kw...) + + child_arch = child_architecture(arch) + + grid = LatitudeLongitudeGrid(child_arch; + size, + longitude, + latitude, + z, + halo) + + bottom_height = regrid_bathymetry(grid, + height_above_water = 1, + minimum_depth = 10, + interpolation_passes = 25) + + return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) +end + +function LoadBalancedOceanGrid(arch::Distributed; + size, + latitude, + longitude, + z, + halo = (3, 3, 3), + maximum_Nx = 1150) + + child_arch = child_architecture(arch) + + # Global grid + grid = LatitudeLongitudeGrid(child_arch; + size, + longitude, + latitude, + z, + halo) + + bottom_height = regrid_bathymetry(grid, + height_above_water = 1, + minimum_depth = 10, + interpolation_passes = 25) + + grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + + # Starting with the load balancing + load_per_x_slab = arch_array(child_arch, zeros(Int, size[1])) + loop! = assess_x_load(device(child_arch), 512, size[1]) + loop!(load_per_x_slab, grid) + + load_per_x_slab = arch_array(CPU(), load_per_x_slab) + local_Nx = calculate_local_size(load_per_x_slab, N[1], arch.ranks[1]) + + # We cannot have Nx > 650 if Nranks = 32 otherwise we incur in memory limitations, + # so for a small number of GPUs we are limited in the load balancing + redistribute_size_to_fulfill_memory_limitation!(local_Nx, maximum_Nx) + + arch = Distributed(child_arch, partition = Partition(x = Sizes(local_Nx...))) + zonal_rank = arch.local_index[1] + + @info "slab decomposition with " zonal_rank local_Nx[zonal_rank], arch + + @show underlying_grid = LatitudeLongitudeGrid(arch; + size = N, + longitude = (-180, 180), + latitude = latitude, + halo = (7, 7, 7), + z = z_faces) + + return ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height), active_cells_map = true) +end + +@kernel function assess_x_load(load_per_slab, ibg) + i = @index(Global, Linear) + + @unroll for j in 1:size(ibg, 2) + @unroll for k in 1:size(ibg, 3) + @inbounds load_per_slab[i] += ifelse(immersed_cell(i, j, k, ibg), 0, 1) + end + end +end + +function calculate_local_size(load_per_slab, N, ranks) + active_cells = sum(load_per_slab) + active_load = active_cells / ranks + local_N = zeros(Int, ranks) # fill the local N with the active load + idx = 1 + for r in 1:ranks-1 + local_load = 0 + while local_load <= active_load + local_load += load_per_slab[idx] + local_N[r] += 1 + idx += 1 + end + end + + local_N[end] = N - sum(local_N[1:end-1]) + + return local_N +end + +function redistribute_size_to_fulfill_memory_limitation!(l, m = 700) + n = length(l) + while any(l .> m) + x⁺, i⁺ = findmax(l) + x⁻, i⁻ = findmin(l) + if x⁺ == m + 1 + l[i⁺] -= 1 + l[i⁻] += 1 + else + Δ = l[i⁺] - m + q = Δ ÷ n + l .+= q + l[i⁺] -= Δ + l[i⁻] += mod(Δ, n) + end + end + while any(l .< 20) + x⁺, i⁺ = findmax(l) + x⁻, i⁻ = findmin(l) + if x⁻ == 19 + l[i⁻] += 1 + l[i⁺] -= 1 + else + Δ = 20 - l[i⁻] + q = Δ ÷ n + l .-= q + l[i⁺] -= mod(Δ, n) + l[i⁻] += Δ + end + end +end diff --git a/src/VerticalGrids.jl b/src/VerticalGrids.jl index 220d791c..5e7cde30 100644 --- a/src/VerticalGrids.jl +++ b/src/VerticalGrids.jl @@ -75,6 +75,21 @@ function stretched_vertical_faces(; surface_layer_Δz = 5.0, return z end +@inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) + +function exponential_z_faces(Nz, Depth; h = Nz / 4.5) + + z_faces = exponential_profile.((1:Nz+1); Lz = Nz, h) + + # Normalize + z_faces .-= z_faces[1] + z_faces .*= - Depth / z_faces[end] + + z_faces[1] = 0.0 + + return reverse(z_faces) +end + # Vertical grid with 49 levels. # Stretched from 10 meters spacing at surface # to 400 meter at the bottom. From 86565bce17c0ab744fd3432c5b5bcf23ae3fcaf8 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 26 Feb 2024 10:53:13 -0700 Subject: [PATCH 204/716] 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 38a76506907018ca461f4f78c7ffa7505fa3227b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 26 Feb 2024 12:57:22 -0500 Subject: [PATCH 205/716] load balanced grid --- .../load_balanced_ocean_grid.jl | 101 ++++++++++++------ 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index 76e4a5d7..83e30672 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -3,13 +3,42 @@ using Oceananigans.DistributedComputations: Sizes using Oceananigans.ImmersedBoundaries: immersed_cell using KernelAbstractions: @index, @kernel -function LoadBalancedOceanGrid(arch; - size, - latitude, - longitude, - z, - halo = (3, 3, 3), - kw...) +""" + LoadBalancedOceanGrid(arch; size, latitude, longitude, z, halo, maximum_size, height_above_water, minimum_depth, interpolation_passes) + +Constructs a LatitudeLongitudeGrid with an ocean bathymetry interpolated from ETOPO1. +If the architecture is `Distributed` and the partition is only in one direction, the partition will be +calculated to maintain an equal number of active cells across different workers. + +# Positional Arguments +====================== +- `arch`: The architecture of the ocean grid. + +# Keyword Arguments +=================== +- `size`: The size of the grid. +- `latitude`: The latitude of the grid. +- `longitude`: The longitude of the grid. +- `z`: The z-faces of the grid. +- `halo`: The halo size of the grid. Default is `(3, 3, 3)`. +- `maximum_size`: The maximum size in the partitioned direction. Default is `1150`. +- `height_above_water`: The height above water level. Default is `1`. +- `minimum_depth`: The minimum depth of the bathymetry. Default is `10`. +- `interpolation_passes`: The number of interpolation passes. Default is `1`. + +# Returns +- `grid`: The load-balanced ocean grid. +""" +function load_balanced_regional_grid(arch; + size, + latitude, + longitude, + z, + halo = (3, 3, 3) + maximum_size = 1150, + height_above_water = 1, + minimum_depth = 10, + interpolation_passes = 1) child_arch = child_architecture(arch) @@ -21,38 +50,44 @@ function LoadBalancedOceanGrid(arch; halo) bottom_height = regrid_bathymetry(grid, - height_above_water = 1, - minimum_depth = 10, - interpolation_passes = 25) + height_above_water, + minimum_depth, + interpolation_passes) return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end -function LoadBalancedOceanGrid(arch::Distributed; - size, - latitude, - longitude, - z, - halo = (3, 3, 3), - maximum_Nx = 1150) - +XPartition = Partition{<:} + +# Load balancing works only for 1D partitions! +function load_balanced_regional_grid(arch::Distributed; + size, + latitude, + longitude, + z, + halo = (3, 3, 3), + maximum_size = 1150, + height_above_water = 1, + minimum_depth = 10, + interpolation_passes = 1) + child_arch = child_architecture(arch) # Global grid - grid = LatitudeLongitudeGrid(child_arch; - size, - longitude, - latitude, - z, - halo) - - bottom_height = regrid_bathymetry(grid, - height_above_water = 1, - minimum_depth = 10, - interpolation_passes = 25) - - grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - + grid = load_balanced_regional_grid(child_arch; + size, + longitude, + latitude, + z, + halo, + maximum_size, + height_above_water, + minimum_depth, + interpolation_passes) + + bottom_height = grid.immersed_boundary.bottom_height + + if arch.partition # Starting with the load balancing load_per_x_slab = arch_array(child_arch, zeros(Int, size[1])) loop! = assess_x_load(device(child_arch), 512, size[1]) @@ -63,7 +98,7 @@ function LoadBalancedOceanGrid(arch::Distributed; # We cannot have Nx > 650 if Nranks = 32 otherwise we incur in memory limitations, # so for a small number of GPUs we are limited in the load balancing - redistribute_size_to_fulfill_memory_limitation!(local_Nx, maximum_Nx) + redistribute_size_to_fulfill_memory_limitation!(local_Nx, maximum_size) arch = Distributed(child_arch, partition = Partition(x = Sizes(local_Nx...))) zonal_rank = arch.local_index[1] From cf2beaab1621419d61e33a3d2396d8a175dddcbd Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 26 Feb 2024 11:30:25 -0700 Subject: [PATCH 206/716] Change name to inpaint_mask and update ECCO2 initialization --- src/DataWrangling/DataWrangling.jl | 2 +- src/DataWrangling/ECCO2.jl | 70 ++++++------- src/DataWrangling/fill_missing_values.jl | 107 ------------------- src/DataWrangling/inpaint_mask.jl | 126 +++++++++++++++++++++++ 4 files changed, 159 insertions(+), 146 deletions(-) delete mode 100644 src/DataWrangling/fill_missing_values.jl create mode 100644 src/DataWrangling/inpaint_mask.jl diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index 67c6e4f7..fb2a5b4a 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -108,7 +108,7 @@ function save_field_time_series!(fts; path, name, overwrite_existing=false) return nothing end -include("fill_missing_values.jl") +include("inpaint_mask.jl") include("JRA55.jl") include("ECCO2.jl") diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 2c924c8b..b2c2ca2b 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -2,7 +2,7 @@ module ECCO2 export ECCO2Metadata, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! -using ClimaOcean.DataWrangling: fill_missing_values! +using ClimaOcean.DataWrangling: inpaint_mask! using ClimaOcean.InitialConditions: three_dimensional_regrid! using Oceananigans @@ -27,12 +27,6 @@ ECCO2Metadata(name::Symbol) = ECCO2Metadata(name, 1992, 1, 2) filename(data::ECCO2Metadata) = "ecco2_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).nc" -ecco2_tracer_fields = Dict( - :ecco2_temperature => :temperature, - :ecco2_salinity => :salinity, - :ecco_2_effective_ice_thickness => :effective_ice_thickness -) - ecco2_short_names = Dict( :temperature => "THETA", :salinity => "SALT", @@ -90,8 +84,9 @@ function construct_vertical_interfaces(ds, depth_name) return zf end -function empty_ecco2_field(data::ECCO2Metadata; architecture = CPU(), - horizontal_halo = (1, 1)) +function empty_ecco2_field(data::ECCO2Metadata; + architecture = CPU(), + horizontal_halo = (1, 1)) variable_name = data.name @@ -183,7 +178,7 @@ end @kernel function _set_ecco2_mask!(mask, Tᵢ, minimum_value) i, j, k = @index(Global, NTuple) - @inbounds mask[i, j, k] = ifelse(Tᵢ[i, j, k] < minimum_value, 0, 1) + @inbounds mask[i, j, k] = Tᵢ[i, j, k] < minimum_value end """ @@ -194,7 +189,7 @@ dataset and 1 represents a valid value """ function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) Tᵢ = ecco2_field(:temperature; architecture) - mask = CenterField(Tᵢ.grid) + mask = CenterField(Tᵢ.grid, Bool) # Set the mask with ones where T is defined launch!(architecture, Tᵢ.grid, :xyz, _set_ecco2_mask!, mask, Tᵢ, minimum_value) @@ -203,41 +198,42 @@ function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) end """ - adjusted_ecco_field(variable_name; - architecture = CPU(), - filename = "./data/initial_ecco_tracers.nc", - mask = ecco2_center_mask(architecture)) + inpainted_ecco2_field(variable_name; + architecture = CPU(), + filename = "./inpainted_ecco2_fields.nc", + mask = ecco2_center_mask(architecture)) -Retrieve the ECCO2 field corresponding to `variable_name` adjusted to fill all the -missing values in the original dataset +Retrieve the ECCO2 field corresponding to `variable_name` inpainted to fill all the +missing values in the original dataset. Arguments: ========== -- `variable_name`: the variable name corresponding to the Dataset +- `variable_name`: the variable name corresponding to the Dataset. Keyword Arguments: ================== -- `architecture`: either `CPU()` or `GPU()` +- `architecture`: either `CPU()` or `GPU()`. - `filename`: the path where to retrieve the data from. If the file does not exist, - the data will be retrived from the ECCO2 dataset, it will be adjusted and - saved down in `filename` + the data will be retrived from the ECCO2 dataset, inpainted, and + saved to `filename`. -- `mask`: the mask used to extend the field (see `adjust_tracer!`) +- `mask`: the mask used to extend the field (see `adjust_tracer!`). """ -function adjusted_ecco2_field(variable_name; - architecture = CPU(), - filename = "./data/adjusted_ecco_tracers.nc", - mask = ecco2_center_mask(architecture)) +function inpainted_ecco2_field(variable_name; + architecture = CPU(), + filename = "./inpainted_ecco2_fields.nc", + mask = ecco2_center_mask(architecture), + kw...) if !isfile(filename) f = ecco2_field(variable_name; architecture) # Make sure all values are extended properly - @info "in-painting ecco field $variable_name and saving it in $filename" - fill_missing_values!(f; mask) + @info "In-painting ecco field $variable_name and saving it in $filename" + inpaint_mask!(f, mask; kw...) ds = Dataset(filename, "c") defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) @@ -251,9 +247,9 @@ function adjusted_ecco2_field(variable_name; f = ecco2_field(variable_name; architecture, user_data = data) else f = ecco2_field(variable_name; architecture) - # Make sure all values are extended properly - @info "in-painting ecco field $variable_name and saving it in $filename" - fill_missing_values!(f; mask) + # Make sure all values are inpainted properly + @info "In-painting ecco field $variable_name and saving it in $filename" + inpaint_mask!(f, mask; kw...) defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) end @@ -264,21 +260,19 @@ function adjusted_ecco2_field(variable_name; return f end -function set!(field::Field, ecco2::ECCO2Metadata; filename = "./data/adjusted_ecco_tracers.nc") +function set!(field::Field, ecco2_metadata::ECCO2Metadata; filename="./inpainted_ecco2_fields.nc", kw...) + # Fields initialized from ECCO2 grid = field.grid mask = ecco2_center_mask(architecture(grid)) - f = adjusted_ecco2_field(ecco2.name; - architecture = architecture(grid), - filename, - mask) + f = inpainted_ecco2_field(ecco2.name; filename, mask, + architecture = architecture(grid), + kw...) f_grid = Field(ecco2_location[ecco2.name], grid) - three_dimensional_regrid!(f_grid, f) - set!(field, f_grid) return field diff --git a/src/DataWrangling/fill_missing_values.jl b/src/DataWrangling/fill_missing_values.jl deleted file mode 100644 index 591a5298..00000000 --- a/src/DataWrangling/fill_missing_values.jl +++ /dev/null @@ -1,107 +0,0 @@ -using Oceananigans -using Oceananigans.BoundaryConditions -using Oceananigans.Fields: OneField -using Oceananigans.Grids: peripheral_node -using Oceananigans.Utils: launch! -using Oceananigans.Fields: instantiated_location, interior, CenterField -using Oceananigans.Architectures: architecture, device, GPU - -using KernelAbstractions: @kernel, @index -using KernelAbstractions.Extras.LoopInfo: @unroll - -# Maybe we can remove this propagate field in lieu of a diffusion, -# Still we'll need to do this a couple of steps on the original grid -@kernel function _propagate_field!(field, tmp_field) - i, j, k = @index(Global, NTuple) - - @inbounds begin - nw = field[i - 1, j, k] - ns = field[i, j - 1, k] - ne = field[i + 1, j, k] - nn = field[i, j + 1, k] - nb = (nw, ne, nn, ns) - - counter = 0 - cumsum = 0.0 - - @unroll for n in nb - counter += ifelse(isnan(n), 0, 1) - cumsum += ifelse(isnan(n), 0, n) - end - - tmp_field[i, j, k] = ifelse(cumsum == 0, NaN, cumsum / counter) - end -end - -@kernel function _substitute_values!(field, tmp_field) - i, j, k = @index(Global, NTuple) - @inbounds substitute = isnan(field[i, j, k]) - @inbounds field[i, j, k] = ifelse(substitute, tmp_field[i, j, k], field[i, j, k]) -end - -@kernel function _nans_outside_mask!(field, mask) - i, j, k = @index(Global, NTuple) - @inbounds field[i, j, k] = ifelse(mask[i, j, k] == 0, NaN, field[i, j, k]) -end - -propagate_horizontally!(field, ::Nothing; kw...) = nothing - -""" - propagate_horizontally!(field, mask; max_iter = Inf) - -propagate horizontally a field with missing values outside of a `mask`. -Grid cells where `mask == 1` will be preserved -""" -function propagate_horizontally!(field, mask; max_iter = Inf) - iter = 0 - grid = field.grid - arch = architecture(grid) - - launch!(arch, grid, :xyz, _nans_outside_mask!, field, mask) - fill_halo_regions!(field) - - tmp_field = deepcopy(field) - - while isnan(sum(interior(field))) && iter < max_iter - launch!(arch, grid, :xyz, _propagate_field!, field, tmp_field) - launch!(arch, grid, :xyz, _substitute_values!, field, tmp_field) - iter += 1 - @debug "propagate pass $iter with sum $(sum(parent(field)))" - end - - return nothing -end - -continue_downwards!(field, ::Nothing) = nothing - -""" - continue_downwards!(field, mask) - -continue downwards a field with missing values outside of a `mask`. -Grid cells where `mask == 1` will be preserved -""" -function continue_downwards!(field, mask) - arch = architecture(field) - grid = field.grid - launch!(arch, grid, :xy, _continue_downwards!, field, grid, mask) - return nothing -end - -@kernel function _continue_downwards!(field, grid, mask) - i, j = @index(Global, NTuple) - - Nz = grid.Nz - - @unroll for k = Nz-1 : -1 : 1 - @inbounds fill_from_above = mask[i, j, k] == 0 - @inbounds field[i, j, k] = ifelse(fill_from_above, field[i, j, k+1], field[i, j, k]) - end -end - -function fill_missing_values!(tracer; mask = nothing, max_iter = Inf) - - continue_downwards!(tracer, mask) - propagate_horizontally!(tracer, mask; max_iter) - - return tracer -end \ No newline at end of file diff --git a/src/DataWrangling/inpaint_mask.jl b/src/DataWrangling/inpaint_mask.jl new file mode 100644 index 00000000..65d03890 --- /dev/null +++ b/src/DataWrangling/inpaint_mask.jl @@ -0,0 +1,126 @@ +using Oceananigans +using Oceananigans.BoundaryConditions +using Oceananigans.Fields: OneField +using Oceananigans.Grids: peripheral_node +using Oceananigans.Utils: launch! +using Oceananigans.Fields: instantiated_location, interior, CenterField +using Oceananigans.Architectures: architecture, device, GPU + +using KernelAbstractions: @kernel, @index +using KernelAbstractions.Extras.LoopInfo: @unroll + +# Maybe we can remove this propagate field in lieu of a diffusion, +# Still we'll need to do this a couple of steps on the original grid +@kernel function _propagate_field!(field, tmp_field) + i, j, k = @index(Global, NTuple) + + @inbounds begin + nw = field[i - 1, j, k] + ns = field[i, j - 1, k] + ne = field[i + 1, j, k] + nn = field[i, j + 1, k] + nb = (nw, ne, nn, ns) + end + + counter = 0 + cumsum = zero(eltype(field)) + + @unroll for n in nb + counter += ifelse(isnan(n), 0, 1) + cumsum += ifelse(isnan(n), 0, n) + end + + @inbounds tmp_field[i, j, k] = ifelse(cumsum == 0, NaN, cumsum / counter) +end + +@kernel function _substitute_values!(field, tmp_field) + i, j, k = @index(Global, NTuple) + @inbounds needs_inpainting = isnan(field[i, j, k]) + @inbounds field[i, j, k] = ifelse(needs_inpainting, tmp_field[i, j, k], field[i, j, k]) +end + +@kernel function _nan_mask!(field, mask) + i, j, k = @index(Global, NTuple) + @inbounds field[i, j, k] = ifelse(mask[i, j, k], NaN, field[i, j, k]) +end + +propagate_horizontally!(field, ::Nothing, tmp_field=deepcopy(field); kw...) = field + +function propagating(field, mask, iter, max_iter) + mask_sum = sum(field; condition=mask) + return isnan(mask_sum) && iter < max_iter +end + +""" + propagate_horizontally!(field, mask [, tmp_field=deepcopy(field)]; max_iter = Inf) + +Horizontally propagate the values of `field` into the `mask`. +In other words, cells where `mask[i, j, k] == false` are preserved, +and cells where `mask[i, j, k] == true` are painted over. +""" +function propagate_horizontally!(field, mask, tmp_field=deepcopy(field); max_iter = Inf) + iter = 0 + grid = field.grid + arch = architecture(grid) + + launch!(arch, grid, :xyz, _nan_mask!, field, mask) + fill_halo_regions!(field) + + # Need temporary field to avoid a race condition + parent(tmp_field) .= parent(field) + + while propagating(field, mask, iter, max_iter) + launch!(arch, grid, :xyz, _propagate_field!, field, tmp_field) + launch!(arch, grid, :xyz, _substitute_values!, field, tmp_field) + iter += 1 + @debug "Propagate pass $iter with sum $(sum(parent(field)))" + end + + return field +end + +continue_downwards!(field, ::Nothing) = field + +""" + continue_downwards!(field, mask) + +Continue downwards a field with missing values within `mask`. +Cells where `mask[i, k, k] == false` will be preserved. +""" +function continue_downwards!(field, mask) + arch = architecture(field) + grid = field.grid + launch!(arch, grid, :xy, _continue_downwards!, field, grid, mask) + return field +end + +@kernel function _continue_downwards!(field, grid, mask) + i, j = @index(Global, NTuple) + Nz = size(grid, 3) + + @unroll for k = Nz-1 : -1 : 1 + @inbounds field[i, j, k] = ifelse(mask[i, j, k], field[i, j, k+1], field[i, j, k]) + end +end + +""" + inpaint_mask!(field, mask; max_iter = Inf) + +Inpaint field within `mask`, using values outside `mask`. +In other words, regions where `mask[i, j, k] == 1` will be inpainted +and regions where `mask[i, j, k] == 0` will be preserved. + +Arguments +========= + - `field`: `Field` to be inpainted. + - `mask`: Boolean-valued `Field`, values where + `mask[i, j, k] == true` are inpainted. + - `max_iter`: Maximum iterations for inpainting. Non-Inf values mean that + NaN's can occur within the mask. +""" +function inpaint_mask!(field, mask; max_iter = Inf) + continue_downwards!(field, mask) + propagate_horizontally!(field, mask; max_iter) + return field +end + From 4cc11de05c7c89e9ffd505ae09341f8cc7e64a11 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 08:55:12 -0500 Subject: [PATCH 207/716] update Oceananigans --- Manifest.toml | 346 ++++++++++++++++++++++++++-------------------- src/ClimaOcean.jl | 1 - 2 files changed, 194 insertions(+), 153 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 79be6308..51fede95 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" +julia_version = "1.10.1" manifest_format = "2.0" project_hash = "b0de2c0b9b63c5f2aa2406aac544be6c8761c819" @@ -20,9 +20,9 @@ version = "1.5.0" [[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] @@ -34,9 +34,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "16267cf279190ca7c1b30d020758ced95db89cd0" +git-tree-sha1 = "c5aeb516a84459e0318a02507d2261edad97eb75" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.5.1" +version = "7.7.1" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -73,20 +73,20 @@ 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"] -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"] @@ -95,38 +95,42 @@ uuid = "179af706-886a-5703-950a-314cd64e0468" version = "0.1.2" [[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 = "95ac638373ac40e29c1b6d086a3698f5026ff6a6" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.0.0" -weakdeps = ["SpecialFunctions"] +version = "5.1.2" [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" SpecialFunctionsExt = "SpecialFunctions" + [deps.CUDA.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "2f64185414751a5f878c4ab616c0edd94ade3419" +git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.6.0+4" +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"] -git-tree-sha1 = "a38bc81bd6fdc7334de537aec3ae60e7b098daa2" +git-tree-sha1 = "9704e50c9158cf8896c2776b8dbc5edd136caf80" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.9.2+4" +version = "0.10.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"] @@ -147,10 +151,10 @@ uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" version = "0.2.5" [[deps.Compat]] -deps = ["UUIDs"] -git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.10.0" +version = "4.14.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -159,13 +163,13 @@ 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.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" +git-tree-sha1 = "9c4708e3ed2b799e6124b5673a712dda0b596a9b" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.3.0" +version = "2.3.1" [[deps.ConstructionBase]] deps = ["LinearAlgebra"] @@ -188,9 +192,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"] @@ -199,15 +203,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 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.11" +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"] @@ -217,9 +221,9 @@ version = "1.6.1" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" +git-tree-sha1 = "1fb174f0d48fe7d142e1109a10636bc1d14f5ac2" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.15" +version = "0.18.17" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -231,16 +235,16 @@ deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[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"] -git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.10" +version = "0.10.11" [deps.Distances.extensions] DistancesChainRulesCoreExt = "ChainRulesCore" @@ -272,9 +276,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" @@ -283,9 +287,9 @@ version = "0.1.10" [[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"] @@ -295,9 +299,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" @@ -326,9 +330,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.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" @@ -343,15 +347,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 = "ac7b73d562b8f4287c3b67b4c66a5395a19c1ae8" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.0" +version = "1.10.2" [[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" @@ -371,10 +375,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"] @@ -392,9 +396,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" @@ -403,9 +407,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Printf", "Reexport", "Requires", "TranscodingStreams", "UUIDs"] -git-tree-sha1 = "ebec83429b5dea3857e071d927156207ebd6d617" +git-tree-sha1 = "5ea6acdd53a51d897672edb694e3cc2912f3f8a7" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.37" +version = "0.4.46" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -415,9 +419,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"] @@ -427,9 +437,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 = "4e0cb2f5aad44dcfdc91088e85dee4ecb22c791c" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.10" +version = "0.9.16" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -439,9 +449,9 @@ version = "0.9.10" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "c879e47398a7ab671c782e02b51a4456794a7fa3" +git-tree-sha1 = "ddab4d40513bce53c8e3157825e245224f74fae7" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.4.0" +version = "6.6.0" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -449,15 +459,29 @@ weakdeps = ["BFloat16s"] [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "a84f8f1e8caaaa4e3b4c101306b9e801d3883ace" +git-tree-sha1 = "88b916503aac4fb7f701bb625cd84ca5dd1677bc" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.27+0" +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", "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.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" @@ -507,9 +531,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" @@ -531,10 +555,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"] @@ -551,38 +575,38 @@ 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 = "8a5b4d2220377d1ece13f49438d71ad20cf1ba83" +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+0" +version = "4.2.0+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"] -git-tree-sha1 = "6979eccb6a9edbbb62681e158443e79ecc0d056a" +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+0" +version = "5.3.2+0" [[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.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[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 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.7" +version = "1.1.9" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] @@ -591,9 +615,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"] @@ -610,15 +634,15 @@ 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"] -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"] @@ -638,28 +662,31 @@ 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" +git-tree-sha1 = "07916f6709a079df919f4eb16740977fda333bb8" +repo-rev = "main" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.5" +version = "0.90.8" [deps.Oceananigans.extensions] - OceananigansEnzymeCoreExt = "EnzymeCore" + OceananigansEnzymeExt = "Enzyme" [deps.Oceananigans.weakdeps] - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" [[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"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.23+2" +version = "0.3.23+4" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] @@ -668,9 +695,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 = "f46caf663e069027a06942d00dced37f1eb3d8ad" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.0+0" +version = "5.0.2+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] @@ -680,9 +707,9 @@ version = "1.4.1" [[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"] @@ -691,9 +718,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"] @@ -709,15 +736,15 @@ weakdeps = ["Requires", "TOML"] [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851" +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.7.2" +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"] @@ -763,10 +790,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"] @@ -780,9 +807,9 @@ version = "1.5.1" [[deps.Quaternions]] deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "da095158bdc8eaccb7890f9884048555ab771019" +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.4" +version = "0.7.6" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] @@ -794,9 +821,9 @@ uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[deps.Random123]] deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "552f30e847641591ba3f39fd1bed559b9deb0ef3" +git-tree-sha1 = "4743b43e5a9c4a2ede372de7061eed81795b12e7" uuid = "74087812-796a-5b5d-8853-05524746bad3" -version = "1.6.1" +version = "1.7.0" [[deps.RandomNumbers]] deps = ["Random", "Requires"] @@ -829,9 +856,13 @@ version = "1.3.0" [[deps.Rotations]] deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "0783924e4a332493f72490253ba4e668aeba1d73" +git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.6.0" +version = "1.7.0" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" @@ -844,15 +875,15 @@ uuid = "6c6a2e73-6563-6170-7368-637461726353" version = "1.2.1" [[deps.SeawaterPolynomials]] -git-tree-sha1 = "958ba75b90c7c8a117d041d33184134201cf8c0f" +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" -version = "0.3.2" +version = "0.3.4" [[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" @@ -867,9 +898,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"] @@ -890,15 +921,15 @@ version = "2.3.1" [[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"] -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] @@ -906,15 +937,19 @@ weakdeps = ["OffsetArrays", "StaticArrays"] StaticArrayInterfaceStaticArraysExt = "StaticArrays" [[deps.StaticArrays]] -deps = ["LinearAlgebra", "Random", "StaticArraysCore"] -git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.6.5" -weakdeps = ["Statistics"] +version = "1.9.3" [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" StaticArraysStatisticsExt = "Statistics" + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + [[deps.StaticArraysCore]] git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" @@ -944,9 +979,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] @@ -959,10 +994,17 @@ uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" version = "0.3.4" [[deps.StructArrays]] -deps = ["Adapt", "ConstructionBase", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "0a3db38e4cce3c54fe7a71f831cd7b6194a54213" +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.16" +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"] @@ -1003,9 +1045,9 @@ version = "1.10.0" [[deps.TaylorSeries]] deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] -git-tree-sha1 = "50718b4fc1ce20cecf28d85215028c78b4d875c2" +git-tree-sha1 = "1c7170668366821b0c4c4fe03ee78f8d6cf36e2c" uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.15.2" +version = "0.16.0" [deps.TaylorSeries.extensions] TaylorSeriesIAExt = "IntervalArithmetic" @@ -1024,18 +1066,18 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.23" [[deps.TranscodingStreams]] -git-tree-sha1 = "49cbf7c74fafaed4c529d47d48c8f7da6a19eb75" +git-tree-sha1 = "54194d92959d8ebaa8e26227dbe3cdefcdcd594f" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.1" +version = "0.10.3" 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" @@ -1067,9 +1109,9 @@ version = "1.3.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "24b81b59bd35b3c42ab84fa589086e19be919916" +git-tree-sha1 = "07e470dabc5a6a4254ffebc29a1b3fc01464e105" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.11.5+0" +version = "2.12.5+0" [[deps.Zlib_jll]] deps = ["Libdl"] diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 21913645..61b51ce7 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -10,7 +10,6 @@ export initialize! using Oceananigans using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ using DataDeps -using CubicSplines function __init__(; remove_existing_data=false) From 8f7e2eaa3842ab01845e08122a0c5478c8a7b653 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 10:41:30 -0500 Subject: [PATCH 208/716] change some docstrings --- src/DataWrangling/ECCO2.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index b2c2ca2b..4cc41ff4 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -132,10 +132,11 @@ end filename = ecco2_file_names[variable_name], short_name = ecco2_short_names[variable_name]) -Retrieve the ecco2 field corresponding to `variable_name`. The data is either: -(1) retrieved from `filename` -(2) dowloaded from `url` if `filename` does not exists -(3) filled from `user_data` if `user_data` is provided +Retrieve the ecco2 field corresponding to `variable_name`. +The data is either: +(1) retrieved from `filename`, +(2) dowloaded from `url` if `filename` does not exists, +(3) filled from `user_data` if `user_data` is provided. """ function ecco2_field(variable_name; architecture = CPU(), @@ -184,8 +185,7 @@ end """ ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) -An integer field where 0 represents a missing value in the ECCO2 :temperature -dataset and 1 represents a valid value +A boolean field where `false` represents a missing value in the ECCO2 :temperature dataset. """ function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) Tᵢ = ecco2_field(:temperature; architecture) @@ -220,7 +220,7 @@ Keyword Arguments: the data will be retrived from the ECCO2 dataset, inpainted, and saved to `filename`. -- `mask`: the mask used to extend the field (see `adjust_tracer!`). +- `mask`: the mask used to inpaint the field (see `inpaint_mask!`). """ function inpainted_ecco2_field(variable_name; architecture = CPU(), From 32349420ec18a0560d1687a73aec42ccc734edc4 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Tue, 27 Feb 2024 17:48:30 +0200 Subject: [PATCH 209/716] include submodules in docs + don't error when missing_docs --- docs/make.jl | 15 ++++++++------- docs/src/library/internals.md | 28 ++++++++++++++++++++++++++++ docs/src/library/public.md | 29 +++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 99949e72..9724e318 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -45,13 +45,14 @@ pages = [ ] makedocs( - sitename = "ClimaOcean.jl", - modules = [ClimaOcean], - format = format, - pages = pages, - doctest = true, - clean = true, - checkdocs = :exports + sitename = "ClimaOcean.jl", + modules = [ClimaOcean], + format = format, + pages = pages, + doctest = true, + clean = true, + warnonly = [:cross_references, :missing_docs], + checkdocs = :exports ) @info "Clean up temporary .jld2 and .nc output created by doctests or literated examples..." diff --git a/docs/src/library/internals.md b/docs/src/library/internals.md index 920f347b..173ade94 100644 --- a/docs/src/library/internals.md +++ b/docs/src/library/internals.md @@ -16,3 +16,31 @@ Modules = [ClimaOcean.Diagnostics] Public = false ``` + +## InitialConditions + +```@autodocs +Modules = [ClimaOcean.InitialConditions] +Public = false +``` + +## DataWrangling + +```@autodocs +Modules = [ClimaOcean.DataWrangling] +Public = false +``` + +## ECCO2 + +```@autodocs +Modules = [ClimaOcean.ECCO2] +Public = false +``` + +## Bathymetry + +```@autodocs +Modules = [ClimaOcean.Bathymetry] +Public = false +``` diff --git a/docs/src/library/public.md b/docs/src/library/public.md index 3ba1c84e..65a7fed6 100644 --- a/docs/src/library/public.md +++ b/docs/src/library/public.md @@ -17,3 +17,32 @@ Private = false Modules = [ClimaOcean.Diagnostics] Private = false ``` + +## InitialConditions + +```@autodocs +Modules = [ClimaOcean.InitialConditions] +Private = false +``` + +## DataWrangling + +```@autodocs +Modules = [ClimaOcean.DataWrangling] +Private = false +``` + +## ECCO2 + +```@autodocs +Modules = [ClimaOcean.ECCO2] +Private = false +``` + +## Bathymetry + +```@autodocs +Modules = [ClimaOcean.Bathymetry] +Private = false +``` + From 6f08f782de5f5c20f12c0a6c0dc6fc1c4157711b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 14:51:03 -0500 Subject: [PATCH 210/716] bugfix --- src/DataWrangling/ECCO2.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 4cc41ff4..ea74c358 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -264,14 +264,15 @@ function set!(field::Field, ecco2_metadata::ECCO2Metadata; filename="./inpainted # Fields initialized from ECCO2 grid = field.grid + name = ecco2_metadata.name mask = ecco2_center_mask(architecture(grid)) - f = inpainted_ecco2_field(ecco2.name; filename, mask, + f = inpainted_ecco2_field(name; filename, mask, architecture = architecture(grid), kw...) - f_grid = Field(ecco2_location[ecco2.name], grid) + f_grid = Field(ecco2_location[name], grid) three_dimensional_regrid!(f_grid, f) set!(field, f_grid) From 96f058e6ec9a0a8cb2cdf9a8cdabc201dbaf1e6c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 21:22:41 -0500 Subject: [PATCH 211/716] continue --- Manifest.toml | 90 +++++++++++++++++----------- experiments/twelth_degree_latlong.jl | 29 +++++---- 2 files changed, 71 insertions(+), 48 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index d5f1c48a..e9e054d3 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -110,26 +110,17 @@ git-tree-sha1 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" uuid = "179af706-886a-5703-950a-314cd64e0468" version = "0.1.2" -[[deps.CLIMAParameters]] -deps = ["DocStringExtensions", "TOML", "Test"] -git-tree-sha1 = "0c8c49ca2b7992490ab2a5292ed23aeae8b0768f" -uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" -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"] 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.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" @@ -148,6 +139,24 @@ git-tree-sha1 = "9704e50c9158cf8896c2776b8dbc5edd136caf80" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" version = "0.10.1+0" +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "aef70bb349b20aa81a82a19704c3ef339d4ee494" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.22.1" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" +repo-rev = "main" +repo-url = "git@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" @@ -198,6 +207,15 @@ deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.1.0+0" +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] git-tree-sha1 = "9c4708e3ed2b799e6124b5673a712dda0b596a9b" @@ -253,10 +271,10 @@ uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" version = "1.5.0" [[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "1fb174f0d48fe7d142e1109a10636bc1d14f5ac2" +deps = ["InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "88d48e133e6d3dd68183309877eac74393daa7eb" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.17" +version = "0.17.20" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -290,6 +308,7 @@ 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" @@ -494,9 +513,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 = "c7753cc3febe006708ce6798482004241f7d890b" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.16" +version = "0.9.17" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -726,8 +745,6 @@ 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 = "07916f6709a079df919f4eb16740977fda333bb8" -repo-rev = "main" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.8" @@ -919,15 +936,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 = "754acd3031a9f2eaf6632ba4850b1c01fe4460c1" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.1.0" +version = "2.1.2" [deps.Roots.extensions] RootsForwardDiffExt = "ForwardDiff" @@ -1032,15 +1049,12 @@ deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" uuid = "90137ffa-7385-5640-81b9-e52037218182" version = "1.9.3" +weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] StaticArraysChainRulesCoreExt = "ChainRulesCore" StaticArraysStatisticsExt = "Statistics" - [deps.StaticArrays.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - [[deps.StaticArraysCore]] git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" @@ -1113,12 +1127,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"] @@ -1160,16 +1180,16 @@ 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 = "9c9ccbdb2ecb490fc69a0392c98766dcc2024eae" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.11.5" -weakdeps = ["CLIMAParameters"] +version = "0.12.3" [deps.Thermodynamics.extensions] CreateParametersExt = "CLIMAParameters" + [deps.Thermodynamics.weakdeps] + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" @@ -1237,9 +1257,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"] diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 51c7380f..ccf9effc 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -17,18 +17,18 @@ using Printf # 100 vertical levels z_faces = exponential_z_faces(100, 6000) -Nx = 4320 -Ny = 1800 +Nx = 360 +Ny = 150 Nz = length(z_faces) - 1 -arch = Distributed(GPU(), partition = Partition(8)) +arch = Distributed(CPU(), partition = Partition(8)) -grid = LoadBalancedOceanGrid(arch; - size = (Nx, Ny, Nz), - z = z_faces, - latitude = (-75, 75), - longitude = (0, 360), - halo = (7, 7, 7)) +@show grid = load_balanced_regional_grid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + latitude = (-75, 75), + longitude = (0, 360), + halo = (7, 7, 7)) ##### ##### The Ocean component @@ -39,17 +39,20 @@ simulation = ocean_simulation(grid) model = simulation.model # Initializing the model -set!(model, T = ECCO2Metadata(:temperature), S = ECCO2Metadata(:salinity), e = 1e-6) +set!(model, + T = ECCO2Metadata(:temperature), + S = ECCO2Metadata(:salinity), + e = 1e-6) ##### ##### The atmosphere ##### -backend = JRA55NetCDFBackend(8) # InMemory(8) -atmosphere = JRA55_prescribed_atmosphere(arch, 1:56; backend) +backend = JRA55NetCDFBackend(10) # InMemory(8) +atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation() -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) function progress(sim) u, v, w = sim.model.velocities From fc67ec1b3159b00d4c4d11e2b42ea16be7430c8f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:21:31 -0500 Subject: [PATCH 212/716] lets go! --- Manifest.toml | 52 +++++----- experiments/twelth_degree_latlong.jl | 7 +- src/Bathymetry.jl | 5 + src/ClimaOcean.jl | 2 + src/OceanSimulations/OceanSimulations.jl | 2 +- .../load_balanced_ocean_grid.jl | 96 +++++++++++-------- 6 files changed, 94 insertions(+), 70 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index e9e054d3..f2e08f4e 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -110,6 +110,12 @@ git-tree-sha1 = "ed2e76c1c3c43fd9d0cb9248674620b29d71f2d1" uuid = "179af706-886a-5703-950a-314cd64e0468" version = "0.1.2" +[[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" @@ -153,7 +159,7 @@ weakdeps = ["SparseArrays"] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" repo-rev = "main" -repo-url = "git@github.com:CliMA/ClimaSeaIce.jl.git" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" @@ -265,16 +271,16 @@ 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" +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 = "1fb174f0d48fe7d142e1109a10636bc1d14f5ac2" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.17.20" +version = "0.18.17" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -744,7 +750,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 = "07916f6709a079df919f4eb16740977fda333bb8" +git-tree-sha1 = "43edfa309bf97157c720de62290858614732eca0" +repo-rev = "main" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.90.8" @@ -997,12 +1005,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" @@ -1127,18 +1129,12 @@ uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.2.1+1" [[deps.SurfaceFluxes]] -deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "c2c43206af0d861e018f746286d1af036aa7bc3a" +deps = ["CLIMAParameters", "DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "3b54de787d5f07b56a34578174174c99dc30beda" 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" +version = "0.8.1" [[deps.TOML]] deps = ["Dates"] @@ -1180,16 +1176,16 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "9c9ccbdb2ecb490fc69a0392c98766dcc2024eae" +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.12.3" +version = "0.11.5" +weakdeps = ["CLIMAParameters"] [deps.Thermodynamics.extensions] CreateParametersExt = "CLIMAParameters" - [deps.Thermodynamics.weakdeps] - CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" - [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index ccf9effc..56f770a6 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -15,20 +15,21 @@ using Printf ##### # 100 vertical levels -z_faces = exponential_z_faces(100, 6000) +z_faces = exponential_z_faces(10, 6000) Nx = 360 Ny = 150 Nz = length(z_faces) - 1 -arch = Distributed(CPU(), partition = Partition(8)) +arch = Distributed(CPU(), partition = Partition(1)) @show grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), z = z_faces, latitude = (-75, 75), longitude = (0, 360), - halo = (7, 7, 7)) + halo = (7, 7, 7), + interpolation_passes = 25) ##### ##### The Ocean component diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index b38470a3..b276eb7e 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -93,6 +93,11 @@ function regrid_bathymetry(target_grid; λ_data = dataset["lon"][:] h_data = convert.(FT, dataset["z"][:, :]) + # Convert longitude to 0 - 360? + λ_data .+= 180 + nhx = size(h_data, 1) + h_data = circshift(h_data, (nhx ÷ 2, 1)) + close(dataset) # Diagnose target grid information diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 0da6574a..c424d72d 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -72,6 +72,7 @@ include("DataWrangling/DataWrangling.jl") include("Bathymetry.jl") include("Diagnostics.jl") include("NearGlobalSimulations/NearGlobalSimulations.jl") +include("OceanSimulations/OceanSimulations.jl") using .VerticalGrids using .Bathymetry @@ -79,6 +80,7 @@ using .DataWrangling: JRA55 using .DataWrangling: ECCO2 using .InitialConditions using .OceanSeaIceModels: OceanSeaIceModel +using .OceanSimulations end # module diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 0d6007f4..5b67278e 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -1,6 +1,6 @@ module OceanSimulations -export LoadBalancedOceanGrid, ocean_simulation +export load_balanced_regional_grid, ocean_simulation using Oceananigans.Advection: TracerAdvection diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index 83e30672..f1cf5543 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -1,12 +1,22 @@ +using ClimaOcean.Bathymetry +using Oceananigans using Oceananigans.DistributedComputations using Oceananigans.DistributedComputations: Sizes using Oceananigans.ImmersedBoundaries: immersed_cell using KernelAbstractions: @index, @kernel """ - LoadBalancedOceanGrid(arch; size, latitude, longitude, z, halo, maximum_size, height_above_water, minimum_depth, interpolation_passes) - -Constructs a LatitudeLongitudeGrid with an ocean bathymetry interpolated from ETOPO1. + load_balanced_regional_grid(arch; size, + latitude, + longitude, + z, + halo, + maximum_size, + height_above_water, + minimum_depth, + interpolation_passes) + +Construct a LatitudeLongitudeGrid with an ocean bathymetry interpolated from ETOPO1. If the architecture is `Distributed` and the partition is only in one direction, the partition will be calculated to maintain an equal number of active cells across different workers. @@ -21,7 +31,8 @@ calculated to maintain an equal number of active cells across different workers. - `longitude`: The longitude of the grid. - `z`: The z-faces of the grid. - `halo`: The halo size of the grid. Default is `(3, 3, 3)`. -- `maximum_size`: The maximum size in the partitioned direction. Default is `1150`. +- `maximum_size`: The maximum size in the partitioned direction. In `nothing` the load balanced direction + is not reduced. Default is `nothing`. - `height_above_water`: The height above water level. Default is `1`. - `minimum_depth`: The minimum depth of the bathymetry. Default is `10`. - `interpolation_passes`: The number of interpolation passes. Default is `1`. @@ -34,22 +45,20 @@ function load_balanced_regional_grid(arch; latitude, longitude, z, - halo = (3, 3, 3) - maximum_size = 1150, + halo = (3, 3, 3), + maximum_size = nothing, height_above_water = 1, minimum_depth = 10, interpolation_passes = 1) - - child_arch = child_architecture(arch) - grid = LatitudeLongitudeGrid(child_arch; + grid = LatitudeLongitudeGrid(arch; size, longitude, latitude, z, halo) - bottom_height = regrid_bathymetry(grid, + bottom_height = regrid_bathymetry(grid; height_above_water, minimum_depth, interpolation_passes) @@ -57,16 +66,19 @@ function load_balanced_regional_grid(arch; return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end -XPartition = Partition{<:} +const SlabPartition = Union{Partition{<:Any, <:Nothing, <:Nothing}, + Partition{<:Nothing, <:Any, <:Nothing}} + +const SlabDistributed = Distributed{<:Any, <:Any, <:SlabPartition} # Load balancing works only for 1D partitions! -function load_balanced_regional_grid(arch::Distributed; +function load_balanced_regional_grid(arch::SlabDistributed; size, latitude, longitude, z, halo = (3, 3, 3), - maximum_size = 1150, + maximum_size = nothing, height_above_water = 1, minimum_depth = 10, interpolation_passes = 1) @@ -87,40 +99,44 @@ function load_balanced_regional_grid(arch::Distributed; bottom_height = grid.immersed_boundary.bottom_height - if arch.partition + # index of the partitioned direction + idx = arch.ranks[1] == 1 ? 2 : 1 + # Starting with the load balancing - load_per_x_slab = arch_array(child_arch, zeros(Int, size[1])) - loop! = assess_x_load(device(child_arch), 512, size[1]) - loop!(load_per_x_slab, grid) + load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) + loop! = assess_load(device(child_arch), 512, size[idx]) + loop!(load_per_slab, grid, idx) - load_per_x_slab = arch_array(CPU(), load_per_x_slab) - local_Nx = calculate_local_size(load_per_x_slab, N[1], arch.ranks[1]) + load_per_slab = arch_array(CPU(), load_per_slab) + local_N = calculate_local_size(load_per_slab, N[idx], arch.ranks[idx]) - # We cannot have Nx > 650 if Nranks = 32 otherwise we incur in memory limitations, - # so for a small number of GPUs we are limited in the load balancing - redistribute_size_to_fulfill_memory_limitation!(local_Nx, maximum_size) + # Limit the maximum size such that we do not have memory issues + redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) - arch = Distributed(child_arch, partition = Partition(x = Sizes(local_Nx...))) - zonal_rank = arch.local_index[1] + partition = idx == 1 ? Partition(x = Sizes(local_N...)) : Partition(y = Sizes(local_N...)) - @info "slab decomposition with " zonal_rank local_Nx[zonal_rank], arch + arch = Distributed(child_arch; partition) + zonal_rank = arch.local_index[idx] - @show underlying_grid = LatitudeLongitudeGrid(arch; - size = N, - longitude = (-180, 180), - latitude = latitude, - halo = (7, 7, 7), - z = z_faces) + @info "slab decomposition with " zonal_rank local_N[zonal_rank] - return ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height), active_cells_map = true) + grid = LatitudeLongitudeGrid(arch; + size = N, + longitude, + latitude, + z, + halo) + + return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height), active_cells_map = true) end -@kernel function assess_x_load(load_per_slab, ibg) - i = @index(Global, Linear) +@kernel function assess_load(load_per_slab, grid, idx) + i1 = @index(Global, Linear) - @unroll for j in 1:size(ibg, 2) - @unroll for k in 1:size(ibg, 3) - @inbounds load_per_slab[i] += ifelse(immersed_cell(i, j, k, ibg), 0, 1) + for i2 in 1:size(grid, idx) + for k in 1:size(grid, 3) + i = ifelse(idx == 1, (i1, i2), (i2, i1)) + @inbounds load_per_slab[i] += ifelse(immersed_cell(i..., k, grid), 0, 1) end end end @@ -144,7 +160,9 @@ function calculate_local_size(load_per_slab, N, ranks) return local_N end -function redistribute_size_to_fulfill_memory_limitation!(l, m = 700) +redistribute_size_to_fulfill_memory_limitation!(l, ::Nothing) = nothing + +function redistribute_size_to_fulfill_memory_limitation!(l, m) n = length(l) while any(l .> m) x⁺, i⁺ = findmax(l) @@ -174,4 +192,6 @@ function redistribute_size_to_fulfill_memory_limitation!(l, m = 700) l[i⁻] += Δ end end + + return nothing end From 3078f0c849776d5002f580f9dc990bc80abb8f51 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:34:18 -0500 Subject: [PATCH 213/716] still strong --- experiments/twelth_degree_latlong.jl | 31 ++++++------------- src/DataWrangling/ECCO2.jl | 4 +-- src/DataWrangling/inpaint_mask.jl | 2 +- src/OceanSimulations/OceanSimulations.jl | 7 +++-- .../load_balanced_ocean_grid.jl | 3 +- 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 56f770a6..9fad8f93 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -21,7 +21,7 @@ Nx = 360 Ny = 150 Nz = length(z_faces) - 1 -arch = Distributed(CPU(), partition = Partition(1)) +arch = CPU() #Distributed(CPU(), partition = Partition(1)) @show grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), @@ -55,7 +55,8 @@ radiation = Radiation() coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) -function progress(sim) +function progress(coupled_sim) + sim = coupled_sim.ocean u, v, w = sim.model.velocities T, S = sim.model.tracers @@ -67,35 +68,23 @@ function progress(sim) maximum(abs, T), maximum(abs, S)) end -simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +coupled_model.callbacks[:progress] = Callback(progress, IterationInterval(10)) # Simulation warm up! -# -# We have regridded from a coarse solution (1/4er of a degree) to a -# fine grid (1/15th of a degree). Also, the bathymetry has little mismatches -# that might crash our simulation. We warm up the simulation with a little -# time step for few iterations to allow the solution to adjust to the new_grid -# bathymetry -simulation.Δt = 10 -simulation.stop_iteration = 1000 -run!(simulation) +coupled_model.Δt = 10 +coupled_model.stop_iteration = 1000 +run!(coupled_model) # Run the real simulation # # Now that the solution has adjusted to the bathymetry we can ramp up the time # step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.2 -wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 10minutes, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 10minutes, max_change = 1.1) -simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +coupled_model.ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations -simulation.stop_iteration = Inf - -simulation.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); - indices = (:, :, Nz), - schedule = TimeInterval(1day), - overwrite_existing = true, - filename = "med_surface_field") +coupled_model.stop_iteration = Inf run!(simulation) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 063f61a6..d78cc5bd 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -232,7 +232,7 @@ function inpainted_ecco2_field(variable_name; f = ecco2_field(variable_name; architecture) # Make sure all values are extended properly - @info "In-painting ecco field $variable_name and saving it in $filename" + @info "In-painting ecco $variable_name and saving it in $filename" inpaint_mask!(f, mask; kw...) ds = Dataset(filename, "c") @@ -248,7 +248,7 @@ function inpainted_ecco2_field(variable_name; else f = ecco2_field(variable_name; architecture) # Make sure all values are inpainted properly - @info "In-painting ecco field $variable_name and saving it in $filename" + @info "In-painting ecco $variable_name and saving it in $filename" inpaint_mask!(f, mask; kw...) defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) diff --git a/src/DataWrangling/inpaint_mask.jl b/src/DataWrangling/inpaint_mask.jl index 65d03890..c6ea8c45 100644 --- a/src/DataWrangling/inpaint_mask.jl +++ b/src/DataWrangling/inpaint_mask.jl @@ -47,7 +47,7 @@ end propagate_horizontally!(field, ::Nothing, tmp_field=deepcopy(field); kw...) = field function propagating(field, mask, iter, max_iter) - mask_sum = sum(field; condition=mask) + mask_sum = sum(field; condition=interior(mask)) return isnan(mask_sum) && iter < max_iter end diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 5b67278e..ba1df215 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -2,6 +2,7 @@ module OceanSimulations export load_balanced_regional_grid, ocean_simulation +using Oceananigans.Units using Oceananigans.Advection: TracerAdvection using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: @@ -29,9 +30,9 @@ default_momentum_advection() = VectorInvariant(; vorticity_scheme = WENO(; order vertical_scheme = Centered(), divergence_scheme = WENO()) -default_tracer_advection() = TracerAdvection(; x = WENO(; order = 7), - y = WENO(; order = 7), - z = Centered()) +default_tracer_advection() = TracerAdvection(WENO(; order = 7), + WENO(; order = 7), + Centered()) # 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... diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index f1cf5543..a647c03a 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -1,7 +1,8 @@ using ClimaOcean.Bathymetry using Oceananigans +using Oceananigans.Architectures: arch_array, device using Oceananigans.DistributedComputations -using Oceananigans.DistributedComputations: Sizes +using Oceananigans.DistributedComputations: Sizes, child_architecture using Oceananigans.ImmersedBoundaries: immersed_cell using KernelAbstractions: @index, @kernel From 0ba9d54d74a6504313a49375ae20811f8e438fdd Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:49:23 -0500 Subject: [PATCH 214/716] should work --- experiments/twelth_degree_latlong.jl | 24 +++++++------- .../load_balanced_ocean_grid.jl | 31 ++++++++++++++----- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 9fad8f93..e77e9584 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -6,8 +6,11 @@ using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalD using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units using ClimaOcean.OceanSimulations +using ClimaOcean.OceanSeaIceModels +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 +using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using Printf ##### @@ -17,11 +20,11 @@ using Printf # 100 vertical levels z_faces = exponential_z_faces(10, 6000) -Nx = 360 -Ny = 150 +Nx = 4320 +Ny = 1800 Nz = length(z_faces) - 1 -arch = CPU() #Distributed(CPU(), partition = Partition(1)) +arch = Distributed(GPU(), partition = Partition(8)) @show grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), @@ -29,15 +32,15 @@ arch = CPU() #Distributed(CPU(), partition = Partition(1)) latitude = (-75, 75), longitude = (0, 360), halo = (7, 7, 7), - interpolation_passes = 25) + interpolation_passes = 25, + bathymetry_file = "bathymetry1.jld2") ##### ##### The Ocean component ##### -simulation = ocean_simulation(grid) - -model = simulation.model +ocean = ocean_simulation(grid) +model = ocean.model # Initializing the model set!(model, @@ -55,8 +58,7 @@ radiation = Radiation() coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) -function progress(coupled_sim) - sim = coupled_sim.ocean +function progress(sim) u, v, w = sim.model.velocities T, S = sim.model.tracers @@ -68,7 +70,7 @@ function progress(coupled_sim) maximum(abs, T), maximum(abs, S)) end -coupled_model.callbacks[:progress] = Callback(progress, IterationInterval(10)) +ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) # Simulation warm up! coupled_model.Δt = 10 @@ -78,7 +80,7 @@ run!(coupled_model) # Run the real simulation # # Now that the solution has adjusted to the bathymetry we can ramp up the time -# step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.2 +# step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.35 wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 10minutes, max_change = 1.1) coupled_model.ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index a647c03a..94de3f82 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -5,6 +5,7 @@ using Oceananigans.DistributedComputations using Oceananigans.DistributedComputations: Sizes, child_architecture using Oceananigans.ImmersedBoundaries: immersed_cell using KernelAbstractions: @index, @kernel +using JLD2 """ load_balanced_regional_grid(arch; size, @@ -50,7 +51,8 @@ function load_balanced_regional_grid(arch; maximum_size = nothing, height_above_water = 1, minimum_depth = 10, - interpolation_passes = 1) + interpolation_passes = 1, + bathymetry_file = nothing) grid = LatitudeLongitudeGrid(arch; size, @@ -59,10 +61,23 @@ function load_balanced_regional_grid(arch; z, halo) - bottom_height = regrid_bathymetry(grid; - height_above_water, - minimum_depth, - interpolation_passes) + if !isnothing(bathymetry_file) + if isfile(bathymetry_file) + bottom_height = jldopen(bathymetry_file)["bathymetry"] + else + bottom_height = regrid_bathymetry(grid; + height_above_water, + minimum_depth, + interpolation_passes) + + jldsave(bathymetry_file, bathymetry = bottom_height) + end + else + bottom_height = regrid_bathymetry(grid; + height_above_water, + minimum_depth, + interpolation_passes) + end return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end @@ -82,7 +97,8 @@ function load_balanced_regional_grid(arch::SlabDistributed; maximum_size = nothing, height_above_water = 1, minimum_depth = 10, - interpolation_passes = 1) + interpolation_passes = 1, + bathymetry_file = nothing) child_arch = child_architecture(arch) @@ -96,7 +112,8 @@ function load_balanced_regional_grid(arch::SlabDistributed; maximum_size, height_above_water, minimum_depth, - interpolation_passes) + interpolation_passes, + bathymetry_file) bottom_height = grid.immersed_boundary.bottom_height From ad97d27ac2b34f649beeeee8ccb8802b1c92cfef Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:53:16 -0500 Subject: [PATCH 215/716] fixit --- experiments/twelth_degree_latlong.jl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index e77e9584..b31c2e1c 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -73,8 +73,10 @@ end ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) # Simulation warm up! -coupled_model.Δt = 10 -coupled_model.stop_iteration = 1000 +ocean.Δt = 10 +ocean.stop_iteration = 10000 +wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 90, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) run!(coupled_model) # Run the real simulation @@ -82,11 +84,10 @@ run!(coupled_model) # Now that the solution has adjusted to the bathymetry we can ramp up the time # step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.35 wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 10minutes, max_change = 1.1) - -coupled_model.ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations -coupled_model.stop_iteration = Inf +coupled_model.ocean.stop_iteration = Inf -run!(simulation) +run!(coupled_model) From ae94c9156729a0584963773fe5655ac18c89c5e1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:54:24 -0500 Subject: [PATCH 216/716] now it should work --- experiments/twelth_degree_latlong.jl | 2 +- src/OceanSimulations/load_balanced_ocean_grid.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index b31c2e1c..8326243c 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -24,7 +24,7 @@ Nx = 4320 Ny = 1800 Nz = length(z_faces) - 1 -arch = Distributed(GPU(), partition = Partition(8)) +arch = CPU() #Distributed(GPU(), partition = Partition(8)) @show grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index 94de3f82..7826e5f2 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -70,7 +70,7 @@ function load_balanced_regional_grid(arch; minimum_depth, interpolation_passes) - jldsave(bathymetry_file, bathymetry = bottom_height) + jldsave(bathymetry_file, bathymetry = Array(interior(bottom_height))) end else bottom_height = regrid_bathymetry(grid; From aa500b0bf736327e1f59bc5f66f8f34ab99cabb1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:54:43 -0500 Subject: [PATCH 217/716] test on satori --- experiments/twelth_degree_latlong.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 8326243c..b31c2e1c 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -24,7 +24,7 @@ Nx = 4320 Ny = 1800 Nz = length(z_faces) - 1 -arch = CPU() #Distributed(GPU(), partition = Partition(8)) +arch = Distributed(GPU(), partition = Partition(8)) @show grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), From 59108a57c71c66a391686ba0cb313054ee676065 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 27 Feb 2024 22:55:26 -0500 Subject: [PATCH 218/716] 100 vertical levels --- experiments/twelth_degree_latlong.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index b31c2e1c..da6aec44 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -18,7 +18,7 @@ using Printf ##### # 100 vertical levels -z_faces = exponential_z_faces(10, 6000) +z_faces = exponential_z_faces(100, 6000) Nx = 4320 Ny = 1800 From b5bcac48595d60fe57287185b2b549f147d18347 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 1 Mar 2024 08:12:53 +0200 Subject: [PATCH 219/716] increase clarity in exponential_z_faces --- Manifest.toml | 131 ++++++++++++++++++--------- Project.toml | 2 +- experiments/twelth_degree_latlong.jl | 2 +- src/VerticalGrids.jl | 4 +- 4 files changed, 94 insertions(+), 45 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index f2e08f4e..6c07f8d5 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.1" manifest_format = "2.0" -project_hash = "bcfc95e502c18276c6e7315f722ad6f48d7698c2" +project_hash = "043decf5ca2c4bac92a6417c1b87d2bdd66286cb" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -36,9 +36,9 @@ version = "0.1.35" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" +git-tree-sha1 = "0fb305e0253fd4e833d486914367a2ee2c2e78d0" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.7.2" +version = "4.0.1" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] @@ -93,6 +93,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,21 +112,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" - -[[deps.CLIMAParameters]] -deps = ["DocStringExtensions", "TOML", "Test"] -git-tree-sha1 = "cf4f5ee75576ae855eca7da064540ce40b9a04c1" -uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" -version = "0.8.6" +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", "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] @@ -141,15 +141,15 @@ 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"] -git-tree-sha1 = "aef70bb349b20aa81a82a19704c3ef339d4ee494" +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.22.1" +version = "1.23.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -182,10 +182,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" @@ -392,17 +392,22 @@ 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" +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"] @@ -415,6 +420,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" @@ -636,6 +647,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" @@ -716,9 +733,9 @@ version = "2023.1.10" [[deps.NCDatasets]] deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "173a378f357e9bb24b22019efb5e4778223ce8cf" +git-tree-sha1 = "98ca95cf41116a24e46dc9a06fa22b923e8411b7" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.13.2" +version = "0.14.2" [[deps.NVTX]] deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] @@ -739,10 +756,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" @@ -750,11 +773,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 = "43edfa309bf97157c720de62290858614732eca0" +git-tree-sha1 = "1910b8553f78cdd9a8496f51ea693b3adbd6b984" repo-rev = "main" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.8" +version = "0.90.9" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -810,6 +833,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" @@ -873,9 +902,9 @@ version = "1.2.0" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" +git-tree-sha1 = "9e8fed0505b0c15b4c1295fd59ea47b411c019cf" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.1" +version = "1.4.2" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] @@ -1129,12 +1158,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"] @@ -1176,15 +1211,17 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "f4555e1302df12011b836fbdcdd3e10e5df7329a" +git-tree-sha1 = "8254d615b8489fb0b9de960c9fae695538802834" repo-rev = "glw/density-example" repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.11.5" -weakdeps = ["CLIMAParameters"] +version = "0.12.4" [deps.Thermodynamics.extensions] - CreateParametersExt = "CLIMAParameters" + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] @@ -1240,6 +1277,12 @@ git-tree-sha1 = "07e470dabc5a6a4254ffebc29a1b3fc01464e105" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" version = "2.12.5+0" +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "37195dcb94a5970397ad425b95a9a26d0befce3a" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.6.0+0" + [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" @@ -1268,6 +1311,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..57638781 100644 --- a/Project.toml +++ b/Project.toml @@ -30,7 +30,7 @@ DataDeps = "0.7" Downloads = "1.6" JLD2 = "0.4" KernelAbstractions = "0.9" -NCDatasets = "0.12, 0.13" +NCDatasets = "0.12, 0.13, 0.14" Oceananigans = "0.90" SeawaterPolynomials = "0.3" Statistics = "1.9" diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index da6aec44..eaef7381 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -18,7 +18,7 @@ using Printf ##### # 100 vertical levels -z_faces = exponential_z_faces(100, 6000) +z_faces = exponential_z_faces(Nz=100, depth=6000) Nx = 4320 Ny = 1800 diff --git a/src/VerticalGrids.jl b/src/VerticalGrids.jl index 5e7cde30..e886cf4a 100644 --- a/src/VerticalGrids.jl +++ b/src/VerticalGrids.jl @@ -77,13 +77,13 @@ end @inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) -function exponential_z_faces(Nz, Depth; h = Nz / 4.5) +function exponential_z_faces(; Nz, depth, h = Nz / 4.5) z_faces = exponential_profile.((1:Nz+1); Lz = Nz, h) # Normalize z_faces .-= z_faces[1] - z_faces .*= - Depth / z_faces[end] + z_faces .*= - depth / z_faces[end] z_faces[1] = 0.0 From 7a487fec24b39d5d8fc626c5caacf3d79b6c5962 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 3 Mar 2024 15:57:30 -0500 Subject: [PATCH 220/716] remove connected regions --- Manifest.toml | 372 +++++++++++++++++- Project.toml | 2 + experiments/twelth_degree_latlong.jl | 48 ++- src/Bathymetry.jl | 85 +++- .../load_balanced_ocean_grid.jl | 8 +- 5 files changed, 484 insertions(+), 31 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index f2e08f4e..3fe30ebe 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.1" manifest_format = "2.0" -project_hash = "bcfc95e502c18276c6e7315f722ad6f48d7698c2" +project_hash = "460654a8f57fbe258c8b89f81009822e850759cf" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -93,6 +93,12 @@ git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" version = "0.1.8" +[[deps.BitTwiddlingConvenienceFunctions]] +deps = ["Static"] +git-tree-sha1 = "0c5f81f47bbbcf4aea7b2959135713459170798b" +uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" +version = "0.1.5" + [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" @@ -116,6 +122,12 @@ git-tree-sha1 = "cf4f5ee75576ae855eca7da064540ce40b9a04c1" uuid = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" version = "0.8.6" +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] +git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.4" + [[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" @@ -145,6 +157,12 @@ 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.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] git-tree-sha1 = "aef70bb349b20aa81a82a19704c3ef339d4ee494" @@ -163,6 +181,12 @@ repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" +[[deps.CloseOpenIntervals]] +deps = ["Static", "StaticArrayInterface"] +git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" +uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" +version = "0.1.12" + [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" @@ -175,6 +199,16 @@ 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" @@ -242,6 +276,12 @@ version = "1.5.4" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +[[deps.CpuId]] +deps = ["Markdown"] +git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" +uuid = "adafc99b-e345-5852-983c-f28acb93d879" +version = "0.3.1" + [[deps.Crayons]] git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" @@ -346,11 +386,29 @@ 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.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.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 = "4820348781ae578893311153d69049a93d05f39d" @@ -378,6 +436,12 @@ 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.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" @@ -388,6 +452,18 @@ weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] ForwardDiffStaticArraysExt = "StaticArrays" +[[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.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" @@ -410,11 +486,29 @@ git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" version = "0.25.0" +[[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.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" @@ -427,6 +521,18 @@ git-tree-sha1 = "ac7b73d562b8f4287c3b67b4c66a5395a19c1ae8" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" version = "1.10.2" +[[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.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] +git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.16" + [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" @@ -438,6 +544,18 @@ git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" version = "0.1.1" +[[deps.ImageCore]] +deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "b2a7eaa169c13f5bcae8131a83bc30eff8f71be0" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.2" + +[[deps.ImageMorphology]] +deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] +git-tree-sha1 = "6f0a801136cb9c229aebea0df296cdcd471dbcd1" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.4.5" + [[deps.IncompleteLU]] deps = ["LinearAlgebra", "SparseArrays"] git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" @@ -529,6 +647,12 @@ version = "0.9.17" [deps.KernelAbstractions.weakdeps] EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" +[[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 = "ddab4d40513bce53c8e3157825e245224f74fae7" @@ -565,11 +689,23 @@ 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.LayoutPointers]] +deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "62edfee3211981241b57ff1cedf4d74d79519277" +uuid = "10f19ff3-798f-405d-979b-55457f8fc047" +version = "0.1.15" + [[deps.LazyArtifacts]] deps = ["Artifacts", "Pkg"] uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" @@ -601,12 +737,42 @@ 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"] +git-tree-sha1 = "e5edc369a598dfde567269dc6add5812cfa10cd5" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.39.3+0" + [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -636,6 +802,17 @@ git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" version = "1.0.3" +[[deps.LoopVectorization]] +deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] +git-tree-sha1 = "0f5648fbae0d015e3abe5867bca2b362f67a5894" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.166" +weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + SpecialFunctionsExt = "SpecialFunctions" + [[deps.MKL_jll]] deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" @@ -680,6 +857,16 @@ git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.13" +[[deps.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" @@ -710,6 +897,12 @@ version = "1.1.0" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2023.1.10" @@ -771,6 +964,12 @@ 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" @@ -805,11 +1004,22 @@ git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.5+0" +[[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.PMIx_jll]] deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" @@ -822,6 +1032,12 @@ uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" version = "1.0.2" weakdeps = ["Requires", "TOML"] +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" @@ -848,6 +1064,12 @@ git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" version = "0.15.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" @@ -859,6 +1081,12 @@ git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" version = "0.3.3" +[[deps.PolyesterWeave]] +deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] +git-tree-sha1 = "240d7170f5ffdb285f9427b92333c3463bf65bf6" +uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" +version = "0.2.1" + [[deps.PooledArrays]] deps = ["DataAPI", "Future"] git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" @@ -980,6 +1208,17 @@ weakdeps = ["RecipesBase"] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" +[[deps.SIMDTypes]] +git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" +uuid = "94e857df-77ce-4151-89e5-788b33177be4" +version = "0.1.0" + +[[deps.SLEEFPirates]] +deps = ["IfElse", "Static", "VectorizationBase"] +git-tree-sha1 = "3aac6d68c5e57449f5b9b865c9ba50ac2970c4cf" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.42" + [[deps.Scratch]] deps = ["Dates"] git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" @@ -1029,6 +1268,12 @@ 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" @@ -1170,6 +1415,12 @@ version = "0.16.0" [deps.TaylorSeries.weakdeps] IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + [[deps.Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" @@ -1186,6 +1437,18 @@ weakdeps = ["CLIMAParameters"] [deps.Thermodynamics.extensions] CreateParametersExt = "CLIMAParameters" +[[deps.ThreadingUtilities]] +deps = ["ManualMemory"] +git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" +uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" +version = "0.5.2" + +[[deps.TiledIteration]] +deps = ["OffsetArrays", "StaticArrayInterface"] +git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" +uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" +version = "0.5.0" + [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" @@ -1215,6 +1478,11 @@ version = "1.5.1" 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" @@ -1229,6 +1497,12 @@ git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" version = "0.1.3" +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "7209df901e6ed7489fe9b7aa3e46fb788e15db85" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.65" + [[deps.VersionParsing]] git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" @@ -1240,6 +1514,60 @@ git-tree-sha1 = "07e470dabc5a6a4254ffebc29a1b3fc01464e105" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" version = "2.12.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" @@ -1257,6 +1585,18 @@ 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" @@ -1268,6 +1608,24 @@ 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 = "1ea2ebe8ffa31f9c324e8c1d6e86b4165b84a024" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.43+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" @@ -1283,3 +1641,15 @@ deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_ 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/Project.toml b/Project.toml index 5018ab52..7917dfa7 100644 --- a/Project.toml +++ b/Project.toml @@ -12,6 +12,8 @@ CubicSplines = "9c784101-8907-5a6d-9be6-98f00873c89b" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +FFMPEG = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +ImageMorphology = "787d08f9-d448-5407-9aad-5290dd7ab264" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index da6aec44..6f8119da 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -18,13 +18,13 @@ using Printf ##### # 100 vertical levels -z_faces = exponential_z_faces(100, 6000) +z_faces = exponential_z_faces(10, 6000) Nx = 4320 Ny = 1800 Nz = length(z_faces) - 1 -arch = Distributed(GPU(), partition = Partition(8)) +arch = CPU() #Distributed(GPU(), partition = Partition(8)) @show grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), @@ -32,8 +32,11 @@ arch = Distributed(GPU(), partition = Partition(8)) latitude = (-75, 75), longitude = (0, 360), halo = (7, 7, 7), - interpolation_passes = 25, - bathymetry_file = "bathymetry1.jld2") + interpolation_passes = 10, + minimum_depth = 10, + height_above_water = 1, + connected_regions_allowed = 3) + # bathymetry_file = "bathymetry1.jld2") ##### ##### The Ocean component @@ -70,24 +73,29 @@ function progress(sim) maximum(abs, T), maximum(abs, S)) end -ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) +ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) -# Simulation warm up! -ocean.Δt = 10 -ocean.stop_iteration = 10000 -wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 90, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) -run!(coupled_model) +# # Simulation warm up! +# ocean.Δt = 10 +# ocean.stop_iteration = 1 +# wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 90, max_change = 1.1) +# ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -# Run the real simulation -# -# Now that the solution has adjusted to the bathymetry we can ramp up the time -# step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.35 -wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 10minutes, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +# stop_time = 365days -# Let's reset the maximum number of iterations -coupled_model.ocean.stop_iteration = Inf +# coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) -run!(coupled_model) +# run!(coupled_simulation) + +# # Run the real simulation +# # +# # Now that the solution has adjusted to the bathymetry we can ramp up the time +# # step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.35 +# wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 10minutes, max_change = 1.1) +# ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) + +# # Let's reset the maximum number of iterations +# coupled_model.ocean.stop_iteration = Inf + +# run!(coupled_simulation) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index b276eb7e..689465f6 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -2,6 +2,8 @@ module Bathymetry export regrid_bathymetry + + using ..DataWrangling: download_progress using Oceananigans @@ -68,7 +70,8 @@ function regrid_bathymetry(target_grid; dir = joinpath(@__DIR__, "..", "data"), url = "https://www.ngdc.noaa.gov/thredds/fileServer/global/ETOPO2022/60s/60s_surface_elev_netcdf", filename = "ETOPO_2022_v1_60s_N90W180_surface.nc", - interpolation_passes = 1) + interpolation_passes = 1, + connected_regions_allowed = Inf) # Allow an `Inf` number of ``lakes'' filepath = joinpath(dir, filename) @@ -145,11 +148,6 @@ function regrid_bathymetry(target_grid; h_data[land] .= height_above_water end - if minimum_depth > 0 - shallow_ocean = h_data .> minimum_depth - h_data[shallow_ocean] .= height_above_water - end - # Build the "native" grid of the bathymetry and make a bathymetry field. Nxn = length(λ_data) Nyn = length(φ_data) @@ -165,13 +163,21 @@ function regrid_bathymetry(target_grid; native_h = Field{Center, Center, Nothing}(native_grid) set!(native_h, h_data) - target_h = interpolate_bathymetry_in_passes(native_h, target_grid; passes = interpolation_passes) + target_h = interpolate_bathymetry_in_passes(native_h, target_grid; + passes = interpolation_passes, + connected_regions_allowed, + minimum_depth, + height_above_water) return target_h end # Here we can either use `regrid!` (three dimensional version) or `interpolate` -function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) +function interpolate_bathymetry_in_passes(native_h, target_grid; + passes = 10, + connected_regions_allowed = Inf, + minimum_depth = 0, + height_above_water = nothing) Nλt, Nφt = Nt = size(target_grid) Nλn, Nφn = Nn = size(native_h) @@ -216,8 +222,71 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10) target_h = Field{Center, Center, Nothing}(target_grid) interpolate!(target_h, old_h) + h_data = Array(interior(target_h, :, :, 1)) + + if minimum_depth > 0 + shallow_ocean = h_data .> minimum_depth + h_data[shallow_ocean] .= height_above_water + end + + remove_lakes!(h_data; connected_regions_allowed) + + set!(target_h, h_data) + fill_halo_regions!(target_h) + return target_h end +function remove_lakes!(h_data; connected_regions_allowed = Inf) + + if connected_regions_allowed == Inf + return h_data + end + + bathtmp = deepcopy(h_data) + batneg = zeros(Bool, size(bathtmp)...) + + batneg[bathtmp.<0] .= true + + labels = ImageMorphology.label_components(batneg) #, connectivity = 1) + try + total_elements = zeros(maximum(labels)) + + for i in 1:lastindex(total_elements) + total_elements[i] = sum(labels[labels .== i]) + end + + all_idx = [] + ocean_idx = findfirst(x -> x == maximum(x), total_elements) + push!(all_idx, ocean_idx) + total_elements = filter((x) -> x != total_elements[ocean_idx], total_elements) + + for _ in 1:connected_regions_allowed + next_maximum = maximum(total_elements) + push!(all_idx, next_maximum) + total_elements = filter((x) -> x != total_elements[next_maximum], total_elements) + end + + labels = Float64.(labels) + labels[labels.==0] .= NaN + + for i in 1:length(total_elements) + remove_lake = (&).(Tuple(i != idx for idx in all_idx)...) + if remove_lake + labels[labels .== i] .= NaN + end + end + + bathtmp .+= labels + bathtmp[isnan.(bathtmp)] .= ABOVE_SEA_LEVEL + catch err + println("this is the error $err") + end + + h_data .= bathtmp + + return h_data +end + end # module diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index 7826e5f2..94a39cf6 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -51,6 +51,7 @@ function load_balanced_regional_grid(arch; maximum_size = nothing, height_above_water = 1, minimum_depth = 10, + connected_regions_allowed = Inf, interpolation_passes = 1, bathymetry_file = nothing) @@ -68,7 +69,8 @@ function load_balanced_regional_grid(arch; bottom_height = regrid_bathymetry(grid; height_above_water, minimum_depth, - interpolation_passes) + interpolation_passes, + connected_regions_allowed) jldsave(bathymetry_file, bathymetry = Array(interior(bottom_height))) end @@ -98,6 +100,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; height_above_water = 1, minimum_depth = 10, interpolation_passes = 1, + connected_regions_allowed = Inf, bathymetry_file = nothing) child_arch = child_architecture(arch) @@ -113,7 +116,8 @@ function load_balanced_regional_grid(arch::SlabDistributed; height_above_water, minimum_depth, interpolation_passes, - bathymetry_file) + bathymetry_file, + connected_regions_allowed) bottom_height = grid.immersed_boundary.bottom_height From 7f3073f127bbc5cc47295fd479cea1cacf822337 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:43:28 -0500 Subject: [PATCH 221/716] using correct package versions --- Manifest.toml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index d9ac34f6..f080b76b 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1410,15 +1410,17 @@ version = "7.2.1+1" [[deps.SurfaceFluxes]] deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "24086f7e46de40dbd32a49d3fd51a534a5a9bcb0" +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.10.0" +version = "0.9.2" [deps.SurfaceFluxes.extensions] - CreateParametersExt = "ClimaParams" + CreateParametersExt = "CLIMAParameters" [deps.SurfaceFluxes.weakdeps] - ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" [[deps.TOML]] deps = ["Dates"] @@ -1466,7 +1468,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "a539e258008ed9275a91e0a374aa1d073e80e2bf" +git-tree-sha1 = "8254d615b8489fb0b9de960c9fae695538802834" +repo-rev = "glw/density-example" +repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" version = "0.12.4" From 405166d74a1a9d0c95c01f6532190f811209e574 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:44:30 -0500 Subject: [PATCH 222/716] add connected regions removal --- experiments/twelth_degree_latlong.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 589be9cc..d2849b39 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -24,7 +24,7 @@ Nx = 4320 Ny = 1800 Nz = length(z_faces) - 1 -arch = CPU() #Distributed(GPU(), partition = Partition(8)) +arch = Distributed(GPU(), partition = Partition(8)) @show grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), @@ -35,8 +35,8 @@ arch = CPU() #Distributed(GPU(), partition = Partition(8)) interpolation_passes = 10, minimum_depth = 10, height_above_water = 1, - connected_regions_allowed = 3) - # bathymetry_file = "bathymetry1.jld2") + connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea + bathymetry_file = "bathymetry1.jld2") ##### ##### The Ocean component From 55f38da3ff114edfb881bdf8b6afa6270df25e7d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:46:36 -0500 Subject: [PATCH 223/716] some doc --- src/Bathymetry.jl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 689465f6..ac5de2eb 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -237,6 +237,25 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; return target_h end +""" + remove_lakes!(h_data; connected_regions_allowed = Inf) + +Remove lakes from the bathymetric data stored in `h_data`. + +# Arguments +============ + +- `h_data`: A 2D array representing the bathymetry data. +- `connected_regions_allowed`: The maximum number of connected regions to keep. + Default is `Inf`, which means all connected regions are kept. + +# Returns +========= + +The function removes lakes from the bathymetry data by identifying connected regions below sea level +and removing all but the specified number of largest connected regions (which represent the ocean and +other possibly disconnected regions like the Mediterranean and the Bering sea). +""" function remove_lakes!(h_data; connected_regions_allowed = Inf) if connected_regions_allowed == Inf From ab80fca4db1d4847a86bb822eed9a72b538698ad Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 3 Mar 2024 17:49:17 -0500 Subject: [PATCH 224/716] this works --- src/Bathymetry.jl | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index ac5de2eb..901d8706 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -2,8 +2,7 @@ module Bathymetry export regrid_bathymetry - - +using ImageMorphology using ..DataWrangling: download_progress using Oceananigans @@ -267,23 +266,27 @@ function remove_lakes!(h_data; connected_regions_allowed = Inf) batneg[bathtmp.<0] .= true - labels = ImageMorphology.label_components(batneg) #, connectivity = 1) + labels = ImageMorphology.label_components(batneg) try total_elements = zeros(maximum(labels)) + label_elements = zeros(maximum(labels)) for i in 1:lastindex(total_elements) total_elements[i] = sum(labels[labels .== i]) + label_elements[i] = i end all_idx = [] - ocean_idx = findfirst(x -> x == maximum(x), total_elements) - push!(all_idx, ocean_idx) + ocean_idx = findfirst(x -> x == maximum(total_elements), total_elements) + push!(all_idx, label_elements[ocean_idx]) total_elements = filter((x) -> x != total_elements[ocean_idx], total_elements) + label_elements = filter((x) -> x != label_elements[ocean_idx], label_elements) for _ in 1:connected_regions_allowed - next_maximum = maximum(total_elements) - push!(all_idx, next_maximum) + next_maximum = findfirst(x -> x == maximum(total_elements), total_elements) + push!(all_idx, label_elements[next_maximum]) total_elements = filter((x) -> x != total_elements[next_maximum], total_elements) + label_elements = filter((x) -> x != label_elements[next_maximum], label_elements) end labels = Float64.(labels) From 8605a9b5d5ceff467936bdd0479cd61e8a7f299b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 3 Mar 2024 17:56:40 -0500 Subject: [PATCH 225/716] finished connected regions --- src/OceanSimulations/load_balanced_ocean_grid.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index 94a39cf6..10aa1545 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -38,6 +38,7 @@ calculated to maintain an equal number of active cells across different workers. - `height_above_water`: The height above water level. Default is `1`. - `minimum_depth`: The minimum depth of the bathymetry. Default is `10`. - `interpolation_passes`: The number of interpolation passes. Default is `1`. +- `connected_regions_allowed`: The number of connected regions allowed in the bathymetry # Returns - `grid`: The load-balanced ocean grid. @@ -78,7 +79,8 @@ function load_balanced_regional_grid(arch; bottom_height = regrid_bathymetry(grid; height_above_water, minimum_depth, - interpolation_passes) + interpolation_passes, + connected_regions_allowed) end return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) From 54631ba43bb96c6e593ee10af0841702f7f0124e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 13:14:05 -0500 Subject: [PATCH 226/716] should work with distributed now --- Manifest.toml | 4 +- experiments/twelth_degree_latlong.jl | 32 +++---- src/Bathymetry.jl | 84 ++++++++++--------- src/DataWrangling/JRA55.jl | 6 ++ .../ocean_sea_ice_surface_fluxes.jl | 17 ++-- .../similarity_theory_turbulent_fluxes.jl | 5 +- .../PrescribedAtmospheres.jl | 11 ++- .../load_balanced_ocean_grid.jl | 14 ++-- 8 files changed, 98 insertions(+), 75 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index f080b76b..da3664fb 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.1" +julia_version = "1.10.2" manifest_format = "2.0" project_hash = "eef01b615158af2777b0945e4cc529fabc90261f" @@ -1468,7 +1468,7 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "8254d615b8489fb0b9de960c9fae695538802834" +git-tree-sha1 = "ed1a35a4b608024f60b71f92930ca9e64d55068c" repo-rev = "glw/density-example" repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index d2849b39..0c456162 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -18,13 +18,13 @@ using Printf ##### # 100 vertical levels -z_faces = exponential_z_faces(Nz=100, depth=6000) +z_faces = exponential_z_faces(Nz=40, depth=6000) -Nx = 4320 -Ny = 1800 +Nx = 360 +Ny = 150 Nz = length(z_faces) - 1 -arch = Distributed(GPU(), partition = Partition(8)) +arch = Distributed(CPU(), partition = Partition(4)) @show grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), @@ -34,9 +34,8 @@ arch = Distributed(GPU(), partition = Partition(8)) halo = (7, 7, 7), interpolation_passes = 10, minimum_depth = 10, - height_above_water = 1, connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea - bathymetry_file = "bathymetry1.jld2") + ) ##### ##### The Ocean component @@ -55,7 +54,7 @@ set!(model, ##### The atmosphere ##### -backend = JRA55NetCDFBackend(10) # InMemory(8) +backend = JRA55NetCDFBackend(10) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation() @@ -75,15 +74,20 @@ end ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) -# # Simulation warm up! -# ocean.Δt = 10 -# ocean.stop_iteration = 1 -# wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 90, max_change = 1.1) -# ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) +# Simulation warm up! +ocean.Δt = 10 +ocean.stop_iteration = 1 +wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 90, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -# stop_time = 365days +stop_time = 365days -# coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) +coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) + +time_step!(coupled_simulation) +time_step!(coupled_simulation) + +jldsave("test_$(arch.local_rank).jld2", T = ocean.model.tracers.T, S = ocean.model.tracers.S) # run!(coupled_simulation) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 901d8706..2921ef43 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -62,6 +62,11 @@ Keyword Arguments: applying a smoothing filter, with more passes increasing the strength of the filter. If _refining_ the original grid, additional passes will not help and no intermediate steps will be performed. + +- connected_regions_allowed: number of ``connected regions'' allowed in the bathymetry. Connected regions are fluid + regions that are fully encompassed by land (for example the ocean is one connected region). + Default is `Inf`. If a value < `Inf` is specified, connected regions will be preserved in order + of how many active cells they contain. """ function regrid_bathymetry(target_grid; height_above_water = nothing, @@ -70,7 +75,7 @@ function regrid_bathymetry(target_grid; url = "https://www.ngdc.noaa.gov/thredds/fileServer/global/ETOPO2022/60s/60s_surface_elev_netcdf", filename = "ETOPO_2022_v1_60s_N90W180_surface.nc", interpolation_passes = 1, - connected_regions_allowed = Inf) # Allow an `Inf` number of ``lakes'' + connected_regions_allowed = 3) # Allow an `Inf` number of ``lakes'' filepath = joinpath(dir, filename) @@ -174,7 +179,7 @@ end # Here we can either use `regrid!` (three dimensional version) or `interpolate` function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10, - connected_regions_allowed = Inf, + connected_regions_allowed = 3, minimum_depth = 0, height_above_water = nothing) Nλt, Nφt = Nt = size(target_grid) @@ -228,8 +233,7 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; h_data[shallow_ocean] .= height_above_water end - remove_lakes!(h_data; connected_regions_allowed) - + h_data = remove_lakes!(h_data; connected_regions_allowed) set!(target_h, h_data) fill_halo_regions!(target_h) @@ -258,56 +262,56 @@ other possibly disconnected regions like the Mediterranean and the Bering sea). function remove_lakes!(h_data; connected_regions_allowed = Inf) if connected_regions_allowed == Inf + @info "we are not removing lakes" return h_data end + @show connected_regions_allowed + bathtmp = deepcopy(h_data) batneg = zeros(Bool, size(bathtmp)...) batneg[bathtmp.<0] .= true labels = ImageMorphology.label_components(batneg) - try - total_elements = zeros(maximum(labels)) - label_elements = zeros(maximum(labels)) + + total_elements = zeros(maximum(labels)) + label_elements = zeros(maximum(labels)) - for i in 1:lastindex(total_elements) - total_elements[i] = sum(labels[labels .== i]) - label_elements[i] = i - end - - all_idx = [] - ocean_idx = findfirst(x -> x == maximum(total_elements), total_elements) - push!(all_idx, label_elements[ocean_idx]) - total_elements = filter((x) -> x != total_elements[ocean_idx], total_elements) - label_elements = filter((x) -> x != label_elements[ocean_idx], label_elements) - - for _ in 1:connected_regions_allowed - next_maximum = findfirst(x -> x == maximum(total_elements), total_elements) - push!(all_idx, label_elements[next_maximum]) - total_elements = filter((x) -> x != total_elements[next_maximum], total_elements) - label_elements = filter((x) -> x != label_elements[next_maximum], label_elements) - end - - labels = Float64.(labels) - labels[labels.==0] .= NaN - - for i in 1:length(total_elements) - remove_lake = (&).(Tuple(i != idx for idx in all_idx)...) - if remove_lake - labels[labels .== i] .= NaN - end - end + for i in 1:lastindex(total_elements) + total_elements[i] = sum(labels[labels .== i]) + label_elements[i] = i + end + + all_idx = [] + ocean_idx = findfirst(x -> x == maximum(total_elements), total_elements) + push!(all_idx, label_elements[ocean_idx]) + total_elements = filter((x) -> x != total_elements[ocean_idx], total_elements) + label_elements = filter((x) -> x != label_elements[ocean_idx], label_elements) + + for _ in 1:connected_regions_allowed + next_maximum = findfirst(x -> x == maximum(total_elements), total_elements) + push!(all_idx, label_elements[next_maximum]) + total_elements = filter((x) -> x != total_elements[next_maximum], total_elements) + label_elements = filter((x) -> x != label_elements[next_maximum], label_elements) + end + + labels = Float64.(labels) - bathtmp .+= labels - bathtmp[isnan.(bathtmp)] .= ABOVE_SEA_LEVEL - catch err - println("this is the error $err") + for i in 1:maximum(labels) + remove_lake = (&).(Tuple(i != idx for idx in all_idx)...) + if remove_lake + labels[labels .== i] .= NaN + end end - h_data .= bathtmp + # Removing land? + labels[labels.==0] .= NaN + + bathtmp .+= labels + bathtmp[isnan.(bathtmp)] .= 0 - return h_data + return bathtmp end end # module diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 5e7fe170..04c417d1 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -3,6 +3,8 @@ module JRA55 using Oceananigans using Oceananigans.Units +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! @@ -544,6 +546,10 @@ 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, diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index a71484e5..89e96a24 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -14,7 +14,7 @@ using Oceananigans: HydrostaticFreeSurfaceModel, architecture using Oceananigans.Grids: inactive_node, node using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Fields: ConstantField, interpolate -using Oceananigans.Utils: launch!, Time +using Oceananigans.Utils: launch!, Time, KernelParameters # using Oceananigans.OutputReaders: extract_field_time_series, update_field_time_series! @@ -178,7 +178,12 @@ 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_similarity_theory_fluxes!, + kernel_size = (size(grid, 1) + 2, size(grid, 2) + 2) + + # kernel parameters that compute fluxes in 0:Nx+1 and 0:Ny+1 + kernel_parameters = KernelParameters(kernel_size, (-1, -1)) + + launch!(arch, grid, kernel_parameters, compute_atmosphere_ocean_similarity_theory_fluxes!, similarity_theory.fields, grid, clock, @@ -193,7 +198,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere.thermodynamics_parameters, similarity_theory.roughness_lengths) - launch!(arch, grid, :xy, assemble_atmosphere_ocean_fluxes!, + launch!(arch, grid, kernel_parameters, assemble_atmosphere_ocean_fluxes!, centered_velocity_fluxes, net_tracer_fluxes, grid, @@ -212,11 +217,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) coupled_model.fluxes.ocean_reference_density, coupled_model.fluxes.ocean_heat_capacity, coupled_model.fluxes.freshwater_density) - - # Note: I think this can be avoided if we modify the preceding kernel - # to compute from 0:Nx+1, ie in halo regions - fill_halo_regions!(centered_velocity_fluxes) - + launch!(arch, grid, :xy, reconstruct_momentum_fluxes!, grid, staggered_velocity_fluxes, centered_velocity_fluxes) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 29e47274..22fdb287 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -63,8 +63,9 @@ Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheory 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★) + FT = eltype(ℂₐ) + p★ = AtmosphericThermodynamics.saturation_vapor_pressure(ℂₐ, convert(FT, Tₛ), Liquid()) + q★ = AtmosphericThermodynamics.q_vap_saturation_from_density(ℂₐ, convert(FT, Tₛ), ρₛ, p★) return q★ end diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 10925962..3e738589 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -94,7 +94,7 @@ function ConstitutiveParameters(FT = Float64; convert(FT, water_molar_mass)) end -const CP = ConstitutiveParameters +const CP{FT} = ConstitutiveParameters{FT} where FT @inline gas_constant(p::CP) = p.gas_constant @inline molmass_dryair(p::CP) = p.dry_air_molar_mass @@ -141,7 +141,7 @@ function HeatCapacityParameters(FT = Float64; convert(FT, water_ice_heat_capacity)) end -const HCP = HeatCapacityParameters +const HCP{FT} = HeatCapacityParameters{FT} where FT @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 @@ -190,7 +190,7 @@ function PhaseTransitionParameters(FT = Float64; convert(FT, total_ice_nucleation_temperature)) end -const PTP = PhaseTransitionParameters +const PTP{FT} = PhaseTransitionParameters{FT} where FT @inline LH_v0(p::PTP) = p.reference_vaporization_enthalpy @inline LH_s0(p::PTP) = p.reference_sublimation_enthalpy @inline LH_f0(p::PTP) = LH_s0(p) - LH_v0(p) @@ -209,6 +209,11 @@ end const PATP{FT} = PrescribedAtmosphereThermodynamicsParameters{FT} where FT +Base.eltype(::PATP{FT}) where FT = FT +Base.eltype(::CP{FT}) where FT = FT +Base.eltype(::HCP{FT}) where FT = FT +Base.eltype(::PTP{FT}) where FT = FT + Base.summary(::PATP{FT}) where FT = "PrescribedAtmosphereThermodynamicsParameters{$FT}" function Base.show(io::IO, p::PrescribedAtmosphereThermodynamicsParameters) diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index 10aa1545..06ee14bc 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -52,7 +52,7 @@ function load_balanced_regional_grid(arch; maximum_size = nothing, height_above_water = 1, minimum_depth = 10, - connected_regions_allowed = Inf, + connected_regions_allowed = 3, interpolation_passes = 1, bathymetry_file = nothing) @@ -66,6 +66,7 @@ function load_balanced_regional_grid(arch; if !isnothing(bathymetry_file) if isfile(bathymetry_file) bottom_height = jldopen(bathymetry_file)["bathymetry"] + return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) else bottom_height = regrid_bathymetry(grid; height_above_water, @@ -74,6 +75,7 @@ function load_balanced_regional_grid(arch; connected_regions_allowed) jldsave(bathymetry_file, bathymetry = Array(interior(bottom_height))) + return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end else bottom_height = regrid_bathymetry(grid; @@ -81,9 +83,9 @@ function load_balanced_regional_grid(arch; minimum_depth, interpolation_passes, connected_regions_allowed) + + return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end - - return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end const SlabPartition = Union{Partition{<:Any, <:Nothing, <:Nothing}, @@ -102,7 +104,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; height_above_water = 1, minimum_depth = 10, interpolation_passes = 1, - connected_regions_allowed = Inf, + connected_regions_allowed = 3, bathymetry_file = nothing) child_arch = child_architecture(arch) @@ -132,7 +134,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; loop!(load_per_slab, grid, idx) load_per_slab = arch_array(CPU(), load_per_slab) - local_N = calculate_local_size(load_per_slab, N[idx], arch.ranks[idx]) + local_N = calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) # Limit the maximum size such that we do not have memory issues redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) @@ -160,7 +162,7 @@ end for i2 in 1:size(grid, idx) for k in 1:size(grid, 3) i = ifelse(idx == 1, (i1, i2), (i2, i1)) - @inbounds load_per_slab[i] += ifelse(immersed_cell(i..., k, grid), 0, 1) + @inbounds load_per_slab[i1] += ifelse(immersed_cell(i..., k, grid), 0, 1) end end end From 2bf5b8f2c8a4b729eed214e5ad4d99185db99c5a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 13:23:16 -0500 Subject: [PATCH 227/716] load balanced --- src/OceanSimulations/load_balanced_ocean_grid.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index 06ee14bc..f46a167d 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -123,7 +123,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; bathymetry_file, connected_regions_allowed) - bottom_height = grid.immersed_boundary.bottom_height + bottom_height = interior(grid.immersed_boundary.bottom_height) # index of the partitioned direction idx = arch.ranks[1] == 1 ? 2 : 1 @@ -147,7 +147,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; @info "slab decomposition with " zonal_rank local_N[zonal_rank] grid = LatitudeLongitudeGrid(arch; - size = N, + size, longitude, latitude, z, From 78083cc32da41d0b18392e0072b82a082c9357bf Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:00:16 -0500 Subject: [PATCH 228/716] now it works with distributed --- experiments/twelth_degree_latlong.jl | 6 +- src/OceanSimulations/OceanSimulations.jl | 2 +- .../load_balanced_ocean_grid.jl | 68 +++++++++++-------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 0c456162..7e60991d 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -35,13 +35,15 @@ arch = Distributed(CPU(), partition = Partition(4)) interpolation_passes = 10, minimum_depth = 10, connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea - ) + bathymetry_file = "tmp.jld2") ##### ##### The Ocean component ##### -ocean = ocean_simulation(grid) +free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=270) + +ocean = ocean_simulation(grid; free_surface) model = ocean.model # Initializing the model diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index ba1df215..ca7a42e5 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -18,7 +18,7 @@ using Oceananigans.Coriolis: Ω_Earth include("load_balanced_ocean_grid.jl") # Some defualts -default_free_surface(grid) = SplitExplicitFreeSurface(cfl=0.7; grid) +default_free_surface(grid) = SplitExplicitFreeSurface(; cfl=0.7, grid) function default_ocean_closure() mixing_length = MixingLength(Cᵇ=0.01) diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index f46a167d..f38c91be 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -1,8 +1,8 @@ using ClimaOcean.Bathymetry using Oceananigans -using Oceananigans.Architectures: arch_array, device +using Oceananigans.Architectures: arch_array, device, architecture using Oceananigans.DistributedComputations -using Oceananigans.DistributedComputations: Sizes, child_architecture +using Oceananigans.DistributedComputations: Sizes, child_architecture, barrier!, all_reduce using Oceananigans.ImmersedBoundaries: immersed_cell using KernelAbstractions: @index, @kernel using JLD2 @@ -109,35 +109,47 @@ function load_balanced_regional_grid(arch::SlabDistributed; child_arch = child_architecture(arch) - # Global grid - grid = load_balanced_regional_grid(child_arch; - size, - longitude, - latitude, - z, - halo, - maximum_size, - height_above_water, - minimum_depth, - interpolation_passes, - bathymetry_file, - connected_regions_allowed) - - bottom_height = interior(grid.immersed_boundary.bottom_height) - # index of the partitioned direction idx = arch.ranks[1] == 1 ? 2 : 1 - # Starting with the load balancing - load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) - loop! = assess_load(device(child_arch), 512, size[idx]) - loop!(load_per_slab, grid, idx) - - load_per_slab = arch_array(CPU(), load_per_slab) - local_N = calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) - - # Limit the maximum size such that we do not have memory issues - redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) + local_N = zeros(Int, arch.ranks[idx]) + bottom_height = zeros(size[1], size[2], 1) + + # Calculating the local halos on the global grid on rank 0 + # so that we can write to file the bathymetry in case `!isnothing(bathymetry_file)` + if arch.local_rank == 1 + grid = load_balanced_regional_grid(child_arch; + size, + longitude, + latitude, + z, + halo, + maximum_size, + height_above_water, + minimum_depth, + interpolation_passes, + bathymetry_file, + connected_regions_allowed) + + # TODO: fix the set! function for DistributedFields in Oceananigans + # to work with non-distributed fields and Subarrays + bottom_height .= arch_array(CPU(), interior(grid.immersed_boundary.bottom_height)) + + # Starting with the load balancing + load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) + loop! = assess_load(device(child_arch), 512, size[idx]) + loop!(load_per_slab, grid, idx) + + load_per_slab = arch_array(CPU(), load_per_slab) + local_N = calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) + + # Limit the maximum size such that we do not have memory issues + redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) + end + + barrier!(arch) + bottom_height = all_reduce(+, bottom_height, arch) + local_N = all_reduce(+, local_N, arch) partition = idx == 1 ? Partition(x = Sizes(local_N...)) : Partition(y = Sizes(local_N...)) From 19e2013fb892edc138982799959b8c307ce1f74d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:15:07 -0500 Subject: [PATCH 229/716] added set! for distributed fields and eccometadata --- src/DataWrangling/ECCO2.jl | 40 +++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index c8944096..77931c54 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -8,6 +8,7 @@ using ClimaOcean.InitialConditions: three_dimensional_regrid! using Oceananigans using Oceananigans: architecture using Oceananigans.BoundaryConditions +using Oceananigans.DistributedComputations: DistributedField using Oceananigans.Utils using KernelAbstractions: @kernel, @index using NCDatasets @@ -263,6 +264,27 @@ function inpainted_ecco2_field(variable_name; return f end +function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename="./inpainted_ecco2_fields.nc", kw...) + # Fields initialized from ECCO2 + grid = field.grid + arch = architecture(grid) + child_arch = child_architecture(arch) + name = ecco2_metadata.name + + mask = ecco2_center_mask(child_arch) + + f = inpainted_ecco2_field(name; filename, mask, + architecture = child_arch, + kw...) + + + f_grid = Field(ecco2_location[name], grid) + three_dimensional_regrid!(f_grid, f) + set!(field, f_grid) + + return field +end + function set!(field::Field, ecco2_metadata::ECCO2Metadata; filename="./inpainted_ecco2_fields.nc", kw...) # Fields initialized from ECCO2 @@ -282,24 +304,6 @@ function set!(field::Field, ecco2_metadata::ECCO2Metadata; filename="./inpainted return field end -function ecco2_column(λ★, φ★) - Δ = 1/4 # resolution in degrees - φ₁ = -90 + Δ/2 - φ₂ = +90 - Δ/2 - λ₁ = 0 + Δ/2 - λ₂ = 360 - Δ/2 - φe = φ₁:Δ:φ₂ - λe = λ₁:Δ:λ₂ - - i★ = searchsortedfirst(λe, λ★) - j★ = searchsortedfirst(φe, φ★) - - longitude = (λe[i★] - Δ/2, λe[i★] + Δ/2) - latitude = (φe[j★] - Δ/2, φe[j★] + Δ/2) - - return i★, j★, longitude, latitude -end - end # module From e457dafd45e05ff4c838d1d01e8d243169887e88 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:20:19 -0500 Subject: [PATCH 230/716] let's try it out --- experiments/twelth_degree_latlong.jl | 24 +++++++++++++----------- src/DataWrangling/ECCO2.jl | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 7e60991d..89a90808 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -26,17 +26,19 @@ Nz = length(z_faces) - 1 arch = Distributed(CPU(), partition = Partition(4)) -@show grid = load_balanced_regional_grid(arch; - size = (Nx, Ny, Nz), - z = z_faces, - latitude = (-75, 75), - longitude = (0, 360), - halo = (7, 7, 7), - interpolation_passes = 10, - minimum_depth = 10, - connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea - bathymetry_file = "tmp.jld2") - +grid = load_balanced_regional_grid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + latitude = (-75, 75), + longitude = (0, 360), + halo = (7, 7, 7), + interpolation_passes = 10, + minimum_depth = 10, + connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea + bathymetry_file = "tmp.jld2") + +@show grid + ##### ##### The Ocean component ##### diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 77931c54..a51a5a70 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -8,7 +8,7 @@ using ClimaOcean.InitialConditions: three_dimensional_regrid! using Oceananigans using Oceananigans: architecture using Oceananigans.BoundaryConditions -using Oceananigans.DistributedComputations: DistributedField +using Oceananigans.DistributedComputations: DistributedField, child_architecture using Oceananigans.Utils using KernelAbstractions: @kernel, @index using NCDatasets From 325e91674683318b54007af1b81e5b8653ea1a4a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:34:13 -0500 Subject: [PATCH 231/716] ecco2 on different cores --- src/DataWrangling/ECCO2.jl | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index a51a5a70..60484362 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -6,9 +6,9 @@ using ClimaOcean.DataWrangling: inpaint_mask! using ClimaOcean.InitialConditions: three_dimensional_regrid! using Oceananigans -using Oceananigans: architecture +using Oceananigans.Architectures: architecture, child_architecture using Oceananigans.BoundaryConditions -using Oceananigans.DistributedComputations: DistributedField, child_architecture +using Oceananigans.DistributedComputations: DistributedField, all_reduce using Oceananigans.Utils using KernelAbstractions: @kernel, @index using NCDatasets @@ -272,12 +272,18 @@ function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename=" name = ecco2_metadata.name mask = ecco2_center_mask(child_arch) - - f = inpainted_ecco2_field(name; filename, mask, - architecture = child_arch, - kw...) - + f_ecco = if arch.local_rank == 0 # NCDatasets does not work in distributed mode?? + inpainted_ecco2_field(name; filename, mask, + architecture = child_arch, + kw...) + else + empty_ecco2_field(ecco2_metadata; architecture = child_arch) + end + + # Distribute ecco field to all workers + parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) + f_grid = Field(ecco2_location[name], grid) three_dimensional_regrid!(f_grid, f) set!(field, f_grid) From 2a8ed2927cdab7e3361d82de564ab22978c2f0e9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:46:34 -0500 Subject: [PATCH 232/716] to test on 1 GPU --- src/DataWrangling/ECCO2.jl | 4 ++-- src/DataWrangling/JRA55.jl | 2 -- src/InitialConditions/InitialConditions.jl | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 60484362..0a13281a 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -273,7 +273,7 @@ function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename=" mask = ecco2_center_mask(child_arch) - f_ecco = if arch.local_rank == 0 # NCDatasets does not work in distributed mode?? + f_ecco = if arch.local_rank == 0 # Make sure we read/write the file using only one core inpainted_ecco2_field(name; filename, mask, architecture = child_arch, kw...) @@ -285,7 +285,7 @@ function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename=" parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) f_grid = Field(ecco2_location[name], grid) - three_dimensional_regrid!(f_grid, f) + three_dimensional_regrid!(f_grid, f_ecco) set!(field, f_grid) return field diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 04c417d1..72544329 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -235,7 +235,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) @@ -546,7 +545,6 @@ 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...) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 9edc1e7b..40158fbb 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -8,7 +8,7 @@ using Oceananigans.Fields: OneField using Oceananigans.Grids: peripheral_node using Oceananigans.Utils: launch! using Oceananigans.Fields: instantiated_location, interior, CenterField -using Oceananigans.Architectures: architecture, device, GPU +using Oceananigans.Architectures: architecture, device, GPU, child_architecture using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll @@ -30,13 +30,12 @@ construct_grid(::Type{<:RectilinearGrid}, arch, size, extent, topology) = construct_grid(::Type{<:LatitudeLongitudeGrid}, arch, size, extent, topology) = LatitudeLongitudeGrid(arch; size, longitude = extent[1], latitude = extent[2], z = extent[3], topology) -# Regrid a field in three dimensions function three_dimensional_regrid!(a, b) target_grid = a.grid isa ImmersedBoundaryGrid ? a.grid.underlying_grid : a.grid source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid topo = topology(target_grid) - arch = architecture(target_grid) + arch = child_architecture(target_grid) target_y = yt = cpu_face_constructor_y(target_grid) target_z = zt = cpu_face_constructor_z(target_grid) From 5056409ef9b341926fcf7d27c5dcd2b532b86688 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:50:34 -0500 Subject: [PATCH 233/716] try a quarter degree on tartarus --- experiments/twelth_degree_latlong.jl | 46 ++++++++++++++++------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 89a90808..9e4cbf25 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -17,14 +17,16 @@ using Printf ##### Global Ocean at 1/12th of a degree ##### +bathymetry_file = "bathymetry_quarter.jld2" + # 100 vertical levels -z_faces = exponential_z_faces(Nz=40, depth=6000) +z_faces = exponential_z_faces(Nz=50, depth=6000) -Nx = 360 -Ny = 150 +Nx = 1440 +Ny = 600 Nz = length(z_faces) - 1 -arch = Distributed(CPU(), partition = Partition(4)) +arch = GPU() #Distributed(CPU(), partition = Partition(4)) grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), @@ -32,10 +34,10 @@ grid = load_balanced_regional_grid(arch; latitude = (-75, 75), longitude = (0, 360), halo = (7, 7, 7), - interpolation_passes = 10, + interpolation_passes = 20, minimum_depth = 10, connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea - bathymetry_file = "tmp.jld2") + bathymetry_file) @show grid @@ -77,6 +79,10 @@ function progress(sim) end ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) +ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(30days), + overwrite_existing = true, + filename = "test_out") # Simulation warm up! ocean.Δt = 10 @@ -84,26 +90,26 @@ ocean.stop_iteration = 1 wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -stop_time = 365days +stop_time = 5days coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) -time_step!(coupled_simulation) -time_step!(coupled_simulation) +# time_step!(coupled_simulation) +# time_step!(coupled_simulation) -jldsave("test_$(arch.local_rank).jld2", T = ocean.model.tracers.T, S = ocean.model.tracers.S) +# jldsave("test_$(arch.local_rank).jld2", T = ocean.model.tracers.T, S = ocean.model.tracers.S) -# run!(coupled_simulation) +run!(coupled_simulation) -# # Run the real simulation -# # -# # Now that the solution has adjusted to the bathymetry we can ramp up the time -# # step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.35 -# wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 10minutes, max_change = 1.1) -# ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +# Run the real simulation +# +# Now that the solution has adjusted to the bathymetry we can ramp up the time +# step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.35 +wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 10minutes, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) -# # Let's reset the maximum number of iterations -# coupled_model.ocean.stop_iteration = Inf +# Let's reset the maximum number of iterations +coupled_model.ocean.stop_time = 7200days -# run!(coupled_simulation) +run!(coupled_simulation) From 0947fcbb2d53706ebb3fb6c38449e0748978972c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:52:25 -0500 Subject: [PATCH 234/716] measure wall time --- experiments/twelth_degree_latlong.jl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 9e4cbf25..13686630 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -66,16 +66,22 @@ radiation = Radiation() coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) +wall_time = [time_ns()] + function progress(sim) u, v, w = sim.model.velocities T, S = sim.model.tracers - @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(T, S): %.2f, %.2f\n", + step_time = 1e-9 * (time_ns() - wall_time[1]) + + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", prettytime(sim.model.clock.time), sim.model.clock.iteration, prettytime(sim.Δt), maximum(abs, u), maximum(abs, v), maximum(abs, w), - maximum(abs, T), maximum(abs, S)) + maximum(abs, T), maximum(abs, S), step_time) + + wall_time[1] = time_ns() end ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) From 3f244a00e0aea36c9f6ee71d7a0100873d751f9b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:57:36 -0500 Subject: [PATCH 235/716] remove vestigial show --- src/Bathymetry.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 2921ef43..9f8bfd24 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -266,8 +266,6 @@ function remove_lakes!(h_data; connected_regions_allowed = Inf) return h_data end - @show connected_regions_allowed - bathtmp = deepcopy(h_data) batneg = zeros(Bool, size(bathtmp)...) From 870a98d04f89affcb37eb3faa2fbe5d6e104dd0d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:00:53 -0500 Subject: [PATCH 236/716] add a `barrier!` --- src/DataWrangling/ECCO2.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 0a13281a..0f9ba385 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -8,7 +8,7 @@ using ClimaOcean.InitialConditions: three_dimensional_regrid! using Oceananigans using Oceananigans.Architectures: architecture, child_architecture using Oceananigans.BoundaryConditions -using Oceananigans.DistributedComputations: DistributedField, all_reduce +using Oceananigans.DistributedComputations: DistributedField, all_reduce, barrier! using Oceananigans.Utils using KernelAbstractions: @kernel, @index using NCDatasets @@ -281,6 +281,8 @@ function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename=" empty_ecco2_field(ecco2_metadata; architecture = child_arch) end + barrier!(arch) + # Distribute ecco field to all workers parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) From 58a262fda7cfa1a4b4261f187e4941ec8596a881 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:20:43 -0500 Subject: [PATCH 237/716] ready to run --- experiments/twelth_degree_latlong.jl | 26 ++++++++++------------ src/InitialConditions/InitialConditions.jl | 3 ++- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 13686630..d7a0aee1 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -22,11 +22,11 @@ bathymetry_file = "bathymetry_quarter.jld2" # 100 vertical levels z_faces = exponential_z_faces(Nz=50, depth=6000) -Nx = 1440 -Ny = 600 +Nx = 360 +Ny = 150 Nz = length(z_faces) - 1 -arch = GPU() #Distributed(CPU(), partition = Partition(4)) +arch = Distributed(CPU(), partition = Partition(4)) grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), @@ -85,10 +85,17 @@ function progress(sim) end ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) + ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), schedule = TimeInterval(30days), overwrite_existing = true, - filename = "test_out") + array_type = Array{Float32}, + filename = "snapshots_$(arch.local_rank)") + +ocean.output_writers[:checkpoint] = Checkpointer(model, + schedule = TimeInterval(60days), + overwrite_existing = true, + prefix = "checkpoint_$(arch.local_rank)") # Simulation warm up! ocean.Δt = 10 @@ -100,18 +107,9 @@ stop_time = 5days coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) -# time_step!(coupled_simulation) -# time_step!(coupled_simulation) - -# jldsave("test_$(arch.local_rank).jld2", T = ocean.model.tracers.T, S = ocean.model.tracers.S) - run!(coupled_simulation) -# Run the real simulation -# -# Now that the solution has adjusted to the bathymetry we can ramp up the time -# step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.35 -wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 10minutes, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 270, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 40158fbb..35604ef6 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -35,7 +35,8 @@ function three_dimensional_regrid!(a, b) source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid topo = topology(target_grid) - arch = child_architecture(target_grid) + arch = architecture(target_grid) + arch = child_architecture(arch) target_y = yt = cpu_face_constructor_y(target_grid) target_z = zt = cpu_face_constructor_z(target_grid) From a692a742653d33d3d8c87609376327c76f20718e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 16:33:52 -0500 Subject: [PATCH 238/716] let ocean run with it's timestep --- src/OceanSeaIceModels/ocean_only_model.jl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 2d7b1bdc..c80ba452 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -6,6 +6,20 @@ OceanOnlyModel(ocean; kw...) = OceanSeaIceModel(nothing, ocean; kw...) ##### No ice-ocean fluxes in this model!! ##### +function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_tendencies=true) + ocean = coupled_model.ocean + + # Be paranoid and update state at iteration 0 + coupled_model.clock.iteration == 0 && update_state!(coupled_model, callbacks) + + time_step!(ocean) + + tick!(coupled_model.clock, Δt) + update_state!(coupled_model, callbacks; compute_tendencies) + + return nothing +end + #= compute_ice_ocean_salinity_flux!(::OceanOnlyModel) = nothing ice_ocean_latent_heat!(::OceanOnlyModel) = nothing From a94daf478a4c0c2dd3e376dd98c4a7e2385e7eac Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 16:39:13 -0500 Subject: [PATCH 239/716] oncean only timestepping --- src/OceanSeaIceModels/ocean_only_model.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index c80ba452..7e8c71d8 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -6,7 +6,7 @@ OceanOnlyModel(ocean; kw...) = OceanSeaIceModel(nothing, ocean; kw...) ##### No ice-ocean fluxes in this model!! ##### -function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_tendencies=true) +function time_step!(coupled_model::OceanOnlyModel, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean # Be paranoid and update state at iteration 0 From 86c87f74ef858e33fc326d7297f2c0121206af12 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:25:49 -0500 Subject: [PATCH 240/716] replace with zero --- src/Bathymetry.jl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 9f8bfd24..92263c00 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -170,8 +170,7 @@ function regrid_bathymetry(target_grid; target_h = interpolate_bathymetry_in_passes(native_h, target_grid; passes = interpolation_passes, connected_regions_allowed, - minimum_depth, - height_above_water) + minimum_depth) return target_h end @@ -180,8 +179,7 @@ end function interpolate_bathymetry_in_passes(native_h, target_grid; passes = 10, connected_regions_allowed = 3, - minimum_depth = 0, - height_above_water = nothing) + minimum_depth = 0) Nλt, Nφt = Nt = size(target_grid) Nλn, Nφn = Nn = size(native_h) @@ -230,7 +228,7 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; if minimum_depth > 0 shallow_ocean = h_data .> minimum_depth - h_data[shallow_ocean] .= height_above_water + h_data[shallow_ocean] .= 0 end h_data = remove_lakes!(h_data; connected_regions_allowed) From 743512edf983dbaeaeffd16f81c6ae7d7ec907e5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:30:21 -0500 Subject: [PATCH 241/716] small change --- .../ocean_sea_ice_surface_fluxes.jl | 1 - .../load_balanced_ocean_grid.jl | 24 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 89e96a24..b12207eb 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -146,7 +146,6 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) # Ocean, atmosphere, and sea ice state ocean_velocities = surface_velocities(ocean) ocean_tracers = surface_tracers(ocean) - ice_concentration = sea_ice_concentration(sea_ice) # Fluxes, and flux contributors centered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.uᶜᶜᶜ, diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index f38c91be..558b1cbf 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -50,7 +50,7 @@ function load_balanced_regional_grid(arch; z, halo = (3, 3, 3), maximum_size = nothing, - height_above_water = 1, + height_above_water = nothing, minimum_depth = 10, connected_regions_allowed = 3, interpolation_passes = 1, @@ -119,17 +119,17 @@ function load_balanced_regional_grid(arch::SlabDistributed; # so that we can write to file the bathymetry in case `!isnothing(bathymetry_file)` if arch.local_rank == 1 grid = load_balanced_regional_grid(child_arch; - size, - longitude, - latitude, - z, - halo, - maximum_size, - height_above_water, - minimum_depth, - interpolation_passes, - bathymetry_file, - connected_regions_allowed) + size, + longitude, + latitude, + z, + halo, + maximum_size, + height_above_water, + minimum_depth, + interpolation_passes, + bathymetry_file, + connected_regions_allowed) # TODO: fix the set! function for DistributedFields in Oceananigans # to work with non-distributed fields and Subarrays From 3c9d35f402ac3d86231e835a20f53a3c1d46f315 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:46:28 -0500 Subject: [PATCH 242/716] fill ecco halo regions --- src/DataWrangling/ECCO2.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 0f9ba385..58229a08 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -239,6 +239,8 @@ function inpainted_ecco2_field(variable_name; @info "In-painting ecco $variable_name and saving it in $filename" inpaint_mask!(f, mask; kw...) + fill_halo_regions!(f) + ds = Dataset(filename, "c") defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) @@ -249,11 +251,13 @@ function inpainted_ecco2_field(variable_name; if haskey(ds, string(variable_name)) data = ds[variable_name][:, :, :] f = ecco2_field(variable_name; architecture, user_data = data) + fill_halo_regions!(f) else f = ecco2_field(variable_name; architecture) # Make sure all values are inpainted properly @info "In-painting ecco $variable_name and saving it in $filename" inpaint_mask!(f, mask; kw...) + fill_halo_regions!(f) defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) end From bb9e5a06b6eae3ab8eba6253c2dd8cb377be70dd Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:12:56 -0500 Subject: [PATCH 243/716] first commit --- experiments/twelth_degree_latlong.jl | 16 ++++-- .../load_balanced_ocean_grid.jl | 57 +++++++++---------- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index d7a0aee1..d3c63260 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -12,12 +12,13 @@ using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using Printf +using JLD2 ##### ##### Global Ocean at 1/12th of a degree ##### -bathymetry_file = "bathymetry_quarter.jld2" +bathymetry_file = nothing # "bathymetry_quarter.jld2" # 100 vertical levels z_faces = exponential_z_faces(Nz=50, depth=6000) @@ -45,7 +46,7 @@ grid = load_balanced_regional_grid(arch; ##### The Ocean component ##### -free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=270) +free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=10minutes) ocean = ocean_simulation(grid; free_surface) model = ocean.model @@ -86,11 +87,18 @@ end ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) +ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(30days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "snapshots_$(arch.local_rank)") + ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(30days), + schedule = TimeInterval(1days), overwrite_existing = true, + indices = (:, :, grid.Nz), array_type = Array{Float32}, - filename = "snapshots_$(arch.local_rank)") + filename = "surface_$(arch.local_rank)") ocean.output_writers[:checkpoint] = Checkpointer(model, schedule = TimeInterval(60days), diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index 558b1cbf..cbb289cd 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -117,40 +117,37 @@ function load_balanced_regional_grid(arch::SlabDistributed; # Calculating the local halos on the global grid on rank 0 # so that we can write to file the bathymetry in case `!isnothing(bathymetry_file)` - if arch.local_rank == 1 - grid = load_balanced_regional_grid(child_arch; - size, - longitude, - latitude, - z, - halo, - maximum_size, - height_above_water, - minimum_depth, - interpolation_passes, - bathymetry_file, - connected_regions_allowed) - - # TODO: fix the set! function for DistributedFields in Oceananigans - # to work with non-distributed fields and Subarrays - bottom_height .= arch_array(CPU(), interior(grid.immersed_boundary.bottom_height)) - - # Starting with the load balancing - load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) - loop! = assess_load(device(child_arch), 512, size[idx]) - loop!(load_per_slab, grid, idx) - - load_per_slab = arch_array(CPU(), load_per_slab) - local_N = calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) - - # Limit the maximum size such that we do not have memory issues - redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) - end - + grid = load_balanced_regional_grid(child_arch; + size, + longitude, + latitude, + z, + halo, + maximum_size, + height_above_water, + minimum_depth, + interpolation_passes, + bathymetry_file, + connected_regions_allowed) + + # TODO: fix the set! function for DistributedFields in Oceananigans + # to work with non-distributed fields and Subarrays + bottom_height .= arch_array(CPU(), interior(grid.immersed_boundary.bottom_height)) + + # Starting with the load balancing + load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) + loop! = assess_load(device(child_arch), 512, size[idx]) + loop!(load_per_slab, grid, idx) + + load_per_slab = arch_array(CPU(), load_per_slab) + local_N .= calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) + barrier!(arch) bottom_height = all_reduce(+, bottom_height, arch) local_N = all_reduce(+, local_N, arch) + redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) + partition = idx == 1 ? Partition(x = Sizes(local_N...)) : Partition(y = Sizes(local_N...)) arch = Distributed(child_arch; partition) From 8ef9d74d3ca0afa71dc29170fefd3ce8fd6827ba Mon Sep 17 00:00:00 2001 From: Andre Nogueira Souza Date: Tue, 5 Mar 2024 19:14:04 -0500 Subject: [PATCH 244/716] working --- experiments/twelth_degree_latlong.jl | 62 ++++++++++++++++------------ 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index d3c63260..fcf67cb6 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -1,3 +1,6 @@ +using MPI +MPI.Init() + using Oceananigans using Oceananigans: architecture using ClimaOcean @@ -18,27 +21,39 @@ using JLD2 ##### Global Ocean at 1/12th of a degree ##### -bathymetry_file = nothing # "bathymetry_quarter.jld2" +bathymetry_file = "bathymetry12.jld2" # 100 vertical levels -z_faces = exponential_z_faces(Nz=50, depth=6000) +z_faces = exponential_z_faces(Nz=100, depth=6000) -Nx = 360 -Ny = 150 +Nx = 4320 +Ny = 1800 Nz = length(z_faces) - 1 -arch = Distributed(CPU(), partition = Partition(4)) - -grid = load_balanced_regional_grid(arch; - size = (Nx, Ny, Nz), - z = z_faces, - latitude = (-75, 75), - longitude = (0, 360), - halo = (7, 7, 7), - interpolation_passes = 20, - minimum_depth = 10, - connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea - bathymetry_file) +arch = Distributed(GPU(), partition = Partition(8)) + +grid = LatitudeLongitudeGrid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + latitude = (-75, 75), + longitude = (0, 360), + halo = (7, 7, 7)) + +bathymetry = jldopen(bathymetry_file)["bathymetry"] + +@show size(bathymetry) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bathymetry); active_cells_map = true) + +# grid = load_balanced_regional_grid(arch; +# size = (Nx, Ny, Nz), +# z = z_faces, +# latitude = (-75, 75), +# longitude = (0, 360), +# halo = (7, 7, 7), +# interpolation_passes = 20, +# minimum_depth = 10, +# connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea +# bathymetry_file) @show grid @@ -46,7 +61,7 @@ grid = load_balanced_regional_grid(arch; ##### The Ocean component ##### -free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=10minutes) +free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=270) ocean = ocean_simulation(grid; free_surface) model = ocean.model @@ -61,7 +76,7 @@ set!(model, ##### The atmosphere ##### -backend = JRA55NetCDFBackend(10) +backend = JRA55NetCDFBackend(5) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation() @@ -87,18 +102,11 @@ end ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) -ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(30days), - overwrite_existing = true, - array_type = Array{Float32}, - filename = "snapshots_$(arch.local_rank)") - ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(1days), + schedule = TimeInterval(30days), overwrite_existing = true, - indices = (:, :, grid.Nz), array_type = Array{Float32}, - filename = "surface_$(arch.local_rank)") + filename = "snapshots_$(arch.local_rank)") ocean.output_writers[:checkpoint] = Checkpointer(model, schedule = TimeInterval(60days), From 852efa2460249c1f47a511ccf6e27223edd7a070 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:15:26 -0500 Subject: [PATCH 245/716] let's see --- experiments/twelth_degree_latlong.jl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index fcf67cb6..aeb2e1f0 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -21,6 +21,30 @@ using JLD2 ##### Global Ocean at 1/12th of a degree ##### +import Oceananigans.Fields: set! +using Oceananigans.DistributedComputations: DistributedField + +# Automatically partition under the hood if sizes are compatible +function set!(u::DistributedField, v::Array) + gsize = global_size(architecture(u), size(u)) + + @show gsize, size(v) + if size(v) == gsize + f = partition_global_array(architecture(u), v, size(u)) + u .= f + return u + else + try + f = on_architecture(architecture(u), v) + u .= f + return u + + catch + throw(ArgumentError("ERROR: DimensionMismatch: array could not be set to match destination field")) + end + end + end + bathymetry_file = "bathymetry12.jld2" # 100 vertical levels From 0447f4aefa63cec42146a15b3600b67eb6337040 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:17:41 -0500 Subject: [PATCH 246/716] try --- experiments/twelth_degree_latlong.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index aeb2e1f0..90cb9134 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -22,7 +22,8 @@ using JLD2 ##### import Oceananigans.Fields: set! -using Oceananigans.DistributedComputations: DistributedField +using Oceananigans.DistributedComputations: DistributedField, global_size, partition_global_array +using Oceananigans.Architectures: on_architecture, architecture # Automatically partition under the hood if sizes are compatible function set!(u::DistributedField, v::Array) From 495e6869de85888b9dbfae33385a553c7a5adb90 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:19:58 -0500 Subject: [PATCH 247/716] uff --- experiments/twelth_degree_latlong.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 90cb9134..dd53aafd 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -22,8 +22,9 @@ using JLD2 ##### import Oceananigans.Fields: set! +using Oceananigans.Grids: on_architecture using Oceananigans.DistributedComputations: DistributedField, global_size, partition_global_array -using Oceananigans.Architectures: on_architecture, architecture +using Oceananigans.Architectures: architecture # Automatically partition under the hood if sizes are compatible function set!(u::DistributedField, v::Array) From d1964aebb986a71cad31ac86a0c9aca3921ff6f1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:25:20 -0500 Subject: [PATCH 248/716] try like this? --- experiments/twelth_degree_latlong.jl | 53 ++++++++++++++-------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index dd53aafd..8c41ad21 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -21,31 +21,31 @@ using JLD2 ##### Global Ocean at 1/12th of a degree ##### -import Oceananigans.Fields: set! -using Oceananigans.Grids: on_architecture -using Oceananigans.DistributedComputations: DistributedField, global_size, partition_global_array -using Oceananigans.Architectures: architecture - -# Automatically partition under the hood if sizes are compatible -function set!(u::DistributedField, v::Array) - gsize = global_size(architecture(u), size(u)) +# import Oceananigans.Fields: set! +# using Oceananigans.Grids: on_architecture +# using Oceananigans.DistributedComputations: DistributedField, global_size, partition_global_array +# using Oceananigans.Architectures: architecture + +# # Automatically partition under the hood if sizes are compatible +# function set!(u::DistributedField, v::Array) +# gsize = global_size(architecture(u), size(u)) - @show gsize, size(v) - if size(v) == gsize - f = partition_global_array(architecture(u), v, size(u)) - u .= f - return u - else - try - f = on_architecture(architecture(u), v) - u .= f - return u +# @show gsize, size(v) +# if size(v) == gsize +# f = partition_global_array(architecture(u), v, size(u)) +# u .= f +# return u +# else +# try +# f = on_architecture(architecture(u), v) +# u .= f +# return u - catch - throw(ArgumentError("ERROR: DimensionMismatch: array could not be set to match destination field")) - end - end - end +# catch +# throw(ArgumentError("ERROR: DimensionMismatch: array could not be set to match destination field")) +# end +# end +# end bathymetry_file = "bathymetry12.jld2" @@ -56,6 +56,8 @@ Nx = 4320 Ny = 1800 Nz = length(z_faces) - 1 +bottom = zeros(Nx, Ny, 1) + arch = Distributed(GPU(), partition = Partition(8)) grid = LatitudeLongitudeGrid(arch; @@ -65,10 +67,9 @@ grid = LatitudeLongitudeGrid(arch; longitude = (0, 360), halo = (7, 7, 7)) -bathymetry = jldopen(bathymetry_file)["bathymetry"] +bottom .= jldopen(bathymetry_file)["bathymetry"] -@show size(bathymetry) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bathymetry); active_cells_map = true) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom); active_cells_map = true) # grid = load_balanced_regional_grid(arch; # size = (Nx, Ny, Nz), From 32eb73c9365981c4c3ae09d139903df4f95fd381 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:28:42 -0500 Subject: [PATCH 249/716] Try it on CPU --- experiments/twelth_degree_latlong.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 8c41ad21..8bc1da3b 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -58,7 +58,7 @@ Nz = length(z_faces) - 1 bottom = zeros(Nx, Ny, 1) -arch = Distributed(GPU(), partition = Partition(8)) +arch = Distributed(CPU(), partition = Partition(8)) grid = LatitudeLongitudeGrid(arch; size = (Nx, Ny, Nz), From 8145778b5786ae3aad89ac78a1de2eee15745d56 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:33:29 -0500 Subject: [PATCH 250/716] better --- src/Bathymetry.jl | 36 ++++++++- .../load_balanced_ocean_grid.jl | 73 ++++++++----------- 2 files changed, 64 insertions(+), 45 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 92263c00..db297146 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -1,6 +1,6 @@ module Bathymetry -export regrid_bathymetry +export regrid_bathymetry, retrieve_bathymetry using ImageMorphology using ..DataWrangling: download_progress @@ -310,5 +310,39 @@ function remove_lakes!(h_data; connected_regions_allowed = Inf) return bathtmp end + +""" + retrieve_bathymetry(grid, filename; kw...) + +Retrieve the bathymetry data from a file or generate it using a grid and save it to a file. + +# Arguments +============ + +- `grid`: The grid used to generate the bathymetry data. +- `filename`: The name of the file to read or save the bathymetry data. +- `kw...`: Additional keyword arguments. + +# Returns +=========== +- `bottom_height`: The retrieved or generated bathymetry data. + +If the specified file exists, the function reads the bathymetry data from the file. +Otherwise, it generates the bathymetry data using the provided grid and saves it to the file before returning it. +""" +function retrieve_bathymetry(grid, filename; kw...) + + if isfile(filename) + bottom_height = jldopen(bathymetry_file)["bathymetry"] + else + bottom_height = regrid_bathymetry(grid; kw...) + jldsave(filename, bathymetry = Array(interior(bottom_height))) + end + + return bottom_height +end + +retrieve_bathymetry(grid, ::Nothing; kw...) = regrid_bathymetry(grid; kw...) + end # module diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index cbb289cd..e2ad92ea 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -63,29 +63,13 @@ function load_balanced_regional_grid(arch; z, halo) - if !isnothing(bathymetry_file) - if isfile(bathymetry_file) - bottom_height = jldopen(bathymetry_file)["bathymetry"] - return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) - else - bottom_height = regrid_bathymetry(grid; - height_above_water, - minimum_depth, - interpolation_passes, - connected_regions_allowed) - - jldsave(bathymetry_file, bathymetry = Array(interior(bottom_height))) - return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) - end - else - bottom_height = regrid_bathymetry(grid; - height_above_water, - minimum_depth, - interpolation_passes, - connected_regions_allowed) - - return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) - end + bottom_height = retrieve_bathymetry(grid, bathymetry_file; + height_above_water, + minimum_depth, + interpolation_passes, + connected_regions_allowed) + + return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end const SlabPartition = Union{Partition{<:Any, <:Nothing, <:Nothing}, @@ -112,27 +96,30 @@ function load_balanced_regional_grid(arch::SlabDistributed; # index of the partitioned direction idx = arch.ranks[1] == 1 ? 2 : 1 - local_N = zeros(Int, arch.ranks[idx]) - bottom_height = zeros(size[1], size[2], 1) + grid = LatitudeLongitudeGrid(child_arch; + size, + longitude, + latitude, + z, + halo) - # Calculating the local halos on the global grid on rank 0 + # Calculating the global bottom on the global grid on rank 0 # so that we can write to file the bathymetry in case `!isnothing(bathymetry_file)` - grid = load_balanced_regional_grid(child_arch; - size, - longitude, - latitude, - z, - halo, - maximum_size, - height_above_water, - minimum_depth, - interpolation_passes, - bathymetry_file, - connected_regions_allowed) - - # TODO: fix the set! function for DistributedFields in Oceananigans - # to work with non-distributed fields and Subarrays - bottom_height .= arch_array(CPU(), interior(grid.immersed_boundary.bottom_height)) + bottom_height = if arch.local_rank == 0 + bathymetry = retrieve_bathymetry(grid, bathymetry_file; + height_above_water, + minimum_depth, + interpolation_passes, + connected_regions_allowed) + arch_array(CPU(), interior(bathymetry)) + else + zeros(size[1], size[2], 1) + end + + barrier!(arch) + bottom_height .= all_reduce(+, bottom_height, arch) + + grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) # Starting with the load balancing load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) @@ -142,8 +129,6 @@ function load_balanced_regional_grid(arch::SlabDistributed; load_per_slab = arch_array(CPU(), load_per_slab) local_N .= calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) - barrier!(arch) - bottom_height = all_reduce(+, bottom_height, arch) local_N = all_reduce(+, local_N, arch) redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) From 30a4bee009dca0af9b4ac5518188769022c07436 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:41:05 -0500 Subject: [PATCH 251/716] hmmm --- experiments/twelth_degree_latlong.jl | 2 +- .../load_balanced_ocean_grid.jl | 35 +++++++++++-------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 8bc1da3b..8c41ad21 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -58,7 +58,7 @@ Nz = length(z_faces) - 1 bottom = zeros(Nx, Ny, 1) -arch = Distributed(CPU(), partition = Partition(8)) +arch = Distributed(GPU(), partition = Partition(8)) grid = LatitudeLongitudeGrid(arch; size = (Nx, Ny, Nz), diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_ocean_grid.jl index e2ad92ea..68d187d3 100644 --- a/src/OceanSimulations/load_balanced_ocean_grid.jl +++ b/src/OceanSimulations/load_balanced_ocean_grid.jl @@ -105,34 +105,39 @@ function load_balanced_regional_grid(arch::SlabDistributed; # Calculating the global bottom on the global grid on rank 0 # so that we can write to file the bathymetry in case `!isnothing(bathymetry_file)` - bottom_height = if arch.local_rank == 0 - bathymetry = retrieve_bathymetry(grid, bathymetry_file; - height_above_water, - minimum_depth, - interpolation_passes, - connected_regions_allowed) - arch_array(CPU(), interior(bathymetry)) - else - zeros(size[1], size[2], 1) - end + bottom_height = retrieve_bathymetry(grid, bathymetry_file; + height_above_water, + minimum_depth, + interpolation_passes, + connected_regions_allowed) barrier!(arch) - bottom_height .= all_reduce(+, bottom_height, arch) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - # Starting with the load balancing + # Calculating the load for each i slab if XPartition or j slab if YPartition load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) loop! = assess_load(device(child_arch), 512, size[idx]) loop!(load_per_slab, grid, idx) - load_per_slab = arch_array(CPU(), load_per_slab) - local_N .= calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) + load_per_slab = arch_array(CPU(), load_per_slab) + + # Redistribute the load to have the same number of + # immersed cells in each core + local_N = if ifelse arch.local_rank == 0 + calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) + else + zeros(Int, arch.ranks[idx]) + end + + barrier!(arch) + local_N = all_reduce(+, local_N, arch) - local_N = all_reduce(+, local_N, arch) + @show local_N redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) + # Partition either x or y depending on the original partition direction partition = idx == 1 ? Partition(x = Sizes(local_N...)) : Partition(y = Sizes(local_N...)) arch = Distributed(child_arch; partition) From ca0121662c108e74abd4b231e17a2624e2c4096d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:41:56 -0500 Subject: [PATCH 252/716] rename file --- src/OceanSimulations/OceanSimulations.jl | 2 +- ...ad_balanced_ocean_grid.jl => load_balanced_regional_grid.jl} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/OceanSimulations/{load_balanced_ocean_grid.jl => load_balanced_regional_grid.jl} (100%) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index ca7a42e5..974e9914 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -15,7 +15,7 @@ using SeawaterPolynomials.TEOS10: TEOS10EquationOfState using Oceananigans.BuoyancyModels: g_Earth using Oceananigans.Coriolis: Ω_Earth -include("load_balanced_ocean_grid.jl") +include("load_balanced_regional_grid.jl") # Some defualts default_free_surface(grid) = SplitExplicitFreeSurface(; cfl=0.7, grid) diff --git a/src/OceanSimulations/load_balanced_ocean_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl similarity index 100% rename from src/OceanSimulations/load_balanced_ocean_grid.jl rename to src/OceanSimulations/load_balanced_regional_grid.jl From 247d68547a039b99c64ea38361b38985541ae15b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:43:25 -0500 Subject: [PATCH 253/716] try it now? --- experiments/twelth_degree_latlong.jl | 42 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 8c41ad21..3e8080d2 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -60,27 +60,27 @@ bottom = zeros(Nx, Ny, 1) arch = Distributed(GPU(), partition = Partition(8)) -grid = LatitudeLongitudeGrid(arch; - size = (Nx, Ny, Nz), - z = z_faces, - latitude = (-75, 75), - longitude = (0, 360), - halo = (7, 7, 7)) - -bottom .= jldopen(bathymetry_file)["bathymetry"] - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom); active_cells_map = true) - -# grid = load_balanced_regional_grid(arch; -# size = (Nx, Ny, Nz), -# z = z_faces, -# latitude = (-75, 75), -# longitude = (0, 360), -# halo = (7, 7, 7), -# interpolation_passes = 20, -# minimum_depth = 10, -# connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea -# bathymetry_file) +# grid = LatitudeLongitudeGrid(arch; +# size = (Nx, Ny, Nz), +# z = z_faces, +# latitude = (-75, 75), +# longitude = (0, 360), +# halo = (7, 7, 7)) + +# bottom .= jldopen(bathymetry_file)["bathymetry"] + +# grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom); active_cells_map = true) + +grid = load_balanced_regional_grid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + latitude = (-75, 75), + longitude = (0, 360), + halo = (7, 7, 7), + interpolation_passes = 20, + minimum_depth = 10, + connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea + bathymetry_file) @show grid From 7fa09249d1cb408cb7edf019976554189c119c2b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:44:47 -0500 Subject: [PATCH 254/716] more changes --- experiments/twelth_degree_latlong.jl | 2 +- src/OceanSimulations/OceanSimulations.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 3e8080d2..ee84027d 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -90,7 +90,7 @@ grid = load_balanced_regional_grid(arch; free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=270) -ocean = ocean_simulation(grid; free_surface) +ocean = ocean_simulation(grid; Δt = 10, free_surface) model = ocean.model # Initializing the model diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 974e9914..aca0bc19 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -36,7 +36,7 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), # 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; +function ocean_simulation(grid; Δt = 5minutes, closure = default_ocean_closure(), free_surface = default_free_surface(grid), reference_density = 1020, @@ -85,7 +85,7 @@ function ocean_simulation(grid; coriolis, boundary_conditions = ocean_boundary_conditions) - ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) + ocean = Simulation(ocean_model; Δt, verbose=false) return ocean end From e1f79176a37ed31eaf29025bfac422ff7ae99866 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:45:24 -0500 Subject: [PATCH 255/716] bugfix --- src/Bathymetry.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index db297146..7ba6e698 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -14,6 +14,7 @@ using Oceananigans.Utils: pretty_filesize, launch! using Oceananigans.Fields: interpolate! using Oceananigans.BoundaryConditions using KernelAbstractions: @kernel, @index +using JLD2 using NCDatasets using Downloads From d99a93a6ad1c88d1adec3765e2fb8af6453acedc Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:47:47 -0500 Subject: [PATCH 256/716] other bugfix --- src/Bathymetry.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 7ba6e698..2a6326bd 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -334,7 +334,7 @@ Otherwise, it generates the bathymetry data using the provided grid and saves it function retrieve_bathymetry(grid, filename; kw...) if isfile(filename) - bottom_height = jldopen(bathymetry_file)["bathymetry"] + bottom_height = jldopen(filename)["bathymetry"] else bottom_height = regrid_bathymetry(grid; kw...) jldsave(filename, bathymetry = Array(interior(bottom_height))) From 155191d3d55e7c8a6f592c179b0f4ef952ba7382 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:07:42 -0500 Subject: [PATCH 257/716] better inpaint --- src/DataWrangling/inpaint_mask.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DataWrangling/inpaint_mask.jl b/src/DataWrangling/inpaint_mask.jl index c6ea8c45..f5a3df19 100644 --- a/src/DataWrangling/inpaint_mask.jl +++ b/src/DataWrangling/inpaint_mask.jl @@ -76,6 +76,8 @@ function propagate_horizontally!(field, mask, tmp_field=deepcopy(field); max_ite @debug "Propagate pass $iter with sum $(sum(parent(field)))" end + fill_halo_regions!(field) + return field end From 2404cadb1b146d6c16637f6490f6dcf6cd0af663 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:10:01 -0500 Subject: [PATCH 258/716] add comment --- src/Bathymetry.jl | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 2a6326bd..372457a9 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -242,7 +242,9 @@ end """ remove_lakes!(h_data; connected_regions_allowed = Inf) -Remove lakes from the bathymetric data stored in `h_data`. +Remove lakes from the bathymetry data stored in `h_data`, by identifying connected regions below sea level +and removing all but the specified number of largest connected regions (which represent the ocean and +other possibly disconnected regions like the Mediterranean and the Bering sea). # Arguments ============ @@ -251,12 +253,6 @@ Remove lakes from the bathymetric data stored in `h_data`. - `connected_regions_allowed`: The maximum number of connected regions to keep. Default is `Inf`, which means all connected regions are kept. -# Returns -========= - -The function removes lakes from the bathymetry data by identifying connected regions below sea level -and removing all but the specified number of largest connected regions (which represent the ocean and -other possibly disconnected regions like the Mediterranean and the Bering sea). """ function remove_lakes!(h_data; connected_regions_allowed = Inf) From cb23185e91f9764a976466e7884d9e16c352f31d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:12:34 -0500 Subject: [PATCH 259/716] remove vestigial code --- .../CATKE_column_simulations/Manifest.toml | 1696 ------------ .../CATKE_column_simulations/Project.toml | 3 - .../CATKE_column_simulations/take_a_look.jl | 14 - .../prototype_omip_simulation/Manifest.toml | 2288 ---------------- .../prototype_omip_simulation/Project.toml | 17 - .../freely_decaying_regional_simulation.jl | 147 -- .../omip_components.jl | 272 -- .../omip_sea_ice_component.jl | 0 .../omip_simulation.jl | 311 --- .../plot_freely_decaying_simulation.jl | 40 - .../regional_omip_simulation.jl | 174 -- .../single_column_omip_simulation.jl | 342 --- .../surface_fluxes.jl | 209 -- .../test_field_time_series.jl | 37 - .../test_single_column_omip_simulation.jl | 166 -- .../updated_Manifest.toml | 2290 ----------------- 16 files changed, 8006 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/Manifest.toml delete mode 100644 experiments/prototype_omip_simulation/Project.toml delete mode 100644 experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl delete mode 100644 experiments/prototype_omip_simulation/omip_components.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/plot_freely_decaying_simulation.jl delete mode 100644 experiments/prototype_omip_simulation/regional_omip_simulation.jl delete mode 100644 experiments/prototype_omip_simulation/single_column_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/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml deleted file mode 100644 index a1639eaa..00000000 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ /dev/null @@ -1,2288 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.0" -manifest_format = "2.0" -project_hash = "2a1113e8d87161459303d19589de1d2641041954" - -[[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.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", "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"] -path = "/Users/gregorywagner/Projects/Oceananigans.jl" -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", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+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/experiments/prototype_omip_simulation/Project.toml b/experiments/prototype_omip_simulation/Project.toml deleted file mode 100644 index deaf8c37..00000000 --- a/experiments/prototype_omip_simulation/Project.toml +++ /dev/null @@ -1,17 +0,0 @@ -[deps] -CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" -ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" -Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" -Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" - -[compat] -GLMakie = "0.9" -Oceananigans = "0.90.6" diff --git a/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl b/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl deleted file mode 100644 index 23585c82..00000000 --- a/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl +++ /dev/null @@ -1,147 +0,0 @@ -using Oceananigans -using Oceananigans.Architectures: arch_array -using Oceananigans.Units -using Oceananigans.BuoyancyModels: buoyancy_frequency -using Oceananigans.Units: Time - -using ClimaOcean -using ClimaOcean.OceanSeaIceModels: Radiation -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere -using ClimaOcean.DataWrangling.ECCO2: ecco2_field - -# using GLMakie -using Printf -using Dates - -start_time = time_ns() - -include("omip_components.jl") - -arch = CPU() -epoch = Date(1992, 1, 1) -date = Date(1992, 10, 1) -start_seconds = Second(date - epoch).value -Te = ecco2_field(:temperature, date) -Se = ecco2_field(:salinity, date) -# ℋe = ecco2_field(:sea_ice_thickness, date) - -land = interior(Te) .< -10 -interior(Te)[land] .= NaN -interior(Se)[land] .= NaN - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### - -latitude = (-80, -20) -longitude = (0, 360) - -i₁ = 4 * first(longitude) + 1 -i₂ = 1440 - 4 * (360 - last(longitude)) -Nx = i₂ - i₁ + 1 - -j₁ = 4 * (90 + first(latitude)) + 1 -j₂ = 720 - 4 * (90 - last(latitude)) -Ny = j₂ - j₁ + 1 - -zc = znodes(Te) -zf = znodes(Te.grid, Face()) -Δz = first(zspacings(Te.grid, Center())) - -Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) -Sᵢ = interior(Se, i₁:i₂, j₁:j₂, :) -# ℋᵢ = interior(ℋe, i₁:i₂, j₁:j₂, :) - -# Construct bottom_height depth by analyzing T -Nx, Ny, Nz = size(Tᵢ) -bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) - -for i = 1:Nx, j = 1:Ny - @inbounds for k = Nz:-1:1 - if isnan(Tᵢ[i, j, k]) - bottom_height[i, j] = zf[k+1] - break - end - end -end - -Tᵢ = arch_array(arch, Tᵢ) -Sᵢ = arch_array(arch, Sᵢ) -# ℋᵢ = arch_array(arch, ℋᵢ) - -if longitude[2] - longitude[1] == 360 - TX = Periodic -else - TX = Bounded -end - -grid = LatitudeLongitudeGrid(arch; latitude, longitude, - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = zf, - topology = (Periodic, Bounded, Bounded)) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - -#= -ocean = omip_ocean_component(grid) -sea_ice = omip_sea_ice_component(ocean.model) - -coupled_model = OceanSeaIceModel(ocean, sea_ice) -stop_time = 4 * 360days -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=stop_time) - -set!(sea_ice.model, h=ℋᵢ) -#set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) -set!(ocean.model, T=Tᵢ, S=Sᵢ) - -wall_clock = Ref(time_ns()) - -function progress(sim) - msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg *= string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", maximum(T), minimum(T)) - msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) - - # e = sim.model.ocean.model.tracers.e - # msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) - - @info msg -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -N² = buoyancy_frequency(ocean.model) -κᶜ = ocean.model.diffusivity_fields.κᶜ -auxiliary_fields = (; N², κᶜ) -fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) - -filename = "free_decay_heat_only_cold_ice_surface" - -coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; - filename = filename * "_fields", - indices = (:, :, Nz), - schedule = TimeInterval(10days), - overwrite_existing = true) - -coupled_simulation.output_writers[:seaice] = JLD2OutputWriter(sea_ice.model, (; h = sea_ice.model.ice_thickness); - filename = filename * "_sea_ice_thickness", - schedule = TimeInterval(10days), - overwrite_existing = true) - -run!(coupled_simulation) -=# diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl deleted file mode 100644 index fa3f2ea9..00000000 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ /dev/null @@ -1,272 +0,0 @@ - using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: - CATKEVerticalDiffusivity, - MixingLength, - TurbulentKineticEnergyEquation - -using Oceananigans.Architectures: architecture -using Oceananigans.Grids: halo_size, topology, φnodes, λnodes, znode -using Oceananigans.Fields: ConstantField, ZeroField, interpolate! -using Oceananigans.Utils: launch! - -using ClimaSeaIce -using ClimaSeaIce.HeatBoundaryConditions: IceWaterThermalEquilibrium - -using KernelAbstractions: @kernel, @index - -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState - -#= -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), - z = znodes(ecco_2_temperature_field.grid, Face()), - resolution = 1/4, # degree - halo = (7, 7, 7)) - - start_time = time_ns() - - Te = ecco_2_temperature_field - launch!(architecture(Te), Te.grid, :xyz, nan_land!, Te) - - ΔΛ = last(longitude) - first(longitude) - ΔΦ = last(latitude) - first(latitude) - Nx = Int(ΔΛ / resolution) - Ny = Int(ΔΦ / resolution) - - Nz = length(z) - 1 - grid = LatitudeLongitudeGrid(arch; latitude, longitude, halo, - size = (Nx, Ny, Nz), - z = z) - - Tᵢ = CenterField(grid) - interpolate!(Tᵢ, Te) - - bottom_height = Field{Center, Center, Nothing}(grid) - set!(bottom_height, -Inf) - - # Construct bottom_height depth by analyzing T - launch!(arch, grid, :xy, infer_bottom_height!, bottom_height, Tᵢ, grid) - - grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - - #= - 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, Tᵢ -end - -function omip_ocean_component(grid; - closure = :default, - passive_tracers = tuple()) - - start_time = time_ns() - - top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) - top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) - top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) - top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(grid) - - ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), - v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), - T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), - S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) - - # Model construction - teos10 = TEOS10EquationOfState() - buoyancy = SeawaterBuoyancy(equation_of_state=teos10) - - Nx, Ny, Nz = size(grid) - - if Nx == Ny == 1 - tracer_advection = nothing - momentum_advection = nothing - else - tracer_advection = WENO() - momentum_advection = VectorInvariant(vorticity_scheme = WENO(), - divergence_scheme = WENO(), - vertical_scheme = WENO()) - end - - tracers = tuple(:T, :S, passive_tracers...) - - if closure == :default - - 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ˢᵖ) - - closure = CATKEVerticalDiffusivity(; mixing_length, - turbulent_kinetic_energy_equation, - maximum_tracer_diffusivity = 1e-1, - maximum_tke_diffusivity = 1e-1, - maximum_viscosity = 1e-1, - negative_turbulent_kinetic_energy_damping_time_scale = 30, - minimum_turbulent_kinetic_energy = 1e-6, - minimum_convective_buoyancy_flux = 1e-11) - - tracers = tuple(:e, tracers...) - end - - ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, tracers, - tracer_advection, momentum_advection, - free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), - boundary_conditions = ocean_boundary_conditions, - coriolis = HydrostaticSphericalCoriolis()) - - ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) - - elapsed = time_ns() - start_time - msg = string("Finished building ocean component (" * prettytime(elapsed * 1e-9), ").") - @info msg - - return ocean -end - -function omip_sea_ice_component(ocean_model) - start_time = time_ns() - - ocean_grid = ocean_model.grid - Nx, Ny, Nz = size(ocean_grid) - Hx, Hy, Hz = halo_size(ocean_grid) - TX, TY, TZ = topology(ocean_grid) - - λ = λnodes(ocean_grid, Face()) - φ = φnodes(ocean_grid, Face()) - longitude = (λ[1], λ[end]) - latitude = (φ[1], φ[end]) - - sea_ice_grid = LatitudeLongitudeGrid(arch; longitude, latitude, - size = (Nx, Ny), - halo = (Hx, Hy), - topology = (TX, TY, Flat)) - - if ocean_grid isa ImmersedBoundaryGrid - h = ocean_grid.immersed_boundary.bottom_height - land = interior(h) .>= 0 - sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBoundary(land)) - end - - sea_ice_ocean_heat_flux = Field{Center, Center, Nothing}(ocean_grid) - - Nz = size(ocean_grid, 3) - So = ocean_model.tracers.S - ocean_surface_salinity = view(So, :, :, Nz) - bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) - - u, v, w = ocean_model.velocities - ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), - v = view(v, :, :, Nz), #interior(v, :, :, Nz), - w = ZeroField()) - - sea_ice_model = SlabSeaIceModel(sea_ice_grid; - velocities = ocean_surface_velocities, - advection = WENO(), - ice_consolidation_thickness = 0.05, - ice_salinity = 4, - internal_heat_flux = ConductiveFlux(conductivity=2), - top_heat_flux = ConstantField(0), # W m⁻² - top_heat_boundary_condition = PrescribedTemperature(-10), - bottom_heat_boundary_condition = bottom_bc, - bottom_heat_flux = sea_ice_ocean_heat_flux) - - sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) - - elapsed = time_ns() - start_time - msg = string("Finished building sea ice component (" * prettytime(elapsed * 1e-9), ").") - @info msg - - return sea_ice -end - -const c = Center() -const f = Face() - -@kernel function infer_bottom_height!(bottom_height, T, grid) - i, j = @index(Global, NTuple) - - Nz = size(grid, 3) - - @inbounds for k = Nz:-1:1 - if isnan(T[i, j, k]) - bottom_height[i, j] = znode(i, j, k+1, grid, c, c, f) - break - end - end -end - -@kernel function nan_land!(T) - i, j, k = @index(Global, NTuple) - - @inbounds begin - Tᵢ = T[i, j, k] - land = Tᵢ < -10 - T[i, j, k] = ifelse(land, NaN, Tᵢ) - end -end diff --git a/experiments/prototype_omip_simulation/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/plot_freely_decaying_simulation.jl b/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl deleted file mode 100644 index 9238a70f..00000000 --- a/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index bf9bce40..00000000 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ /dev/null @@ -1,174 +0,0 @@ -using Oceananigans -using Oceananigans.Architectures: arch_array -using Oceananigans.Units -using Oceananigans.BuoyancyModels: buoyancy_frequency -using Oceananigans.Units: Time - -using ClimaOcean -using ClimaOcean.OceanSeaIceModels: Radiation, FreezingLimitedOceanTemperature -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend -using ClimaOcean.DataWrangling.ECCO2: ecco2_field - -using ClimaSeaIce: LinearLiquidus - -# using GLMakie -using Printf -using Dates - -start_time = time_ns() - -include("omip_components.jl") - -arch = CPU() - -##### -##### Construct initial conditions + grid -##### - -epoch = Date(1992, 1, 1) -date = Date(1992, 1, 2) -start_seconds = Second(date - epoch).value -Te = ecco2_field(:temperature, date, architecture=arch) - -latitude = (-75, -70) -grid, Tᵢ = regional_omip_grid(arch, Te; latitude) - -backend = JRA55NetCDFBackend(8) # InMemory(8) -atmosphere = JRA55_prescribed_atmosphere(arch, 1:56; backend) -radiation = Radiation() - -#closure = RiBasedVerticalDiffusivity(maximum_diffusivity=1e2, maximum_viscosity=1e2) -#closure = RiBasedVerticalDiffusivity() -closure = :default -ocean = omip_ocean_component(grid; closure) -@show size(Tᵢ) ocean.model.grid -set!(ocean.model, T=Tᵢ) #, S=Sᵢ) - -Se = ecco2_field(:salinity, date, architecture=arch) -interpolate!(ocean.model.tracers.S, Se) - -if :e ∈ keys(ocean.model.tracers) - set!(ocean.model, e=1e-6) -end - -sea_ice = FreezingLimitedOceanTemperature(LinearLiquidus(eltype(grid))) - -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_model.clock.time = start_seconds -stop_time = start_seconds + 30days -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=stop_time) - -elapsed = 1e-9 * (time_ns() - start_time) -@info string("Coupled simulation built ", prettytime(elapsed), ".") -start_time = time_ns() - -wall_clock = Ref(time_ns()) - -# Hm... - -function clip_diffusivity(coupled_simulation) - ocean_model = coupled_simulation.model.ocean.model - κᶜ = parent(ocean_model.diffusivity_fields.κᶜ) - κᵘ = parent(ocean_model.diffusivity_fields.κᵘ) - @. κᶜ = min(κᶜ, 100) - @. κᵘ = min(κᵘ, 100) - return nothing -end - -coupled_simulation.callbacks[:clip] = Callback(clip_diffusivity) - -##### -##### Progress -##### - -Jᵘ = coupled_model.fluxes.total.ocean.momentum.u -Jᵛ = coupled_model.fluxes.total.ocean.momentum.v -Jᵀ = coupled_model.fluxes.total.ocean.tracers.T -Jˢ = coupled_model.fluxes.total.ocean.tracers.S -Fv = coupled_model.fluxes.turbulent.fields.water_vapor -Qc = coupled_model.fluxes.turbulent.fields.sensible_heat -Qv = coupled_model.fluxes.turbulent.fields.latent_heat -ρₒ = coupled_model.fluxes.ocean_reference_density -cₚ = coupled_model.fluxes.ocean_heat_capacity - -import Oceananigans.Fields: reduced_dimensions -reduced_dimensions(::Oceananigans.AbstractOperations.BinaryOperation) = tuple(3) - -ΣQ = ρₒ * cₚ * Jᵀ -τˣ = ρₒ * Jᵘ -τʸ = ρₒ * Jᵛ -N² = buoyancy_frequency(ocean.model) -κᶜ = ocean.model.diffusivity_fields.κᶜ - -function progress(sim) - msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg *= string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) - msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) - msg *= @sprintf(", max|τ|: (%.2e, %.2e) N m⁻²", maximum(τˣ), maximum(τʸ)) - msg *= @sprintf(", max|Qv|: %.2e W m⁻²", maximum(Qv)) - msg *= @sprintf(", max|Qc|: %.2e W m⁻²", maximum(Qc)) - msg *= @sprintf(", extrema(ΣQ): (%.2e, %.2e) W m⁻²", minimum(ΣQ), maximum(ΣQ)) - msg *= @sprintf(", extrema(Fv): (%.2e, %.2e) kg s⁻¹ m⁻²", minimum(Fv), maximum(Fv)) - msg *= @sprintf(", extrema(κᶜ): (%.2e, %.2e) m² s⁻¹", minimum(κᶜ), maximum(κᶜ)) - - #e = sim.model.ocean.model.tracers.e - #msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) - - @info msg -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -run!(coupled_simulation) - -#= -# Build flux outputs -Jᵘ = coupled_model.fluxes.total.ocean.momentum.u -Jᵛ = coupled_model.fluxes.total.ocean.momentum.v -Jᵀ = coupled_model.fluxes.total.ocean.tracers.T -Jˢ = coupled_model.fluxes.total.ocean.tracers.S -Fv = coupled_model.fluxes.turbulent.fields.freshwater -Qc = coupled_model.fluxes.turbulent.fields.sensible_heat -Qv = coupled_model.fluxes.turbulent.fields.latent_heat -ρₒ = coupled_model.fluxes.ocean_reference_density -cₚ = coupled_model.fluxes.ocean_heat_capacity - -ΣQ = ρₒ * cₚ * Jᵀ -τˣ = ρₒ * Jᵘ -τʸ = ρₒ * Jᵛ -N² = buoyancy_frequency(ocean.model) -κᶜ = ocean.model.diffusivity_fields.κᶜ - -fluxes = (; τˣ, τʸ, Fv, Jˢ, ΣQ, Qc, Qv) - -auxiliary_fields = (; N², κᶜ) -fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) - -# Slice fields at the surface -outputs = merge(fields, fluxes) - -filename = "regional_omip_simulation" - -coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, fluxes; - filename = filename * "_fluxes", - schedule = TimeInterval(1days), - overwrite_existing = true) - -coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; - filename = filename * "_fields", - indices = (:, :, Nz), - schedule = TimeInterval(1days), - overwrite_existing = true) - -=# diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl deleted file mode 100644 index 093b9415..00000000 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ /dev/null @@ -1,342 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.BuoyancyModels: buoyancy_frequency -using Oceananigans.Units: Time - -using ClimaOcean -using ClimaOcean.DataWrangling.ECCO2: ecco2_column - -using GLMakie -using Printf -using Dates - -include("omip_components.jl") - -locations = ( - eastern_mediterranean = (λ = 30, φ = 32), - ocean_station_papa = (λ = 215, φ = 50), - north_atlantic = (λ = 325, φ = 50), - drake_passage = (λ = 300, φ = -60), - weddell_sea = (λ = 325, φ = -70), - tasman_southern_ocean = (λ = 145, φ = -55), -) - -location = :ocean_station_papa - -start_time = time_ns() - -epoch = Date(1992, 1, 1) -date = Date(1992, 10, 1) -start_seconds = Second(date - epoch).value -Tᵢ = ecco2_field(:temperature, date) -Sᵢ = ecco2_field(:salinity, date) - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### - -Nz = 80 -H = 400 -arch = CPU() -λ★, φ★ = locations[location] -i★, j★, longitude, latitude = ecco2_column(λ★, φ★) - -grid = LatitudeLongitudeGrid(arch; longitude, latitude, - size = (1, 1, Nz), - z = (-H, 0), - topology = (Periodic, Periodic, Bounded)) - -ocean = omip_ocean_component(grid) - -backend = JRA55NetCDFBackend(8 * 60) -atmosphere = JRA55_prescribed_atmosphere(:; longitude, latitude, backend) - -ocean.model.clock.time = start_seconds -ocean.model.clock.iteration = 0 -interpolate!(ocean.model.tracers.T, Tᵢ) -interpolate!(ocean.model.tracers.S, Sᵢ) -set!(ocean.model, e=1e-6) - -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -times = ua.times - -fig = Figure(size=(1200, 1800)) -axu = Axis(fig[1, 1]) -axT = Axis(fig[2, 1]) -axq = Axis(fig[3, 1]) - -lines!(axu, times ./ days, interior(ua, 1, 1, 1, :)) -lines!(axu, times ./ days, interior(va, 1, 1, 1, :)) -lines!(axT, times ./ days, interior(Ta, 1, 1, 1, :)) -lines!(axq, times ./ days, interior(qa, 1, 1, 1, :)) - -display(fig) - -sea_ice = nothing -radiation = Radiation() -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 30days) - -elapsed = time_ns() - start_time -@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -wall_clock = Ref(time_ns()) - -function progress(sim) - msg = string("(", location, ")") - msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg *= string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - e = sim.model.ocean.model.tracers.e - - τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) - τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) - u★ = sqrt(sqrt(τˣ^2 + τʸ^2)) - Q = first(sim.model.fluxes.total.ocean.heat) - - Nz = size(T, 3) - msg *= @sprintf(", u★: %.2f m s⁻¹", u★) - msg *= @sprintf(", Q: %.2f W m⁻²", Q) - msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) - msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) - msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) - - @info msg -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) - -# Build flux outputs -Ju = coupled_model.fluxes.total.ocean.momentum.u -Jv = coupled_model.fluxes.total.ocean.momentum.v -JT = coupled_model.fluxes.total.ocean.tracers.T -Js = coupled_model.fluxes.total.ocean.tracers.S -E = coupled_model.fluxes.turbulent.fields.water_vapor -Qc = coupled_model.fluxes.turbulent.fields.sensible_heat -Qv = coupled_model.fluxes.turbulent.fields.latent_heat -ρₒ = coupled_model.fluxes.ocean_reference_density -cₚ = coupled_model.fluxes.ocean_heat_capacity - -Q = ρₒ * cₚ * Jᵀ -τx = ρₒ * Jᵘ -τy = ρₒ * Jᵛ -N² = buoyancy_frequency(ocean.model) -κc = ocean.model.diffusivity_fields.κᶜ - -fluxes = (; τx, τy, E, Js, Q, Qc, Qc) - -auxiliary_fields = (; N², κc) -fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) - -# Slice fields at the surface -outputs = merge(fields, fluxes) - -output_attributes = Dict{String, Any}( - "κc" => Dict("long_name" => "Tracer diffusivity", "units" => "m^2 / s"), - "Q" => Dict("long_name" => "Net heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "Qv" => Dict("long_name" => "Latent heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "Qc" => Dict("long_name" => "Sensible heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "Js" => Dict("long_name" => "Salt flux", "units" => "g kg⁻¹ m s⁻¹", "convention" => "positive upwards"), - "E" => Dict("long_name" => "Freshwater evaporation flux", "units" => "m s⁻¹", "convention" => "positive upwards"), - "e" => Dict("long_name" => "Turbulent kinetic energy", "units" => "m^2 / s^2"), - "τx" => Dict("long_name" => "Zonal momentum flux", "units" => "m^2 / s^2"), - "τx" => Dict("long_name" => "Meridional momentum flux", "units" => "m^2 / s^2"), -) - -filename = "single_column_omip_$location" - -coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, - schedule = TimeInterval(3hours), - overwrite_existing = true) - -#= -coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, - schedule = AveragedTimeInterval(1days), - output_attributes, - overwrite_existing = true) -=# - -run!(coupled_simulation) - -#= -filename *= ".jld2" - -ut = FieldTimeSeries(filename, "u") -vt = FieldTimeSeries(filename, "v") -Tt = FieldTimeSeries(filename, "T") -St = FieldTimeSeries(filename, "S") -et = FieldTimeSeries(filename, "e") -N²t = FieldTimeSeries(filename, "N²") -κt = FieldTimeSeries(filename, "κᶜ") - -Qt = FieldTimeSeries(filename, "Q") -Qset = FieldTimeSeries(filename, "Qse") -Qlat = FieldTimeSeries(filename, "Qla") -Jˢt = FieldTimeSeries(filename, "Jˢ") -Et = FieldTimeSeries(filename, "E") -τˣt = FieldTimeSeries(filename, "τˣ") -τʸt = FieldTimeSeries(filename, "τʸ") - -Nz = size(Tt, 3) -times = Qt.times - -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -Qlw = atmosphere.downwelling_radiation.longwave -Qsw = atmosphere.downwelling_radiation.shortwave -Pr = atmosphere.freshwater_flux.rain -Ps = atmosphere.freshwater_flux.snow - -Nt = length(times) -uat = zeros(Nt) -vat = zeros(Nt) -Tat = zeros(Nt) -qat = zeros(Nt) -Qswt = zeros(Nt) -Qlwt = zeros(Nt) -Pt = zeros(Nt) - -for n = 1:Nt - t = times[n] - uat[n] = ua[1, 1, 1, Time(t)] - vat[n] = va[1, 1, 1, Time(t)] - Tat[n] = Ta[1, 1, 1, Time(t)] - qat[n] = qa[1, 1, 1, Time(t)] - Qswt[n] = Qsw[1, 1, 1, Time(t)] - Qlwt[n] = Qlw[1, 1, 1, Time(t)] - Pt[n] = Pr[1, 1, 1, Time(t)] + Ps[1, 1, 1, Time(t)] -end - -set_theme!(Theme(linewidth=3)) - -fig = Figure(size=(2400, 1800)) - -axτ = Axis(fig[1, 1:2], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") -axu = Axis(fig[2, 1:2], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") -axQ = Axis(fig[1, 3:4], xlabel="Days since Oct 1 1992", ylabel="Heat flux (W m⁻²)") -axT = Axis(fig[2, 3:4], xlabel="Days since Oct 1 1992", ylabel="Surface temperature (ᵒC)") -axF = Axis(fig[1, 5:6], xlabel="Days since Oct 1 1992", ylabel="Freshwater volume flux (m s⁻¹)") -axS = Axis(fig[2, 5:6], xlabel="Days since Oct 1 1992", ylabel="Surface salinity (g kg⁻¹)") - -axuz = Axis(fig[3, 1], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") -axTz = Axis(fig[3, 2], xlabel="Temperature (ᵒC)", ylabel="z (m)") -axSz = Axis(fig[3, 3], xlabel="Salinity (g kg⁻¹)", ylabel="z (m)") -axNz = Axis(fig[3, 4], xlabel="Buoyancy frequency (s⁻²)", ylabel="z (m)") -axκz = Axis(fig[3, 5], xlabel="Eddy diffusivity (m² s⁻¹)", ylabel="z (m)", xscale=log10) -axez = Axis(fig[3, 6], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)", xscale=log10) - -title = @sprintf("Single column simulation at %.2f, %.2f", φ★, λ★) -Label(fig[0, 1:6], title) - -slider = Slider(fig[4, 1:6], range=1:Nt, startvalue=1) -n = slider.value - -times = (times .- times[1]) ./days -tn = @lift times[$n] - -colors = Makie.wong_colors() - -#lines!(axu, times, uat, color=colors[1]) -#lines!(axu, times, vat, color=colors[2]) - -ρₒ = coupled_model.fluxes.ocean_reference_density -Jᵘt = interior(τˣt, 1, 1, 1, :) ./ ρₒ -Jᵛt = interior(τʸt, 1, 1, 1, :) ./ ρₒ -u★ = @. (Jᵘt^2 + Jᵛt^2)^(1/4) - -lines!(axu, times, interior(ut, 1, 1, Nz, :), color=colors[1], label="Zonal") -lines!(axu, times, interior(vt, 1, 1, Nz, :), color=colors[2], label="Meridional") -lines!(axu, times, u★, color=colors[3], label="Ocean-side u★") -vlines!(axu, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axu) - -lines!(axτ, times, interior(τˣt, 1, 1, 1, :), label="Zonal") -lines!(axτ, times, interior(τʸt, 1, 1, 1, :), label="Meridional") -vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axτ) - -lines!(axT, times, Tat .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") -lines!(axT, times, interior(Tt, 1, 1, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") -vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axT) - -lines!(axQ, times, interior(Qt, 1, 1, 1, :), color=colors[1], label="Total", linewidth=6) -lines!(axQ, times, interior(Qset, 1, 1, 1, :), color=colors[2], label="Sensible", linewidth=2) -lines!(axQ, times, interior(Qlat, 1, 1, 1, :), color=colors[3], label="Latent", linewidth=2) -lines!(axQ, times, - Qswt, color=colors[4], label="Shortwave", linewidth=2) -lines!(axQ, times, - Qlwt, color=colors[5], label="Longwave", linewidth=2) -vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axQ) - -#lines!(axF, times, interior(Jˢt, 1, 1, 1, :), label="Net freshwater flux") -lines!(axF, times, Pt, label="Prescribed freshwater flux") -lines!(axF, times, - interior(Et, 1, 1, 1, :), label="Evaporation") -vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axF) - -lines!(axS, times, interior(St, 1, 1, Nz, :)) -vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) - -zc = znodes(Tt) -zf = znodes(κt) -un = @lift interior(ut[$n], 1, 1, :) -vn = @lift interior(vt[$n], 1, 1, :) -Tn = @lift interior(Tt[$n], 1, 1, :) -Sn = @lift interior(St[$n], 1, 1, :) -κn = @lift interior(κt[$n], 1, 1, :) -en = @lift max.(1e-6, interior(et[$n], 1, 1, :)) -N²n = @lift interior(N²t[$n], 1, 1, :) - -scatterlines!(axuz, un, zc, label="u") -scatterlines!(axuz, vn, zc, label="v") -scatterlines!(axTz, Tn, zc) -scatterlines!(axSz, Sn, zc) -scatterlines!(axez, en, zc) -scatterlines!(axNz, N²n, zf) -scatterlines!(axκz, κn, zf) - -axislegend(axuz) - -Tmax = maximum(interior(Tt)) -Tmin = minimum(interior(Tt)) -xlims!(axTz, Tmin - 0.1, Tmax + 0.1) - -Nmax = maximum(interior(N²t)) -Nmin = minimum(interior(N²t)) -xlims!(axNz, Nmin / 2, Nmin * 1.1) - -emax = maximum(interior(et)) -xlims!(axez, 8e-7, emax * 1.1) -xlims!(axκz, 1e-7, 10) - -Smax = maximum(interior(St)) -Smin = minimum(interior(St)) -xlims!(axSz, Smin - 0.2, Smax + 0.2) - -display(fig) - -record(fig, "$(location)_single_column_simulation.mp4", 1:Nt, framerate=24) do nn - @info "Drawing frame $nn of $Nt..." - n[] = nn -# end -end -=# diff --git a/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 d784f5e80d46d16e4cf042d19ed43425d9fb3da7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:12:46 -0500 Subject: [PATCH 260/716] better --- src/Bathymetry.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 372457a9..bd92198e 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -307,7 +307,6 @@ function remove_lakes!(h_data; connected_regions_allowed = Inf) return bathtmp end - """ retrieve_bathymetry(grid, filename; kw...) From 64a4d1d0d36a13cc0d1c0786096683c6a438d5e5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:45:42 -0500 Subject: [PATCH 261/716] let's see --- src/OceanSimulations/load_balanced_regional_grid.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 68d187d3..138383a1 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -117,9 +117,10 @@ function load_balanced_regional_grid(arch::SlabDistributed; # Calculating the load for each i slab if XPartition or j slab if YPartition load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) - loop! = assess_load(device(child_arch), 512, size[idx]) + loop! = assess_load!(device(child_arch), 512, size[idx]) loop!(load_per_slab, grid, idx) + @show load_per_slab load_per_slab = arch_array(CPU(), load_per_slab) # Redistribute the load to have the same number of @@ -155,7 +156,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height), active_cells_map = true) end -@kernel function assess_load(load_per_slab, grid, idx) +@kernel function assess_load!(load_per_slab, grid, idx) i1 = @index(Global, Linear) for i2 in 1:size(grid, idx) From b270d044c07adc7084cf854a7a2d64fda061329c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:50:15 -0500 Subject: [PATCH 262/716] another fix --- src/DataWrangling/ECCO2.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 58229a08..f861ce97 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -90,7 +90,7 @@ end function empty_ecco2_field(data::ECCO2Metadata; architecture = CPU(), - horizontal_halo = (1, 1)) + horizontal_halo = (5, 5)) variable_name = data.name @@ -144,7 +144,7 @@ The data is either: """ function ecco2_field(variable_name; architecture = CPU(), - horizontal_halo = (1, 1), + horizontal_halo = (5, 5), user_data = nothing, year = 1992, month = 1, From ca503de15127d2f384d118d16df3d9f0f774f21f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:52:09 -0500 Subject: [PATCH 263/716] show method --- src/OceanSimulations/load_balanced_regional_grid.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 138383a1..a25f8079 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -121,6 +121,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; loop!(load_per_slab, grid, idx) @show load_per_slab + load_per_slab = arch_array(CPU(), load_per_slab) # Redistribute the load to have the same number of From 7000816c5659babf7fa20c1c08324c66046f5e3b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:52:22 -0500 Subject: [PATCH 264/716] let's use a barrier --- src/OceanSimulations/load_balanced_regional_grid.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index a25f8079..ccdd2e0f 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -121,6 +121,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; loop!(load_per_slab, grid, idx) @show load_per_slab + barrier!(arch) load_per_slab = arch_array(CPU(), load_per_slab) From 39104f7c4edc7b0e2898581955285717e1bd2492 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:59:29 -0500 Subject: [PATCH 265/716] let's try like this? --- src/OceanSimulations/load_balanced_regional_grid.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index ccdd2e0f..a35c7034 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -116,13 +116,12 @@ function load_balanced_regional_grid(arch::SlabDistributed; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) # Calculating the load for each i slab if XPartition or j slab if YPartition - load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) - loop! = assess_load!(device(child_arch), 512, size[idx]) + load_per_slab = arch_array(CPU(), zeros(Int, size[idx])) + loop! = assess_load!(device(CPU()), 512, size[idx]) loop!(load_per_slab, grid, idx) - @show load_per_slab barrier!(arch) - + load_per_slab = arch_array(CPU(), load_per_slab) # Redistribute the load to have the same number of From 1e0f9097a8ecfdd44c88059bcb77ca080d25d05f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:00:16 -0500 Subject: [PATCH 266/716] this should work? --- src/OceanSimulations/load_balanced_regional_grid.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index a35c7034..22dcce23 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -116,14 +116,12 @@ function load_balanced_regional_grid(arch::SlabDistributed; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) # Calculating the load for each i slab if XPartition or j slab if YPartition - load_per_slab = arch_array(CPU(), zeros(Int, size[idx])) + load_per_slab = zeros(Int, size[idx]) loop! = assess_load!(device(CPU()), 512, size[idx]) loop!(load_per_slab, grid, idx) barrier!(arch) - load_per_slab = arch_array(CPU(), load_per_slab) - # Redistribute the load to have the same number of # immersed cells in each core local_N = if ifelse arch.local_rank == 0 From 018bda7626689206265272dd72ed64a54a737f33 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:05:34 -0500 Subject: [PATCH 267/716] infer load on CPU --- src/OceanSimulations/load_balanced_regional_grid.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 22dcce23..5d26b9be 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -96,7 +96,8 @@ function load_balanced_regional_grid(arch::SlabDistributed; # index of the partitioned direction idx = arch.ranks[1] == 1 ? 2 : 1 - grid = LatitudeLongitudeGrid(child_arch; + # Calculate the load balancing on the CPU + grid = LatitudeLongitudeGrid(CPU(); size, longitude, latitude, From 7a995ef0f29129fe149cc07f0210e97eb300c241 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:09:14 -0500 Subject: [PATCH 268/716] show stuff --- .../load_balanced_regional_grid.jl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 5d26b9be..acb34e89 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -96,6 +96,9 @@ function load_balanced_regional_grid(arch::SlabDistributed; # index of the partitioned direction idx = arch.ranks[1] == 1 ? 2 : 1 + @show "before grid" + barrier!(arch) + # Calculate the load balancing on the CPU grid = LatitudeLongitudeGrid(CPU(); size, @@ -104,6 +107,10 @@ function load_balanced_regional_grid(arch::SlabDistributed; z, halo) + + @show "after grid" + barrier!(arch) + # Calculating the global bottom on the global grid on rank 0 # so that we can write to file the bathymetry in case `!isnothing(bathymetry_file)` bottom_height = retrieve_bathymetry(grid, bathymetry_file; @@ -112,15 +119,20 @@ function load_balanced_regional_grid(arch::SlabDistributed; interpolation_passes, connected_regions_allowed) + @show "after bottom_height" barrier!(arch) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + @show "after immersed" + barrier!(arch) + # Calculating the load for each i slab if XPartition or j slab if YPartition load_per_slab = zeros(Int, size[idx]) loop! = assess_load!(device(CPU()), 512, size[idx]) loop!(load_per_slab, grid, idx) + @show "after load_per_slab" barrier!(arch) # Redistribute the load to have the same number of @@ -131,9 +143,12 @@ function load_balanced_regional_grid(arch::SlabDistributed; zeros(Int, arch.ranks[idx]) end + @show "after local_N" barrier!(arch) + local_N = all_reduce(+, local_N, arch) + @show "local_N" @show local_N redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) From 5b4182513d7a91787755aae1b37e3a31c5a3d2c6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:11:54 -0500 Subject: [PATCH 269/716] try it out --- src/OceanSimulations/load_balanced_regional_grid.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index acb34e89..402db073 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -107,7 +107,6 @@ function load_balanced_regional_grid(arch::SlabDistributed; z, halo) - @show "after grid" barrier!(arch) @@ -124,15 +123,20 @@ function load_balanced_regional_grid(arch::SlabDistributed; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - @show "after immersed" + @show "after immersed" size(idx) barrier!(arch) - # Calculating the load for each i slab if XPartition or j slab if YPartition + # Calculate the load for each i-slab if the partition is in x, + # calculate the load for eahc j-slab if the partition is in y. load_per_slab = zeros(Int, size[idx]) + + @show "after load per slab" size(idx) idx + barrier!(arch) + loop! = assess_load!(device(CPU()), 512, size[idx]) loop!(load_per_slab, grid, idx) - @show "after load_per_slab" + @show "after assess_load" barrier!(arch) # Redistribute the load to have the same number of From 2bfa96b79edf3c5ef49dbeae2ab569d09a9f825f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:15:43 -0500 Subject: [PATCH 270/716] try it like this --- src/DataWrangling/ECCO2.jl | 6 ++-- src/InitialConditions/InitialConditions.jl | 39 +++++++++++++++++++++- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index f861ce97..a572f6d3 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -3,7 +3,7 @@ module ECCO2 export ECCO2Metadata, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.DataWrangling: inpaint_mask! -using ClimaOcean.InitialConditions: three_dimensional_regrid! +using ClimaOcean.InitialConditions: three_dimensional_regrid!, three_dimensional_interpolate! using Oceananigans using Oceananigans.Architectures: architecture, child_architecture @@ -291,7 +291,7 @@ function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename=" parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) f_grid = Field(ecco2_location[name], grid) - three_dimensional_regrid!(f_grid, f_ecco) + three_dimensional_interpolate!(f_grid, f_ecco) set!(field, f_grid) return field @@ -310,7 +310,7 @@ function set!(field::Field, ecco2_metadata::ECCO2Metadata; filename="./inpainted kw...) f_grid = Field(ecco2_location[name], grid) - three_dimensional_regrid!(f_grid, f) + three_dimensional_interpolate!(f_grid, f) set!(field, f_grid) return field diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 35604ef6..6f700f7e 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -17,7 +17,7 @@ using JLD2 # Implementation of 3-dimensional regridding # TODO: move all the following to Oceananigans! -using Oceananigans.Fields: regrid! +using Oceananigans.Fields: regrid!, interpolate! using Oceananigans.Grids: cpu_face_constructor_x, cpu_face_constructor_y, cpu_face_constructor_z, @@ -67,6 +67,43 @@ function three_dimensional_regrid!(a, b) return a end +function three_dimensional_interpolate!(a, b) + target_grid = a.grid isa ImmersedBoundaryGrid ? a.grid.underlying_grid : a.grid + source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid + + topo = topology(target_grid) + arch = architecture(target_grid) + arch = child_architecture(arch) + + target_y = yt = cpu_face_constructor_y(target_grid) + target_z = zt = cpu_face_constructor_z(target_grid) + + target_size = Nt = size(target_grid) + + source_x = xs = cpu_face_constructor_x(source_grid) + source_y = ys = cpu_face_constructor_y(source_grid) + + source_size = Ns = size(source_grid) + + # Start by regridding in z + @debug "Interpolating in z" + zgrid = construct_grid(typeof(target_grid), arch, (Ns[1], Ns[2], Nt[3]), (xs, ys, zt), topo) + field_z = Field(location(b), zgrid) + interpolate!(field_z, b) + + # regrid in y + @debug "Interpolating in y" + ygrid = construct_grid(typeof(target_grid), arch, (Ns[1], Nt[2], Nt[3]), (xs, yt, zt), topo) + field_y = Field(location(b), ygrid); + interpolate!(field_y, field_z) + + # Finally regrid in x + @debug "Interpolating in x" + interpolate!(a, field_y) + + return a +end + include("diffuse_tracers.jl") end # module From f124a0befa794fae984312db02562f7fde6c5ccd Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:16:27 -0500 Subject: [PATCH 271/716] test --- src/OceanSimulations/load_balanced_regional_grid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 402db073..78412869 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -130,7 +130,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; # calculate the load for eahc j-slab if the partition is in y. load_per_slab = zeros(Int, size[idx]) - @show "after load per slab" size(idx) idx + @show "after load per slab" size[idx] idx barrier!(arch) loop! = assess_load!(device(CPU()), 512, size[idx]) From 99def85cdc3b087593a315d4fb2337f154b4e1dd Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:18:36 -0500 Subject: [PATCH 272/716] test it out --- src/OceanSimulations/load_balanced_regional_grid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 78412869..8e28dd7c 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -123,7 +123,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - @show "after immersed" size(idx) + @show "after immersed" size[idx] idx barrier!(arch) # Calculate the load for each i-slab if the partition is in x, From 6726dd65aba89ae0efc60b52349ea175bd8e3c9a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:22:26 -0500 Subject: [PATCH 273/716] let's see --- .../load_balanced_regional_grid.jl | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 8e28dd7c..3f18a861 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -96,9 +96,6 @@ function load_balanced_regional_grid(arch::SlabDistributed; # index of the partitioned direction idx = arch.ranks[1] == 1 ? 2 : 1 - @show "before grid" - barrier!(arch) - # Calculate the load balancing on the CPU grid = LatitudeLongitudeGrid(CPU(); size, @@ -107,9 +104,6 @@ function load_balanced_regional_grid(arch::SlabDistributed; z, halo) - @show "after grid" - barrier!(arch) - # Calculating the global bottom on the global grid on rank 0 # so that we can write to file the bathymetry in case `!isnothing(bathymetry_file)` bottom_height = retrieve_bathymetry(grid, bathymetry_file; @@ -118,21 +112,12 @@ function load_balanced_regional_grid(arch::SlabDistributed; interpolation_passes, connected_regions_allowed) - @show "after bottom_height" - barrier!(arch) - grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - @show "after immersed" size[idx] idx - barrier!(arch) - # Calculate the load for each i-slab if the partition is in x, # calculate the load for eahc j-slab if the partition is in y. load_per_slab = zeros(Int, size[idx]) - @show "after load per slab" size[idx] idx - barrier!(arch) - loop! = assess_load!(device(CPU()), 512, size[idx]) loop!(load_per_slab, grid, idx) @@ -181,6 +166,7 @@ end for i2 in 1:size(grid, idx) for k in 1:size(grid, 3) i = ifelse(idx == 1, (i1, i2), (i2, i1)) + @show i @inbounds load_per_slab[i1] += ifelse(immersed_cell(i..., k, grid), 0, 1) end end From d42aa1c7b0bb8e983a766ae6ca6a71beac3f9662 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:25:43 -0500 Subject: [PATCH 274/716] let's go --- src/OceanSimulations/load_balanced_regional_grid.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 3f18a861..d70e74c9 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -164,6 +164,7 @@ end i1 = @index(Global, Linear) for i2 in 1:size(grid, idx) + @show size(grid, idx) for k in 1:size(grid, 3) i = ifelse(idx == 1, (i1, i2), (i2, i1)) @show i From 4062311f043d119ffc3c8444775b295b8a885668 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:31:49 -0500 Subject: [PATCH 275/716] now it will work! --- .../load_balanced_regional_grid.jl | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index d70e74c9..7c03fe6e 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -97,7 +97,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; idx = arch.ranks[1] == 1 ? 2 : 1 # Calculate the load balancing on the CPU - grid = LatitudeLongitudeGrid(CPU(); + grid = LatitudeLongitudeGrid(child_arch; size, longitude, latitude, @@ -116,30 +116,16 @@ function load_balanced_regional_grid(arch::SlabDistributed; # Calculate the load for each i-slab if the partition is in x, # calculate the load for eahc j-slab if the partition is in y. - load_per_slab = zeros(Int, size[idx]) + load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) - loop! = assess_load!(device(CPU()), 512, size[idx]) + loop! = assess_load!(device(chil_arch), 512, size[idx]) loop!(load_per_slab, grid, idx) - - @show "after assess_load" - barrier!(arch) + load_per_slab = arch_array(CPU(), load_per_slab) # Redistribute the load to have the same number of # immersed cells in each core - local_N = if ifelse arch.local_rank == 0 - calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) - else - zeros(Int, arch.ranks[idx]) - end - - @show "after local_N" - barrier!(arch) - - local_N = all_reduce(+, local_N, arch) - - @show "local_N" - @show local_N - + local_N = calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) + redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) # Partition either x or y depending on the original partition direction @@ -148,7 +134,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; arch = Distributed(child_arch; partition) zonal_rank = arch.local_index[idx] - @info "slab decomposition with " zonal_rank local_N[zonal_rank] + @info "slab decomposition with " zonal_rank local_N grid = LatitudeLongitudeGrid(arch; size, @@ -162,12 +148,11 @@ end @kernel function assess_load!(load_per_slab, grid, idx) i1 = @index(Global, Linear) + sz = ifelse(idx == 1, size(grid, 2), size(grid, 1)) - for i2 in 1:size(grid, idx) - @show size(grid, idx) + for i2 in 1:sz for k in 1:size(grid, 3) i = ifelse(idx == 1, (i1, i2), (i2, i1)) - @show i @inbounds load_per_slab[i1] += ifelse(immersed_cell(i..., k, grid), 0, 1) end end @@ -195,7 +180,10 @@ end redistribute_size_to_fulfill_memory_limitation!(l, ::Nothing) = nothing function redistribute_size_to_fulfill_memory_limitation!(l, m) + n = length(l) + + # Reduce large sizes while any(l .> m) x⁺, i⁺ = findmax(l) x⁻, i⁻ = findmin(l) @@ -210,6 +198,8 @@ function redistribute_size_to_fulfill_memory_limitation!(l, m) l[i⁻] += mod(Δ, n) end end + + # Increase small sizes while any(l .< 20) x⁺, i⁺ = findmax(l) x⁻, i⁻ = findmin(l) From b560bcf02cdd1b6b9943d9a782ce42afd481608b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:32:17 -0500 Subject: [PATCH 276/716] let's go here! --- experiments/twelth_degree_latlong.jl | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index ee84027d..9ce7aa99 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -60,17 +60,6 @@ bottom = zeros(Nx, Ny, 1) arch = Distributed(GPU(), partition = Partition(8)) -# grid = LatitudeLongitudeGrid(arch; -# size = (Nx, Ny, Nz), -# z = z_faces, -# latitude = (-75, 75), -# longitude = (0, 360), -# halo = (7, 7, 7)) - -# bottom .= jldopen(bathymetry_file)["bathymetry"] - -# grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom); active_cells_map = true) - grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), z = z_faces, @@ -90,14 +79,13 @@ grid = load_balanced_regional_grid(arch; free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=270) -ocean = ocean_simulation(grid; Δt = 10, free_surface) +ocean = ocean_simulation(grid; Δt = 10, free_surface, closure = RiBasedVerticalDiffusivity()) model = ocean.model # Initializing the model set!(model, T = ECCO2Metadata(:temperature), - S = ECCO2Metadata(:salinity), - e = 1e-6) + S = ECCO2Metadata(:salinity)) ##### ##### The atmosphere From 699c07bdf558be143760cca7578f7196ace6a6cc Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:33:28 -0500 Subject: [PATCH 277/716] let's go! --- experiments/correct_oceananigans.jl | 64 ++++++++++++++++++++++++++++ experiments/twelth_degree_latlong.jl | 27 +----------- 2 files changed, 65 insertions(+), 26 deletions(-) create mode 100644 experiments/correct_oceananigans.jl diff --git a/experiments/correct_oceananigans.jl b/experiments/correct_oceananigans.jl new file mode 100644 index 00000000..e5f0ffd6 --- /dev/null +++ b/experiments/correct_oceananigans.jl @@ -0,0 +1,64 @@ + +#### +#### This file contains all the bug-fixes that still didn't get merged in Oceananigans.jl +#### + +using Oceananigans.BuoyancyModels: ∂z_b +using Oceananigans.Operators +using Oceananigans.Grids: peripheral_node, inactive_node +using Oceananigans.TurbulenceClosures: top_buoyancy_flux, getclosure, taper + +import Oceananigans.TurbulenceClosures: _compute_ri_based_diffusivities! + +@inline function _compute_ri_based_diffusivities!(i, j, k, diffusivities, grid, closure, + velocities, tracers, buoyancy, tracer_bcs, clock) + + # Ensure this works with "ensembles" of closures, in addition to ordinary single closures + closure_ij = getclosure(i, j, closure) + + ν₀ = closure_ij.ν₀ + κ₀ = closure_ij.κ₀ + κᶜᵃ = closure_ij.κᶜᵃ + Cᵉⁿ = closure_ij.Cᵉⁿ + Cᵃᵛ = closure_ij.Cᵃᵛ + Ri₀ = closure_ij.Ri₀ + Riᵟ = closure_ij.Riᵟ + tapering = closure_ij.Ri_dependent_tapering + Qᵇ = top_buoyancy_flux(i, j, grid, buoyancy, tracer_bcs, clock, merge(velocities, tracers)) + + # Convection and entrainment + N² = ∂z_b(i, j, k, grid, buoyancy, tracers) + + # Conditions + convecting = N² < 0 # applies regardless of Qᵇ + + # Convective adjustment diffusivity + κᶜᵃ = ifelse(convecting, κᶜᵃ, zero(grid)) + + # Shear mixing diffusivity and viscosity + Ri = ℑxyᶜᶜᵃ(i, j, k, grid, ℑxyᶠᶠᵃ, diffusivities.Ri) + τ = taper(tapering, Ri, Ri₀, Riᵟ) + + κᶜ★ = κ₀ * τ + κᵘ★ = ν₀ * τ + + # Previous diffusivities + κᶜ = diffusivities.κᶜ + κᵘ = diffusivities.κᵘ + + # New diffusivities + κᶜ⁺ = κᶜ★ + κᶜᵃ + κᵘ⁺ = κᵘ★ + + # Set to zero on periphery and NaN within inactive region + on_periphery = peripheral_node(i, j, k, grid, Center(), Center(), Face()) + within_inactive = inactive_node(i, j, k, grid, Center(), Center(), Face()) + κᶜ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᶜ⁺)) + κᵘ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᵘ⁺)) + + # Update by averaging in time + @inbounds κᶜ[i, j, k] = (Cᵃᵛ * κᶜ[i, j, k] + κᶜ⁺) / (1 + Cᵃᵛ) + @inbounds κᵘ[i, j, k] = (Cᵃᵛ * κᵘ[i, j, k] + κᵘ⁺) / (1 + Cᵃᵛ) + + return nothing +end \ No newline at end of file diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 9ce7aa99..d97c737d 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -21,32 +21,7 @@ using JLD2 ##### Global Ocean at 1/12th of a degree ##### -# import Oceananigans.Fields: set! -# using Oceananigans.Grids: on_architecture -# using Oceananigans.DistributedComputations: DistributedField, global_size, partition_global_array -# using Oceananigans.Architectures: architecture - -# # Automatically partition under the hood if sizes are compatible -# function set!(u::DistributedField, v::Array) -# gsize = global_size(architecture(u), size(u)) - -# @show gsize, size(v) -# if size(v) == gsize -# f = partition_global_array(architecture(u), v, size(u)) -# u .= f -# return u -# else -# try -# f = on_architecture(architecture(u), v) -# u .= f -# return u - -# catch -# throw(ArgumentError("ERROR: DimensionMismatch: array could not be set to match destination field")) -# end -# end -# end - +include("correct_oceananigans.jl") bathymetry_file = "bathymetry12.jld2" # 100 vertical levels From b73c7c31cc612e52de0d2b39cafa004d03e5424c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:34:26 -0500 Subject: [PATCH 278/716] better! --- experiments/correct_oceananigans.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/experiments/correct_oceananigans.jl b/experiments/correct_oceananigans.jl index e5f0ffd6..d3269193 100644 --- a/experiments/correct_oceananigans.jl +++ b/experiments/correct_oceananigans.jl @@ -19,12 +19,10 @@ import Oceananigans.TurbulenceClosures: _compute_ri_based_diffusivities! ν₀ = closure_ij.ν₀ κ₀ = closure_ij.κ₀ κᶜᵃ = closure_ij.κᶜᵃ - Cᵉⁿ = closure_ij.Cᵉⁿ Cᵃᵛ = closure_ij.Cᵃᵛ Ri₀ = closure_ij.Ri₀ Riᵟ = closure_ij.Riᵟ tapering = closure_ij.Ri_dependent_tapering - Qᵇ = top_buoyancy_flux(i, j, grid, buoyancy, tracer_bcs, clock, merge(velocities, tracers)) # Convection and entrainment N² = ∂z_b(i, j, k, grid, buoyancy, tracers) From 26c31ecb06171f7dac774aefdbd9ff563f64a310 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:36:59 -0500 Subject: [PATCH 279/716] bugfix --- src/OceanSimulations/load_balanced_regional_grid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 7c03fe6e..8e712d3a 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -118,7 +118,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; # calculate the load for eahc j-slab if the partition is in y. load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) - loop! = assess_load!(device(chil_arch), 512, size[idx]) + loop! = assess_load!(device(child_arch), 512, size[idx]) loop!(load_per_slab, grid, idx) load_per_slab = arch_array(CPU(), load_per_slab) From 00bd8a2f0aa8b1a4bb38bda4538fd37b16bb7918 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:43:16 -0500 Subject: [PATCH 280/716] now it will work --- src/OceanSimulations/load_balanced_regional_grid.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 8e712d3a..64d615f3 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -114,6 +114,11 @@ function load_balanced_regional_grid(arch::SlabDistributed; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + if size(bottom_height) == 2 + bottom_height = arch_array(child_arch, zeros(size[1], size[2], 1)) + bottom_height .= grid.immersed_boundary.bottom_height + end + # Calculate the load for each i-slab if the partition is in x, # calculate the load for eahc j-slab if the partition is in y. load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) From 08cdad33320f34d8be5ee6e1ed23ab6532ffec34 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:47:27 -0500 Subject: [PATCH 281/716] fixes --- src/OceanSimulations/load_balanced_regional_grid.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 64d615f3..9d2f45d6 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -114,9 +114,10 @@ function load_balanced_regional_grid(arch::SlabDistributed; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - if size(bottom_height) == 2 - bottom_height = arch_array(child_arch, zeros(size[1], size[2], 1)) - bottom_height .= grid.immersed_boundary.bottom_height + # Cannot have two dimensional vectors + # set! a field on `Distributed`. TODO: fix in Oceananigans + if ndims(bottom_height) == 2 + bottom_height = reshape(bottom_height, Base.size(bottom_height)..., 1) end # Calculate the load for each i-slab if the partition is in x, From fbce7d71314f1430f1a2a0c25b6f83502513aee1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:48:24 -0500 Subject: [PATCH 282/716] maximum size --- experiments/twelth_degree_latlong.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index d97c737d..46968b9a 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -42,6 +42,7 @@ grid = load_balanced_regional_grid(arch; longitude = (0, 360), halo = (7, 7, 7), interpolation_passes = 20, + maximum_size = 650, minimum_depth = 10, connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea bathymetry_file) From 6c0e3384e6df847c5681dc061c19f77a3e5b17c0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:51:18 -0500 Subject: [PATCH 283/716] performance measure --- experiments/performance.jl | 125 +++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 experiments/performance.jl diff --git a/experiments/performance.jl b/experiments/performance.jl new file mode 100644 index 00000000..453c109d --- /dev/null +++ b/experiments/performance.jl @@ -0,0 +1,125 @@ +using Preferences +const iscray = parse(Bool, load_preference(Base.UUID("3da0fdf6-3ccc-4f1b-acd9-58baa6c99267"), "iscray", "false")) +@debug "Preloading GTL library" iscray +if iscray + import Libdl + Libdl.dlopen_e("libmpi_gtl_cuda", Libdl.RTLD_LAZY | Libdl.RTLD_GLOBAL) +end + +using MPI +MPI.Init() + +using Oceananigans +using Oceananigans: architecture +using ClimaOcean +using ClimaOcean.ECCO2 +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity +using Oceananigans.Coriolis: ActiveCellEnstrophyConserving +using Oceananigans.Units +using ClimaOcean.OceanSimulations +using ClimaOcean.OceanSeaIceModels +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation +using ClimaOcean.VerticalGrids: exponential_z_faces +using ClimaOcean.JRA55 +using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere +using Printf +using JLD2 + +##### +##### Global Ocean at 1/12th of a degree +##### + +include("correct_oceananigans.jl") +bathymetry_file = "bathymetry12.jld2" + +# 100 vertical levels +z_faces = exponential_z_faces(Nz=100, depth=6000) + +Nx = 4320 +Ny = 1800 +Nz = length(z_faces) - 1 + +bottom = zeros(Nx, Ny, 1) + +arch = Distributed(GPU(), partition = Partition(8)) + +grid = load_balanced_regional_grid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + latitude = (-75, 75), + longitude = (0, 360), + halo = (7, 7, 7), + interpolation_passes = 20, + maximum_size = 650, + minimum_depth = 10, + connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea + bathymetry_file) + +@show grid + +##### +##### The Ocean component +##### + +free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=270) + +ocean = ocean_simulation(grid; Δt = 10, free_surface, closure = RiBasedVerticalDiffusivity()) +model = ocean.model + +# Initializing the model +set!(model, + T = ECCO2Metadata(:temperature), + S = ECCO2Metadata(:salinity)) + +##### +##### The atmosphere +##### + +backend = JRA55NetCDFBackend(5) +atmosphere = JRA55_prescribed_atmosphere(arch; backend) +radiation = Radiation() + +coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) + +function profiled_time_steps!(model, Δt; gc_steps = 100, profiled_steps = 10) + # initial time steps + for step in 1:10 + time_step!(model, Δt) + end + + nranks = MPI.Comm_size(MPI.COMM_WORLD) + rank = MPI.Comm_rank(MPI.COMM_WORLD) + + if rank == 0 + @info "start profiling" + end + elapsed_time = Float64[0] + # Perform profiling + for step in 1:gc_steps + for nogc in 1:profiled_steps + elapsed_time[1] += @elapsed begin + NVTX.@range "one time step" begin + time_step!(model, Δt) + end + end + end + GC.gc() + end + + elapsed_time[1] = elapsed_time[1] / nranks / gc_steps / profiled_steps + MPI.Allreduce!(elapsed_time, +, MPI.COMM_WORLD) + + if rank == 0 + file = "time_twelth.jld2" + while isfile(file) + file = "new_" * file + end + jldsave(file, elapsed_time=elapsed_time[1]) + end + + MPI.Barrier(MPI.COMM_WORLD) + + return nothing +end + +profiled_time_steps!(coupled_model, 0.1) \ No newline at end of file From c1399322c0e2722cc46bab8c330da9657fcfe9bf Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:53:04 -0500 Subject: [PATCH 284/716] test it out --- src/OceanSimulations/load_balanced_regional_grid.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 9d2f45d6..cbd59aa9 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -124,14 +124,26 @@ function load_balanced_regional_grid(arch::SlabDistributed; # calculate the load for eahc j-slab if the partition is in y. load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) + @show "before load per slab" + @show load_per_slab + barrier!(arch) + loop! = assess_load!(device(child_arch), 512, size[idx]) loop!(load_per_slab, grid, idx) load_per_slab = arch_array(CPU(), load_per_slab) + @show "after load per slab" + @show load_per_slab + barrier!(arch) + # Redistribute the load to have the same number of # immersed cells in each core local_N = calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) + @show "after local N" + @show local_N + barrier!(arch) + redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) # Partition either x or y depending on the original partition direction From 9b977141a92094bfda85693aa53e1fe1ab101c32 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 21:55:38 -0500 Subject: [PATCH 285/716] not working? --- .../load_balanced_regional_grid.jl | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index cbd59aa9..c5473dd7 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -124,26 +124,14 @@ function load_balanced_regional_grid(arch::SlabDistributed; # calculate the load for eahc j-slab if the partition is in y. load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) - @show "before load per slab" - @show load_per_slab - barrier!(arch) - loop! = assess_load!(device(child_arch), 512, size[idx]) loop!(load_per_slab, grid, idx) load_per_slab = arch_array(CPU(), load_per_slab) - @show "after load per slab" - @show load_per_slab - barrier!(arch) - # Redistribute the load to have the same number of # immersed cells in each core local_N = calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) - @show "after local N" - @show local_N - barrier!(arch) - redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) # Partition either x or y depending on the original partition direction @@ -161,7 +149,7 @@ function load_balanced_regional_grid(arch::SlabDistributed; z, halo) - return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height), active_cells_map = true) + return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end @kernel function assess_load!(load_per_slab, grid, idx) From 518556d0e6ca7bee5059c1ee34d6a38e66f93ed0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:03:31 -0500 Subject: [PATCH 286/716] another test --- .../load_balanced_regional_grid.jl | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index c5473dd7..4ffa0ae7 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -152,6 +152,44 @@ function load_balanced_regional_grid(arch::SlabDistributed; return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end +import Oceananigans.ImmersedBoundaries: ImmersedBoundaryGrid +using Oceananigans.ImmersedBoundaries: map_interior_active_cells, architecture, topology, map_active_z_columns + +function ImmersedBoundaryGrid(grid, ib; active_cells_map::Bool = true) + + arch = architecture(grid) + + @show "before immersed boundary" + barrier(arch) + + ibg = ImmersedBoundaryGrid(grid, ib) + TX, TY, TZ = topology(ibg) + + @show "I am here!" + barrier(arch) + + # Create the cells map on the CPU, then switch it to the GPU + if active_cells_map + interior_map = map_interior_active_cells(ibg) + + @show "after interior map" + barrier(arch) + + column_map = map_active_z_columns(ibg) + + @show "after column map" + barrier(arch) + else + interior_map = nothing + column_map = nothing + end + + return ImmersedBoundaryGrid{TX, TY, TZ}(ibg.underlying_grid, + ibg.immersed_boundary, + interior_map, + column_map) +end + @kernel function assess_load!(load_per_slab, grid, idx) i1 = @index(Global, Linear) sz = ifelse(idx == 1, size(grid, 2), size(grid, 1)) From 8427467d3080d52d9b4d5ee4378ef54796adfdb0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:05:46 -0500 Subject: [PATCH 287/716] gogogo --- src/OceanSimulations/load_balanced_regional_grid.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 4ffa0ae7..b890265f 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -160,25 +160,25 @@ function ImmersedBoundaryGrid(grid, ib; active_cells_map::Bool = true) arch = architecture(grid) @show "before immersed boundary" - barrier(arch) + barrier!(arch) ibg = ImmersedBoundaryGrid(grid, ib) TX, TY, TZ = topology(ibg) @show "I am here!" - barrier(arch) + barrier!(arch) # Create the cells map on the CPU, then switch it to the GPU if active_cells_map interior_map = map_interior_active_cells(ibg) @show "after interior map" - barrier(arch) + barrier!(arch) column_map = map_active_z_columns(ibg) @show "after column map" - barrier(arch) + barrier!(arch) else interior_map = nothing column_map = nothing From e50c80a664f5f75d89371edc1eafbfc1658b88ec Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:09:26 -0500 Subject: [PATCH 288/716] let's see --- .../load_balanced_regional_grid.jl | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index b890265f..eada6bf2 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -155,6 +155,32 @@ end import Oceananigans.ImmersedBoundaries: ImmersedBoundaryGrid using Oceananigans.ImmersedBoundaries: map_interior_active_cells, architecture, topology, map_active_z_columns +function ImmersedBoundaryGrid(grid, ib::GridFittedBottom) + + arch = architecture(grid) + + @show "before setting field" + barrier!(arch) + + bottom_field = Field{Center, Center, Nothing}(grid) + set!(bottom_field, ib.bottom_height) + + @show "after setting field" + barrier!(arch) + + fill_halo_regions!(bottom_field) + + @show "after fill halo" + barrier!(arch) + new_ib = GridFittedBottom(bottom_field, ib.immersed_condition) + + @show "after new_ib" + barrier!(arch) + + TX, TY, TZ = topology(grid) + return ImmersedBoundaryGrid{TX, TY, TZ}(grid, new_ib) +end + function ImmersedBoundaryGrid(grid, ib; active_cells_map::Bool = true) arch = architecture(grid) From 4ef2f7ad17a31bd561207600ab0e876220af3f30 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:36:58 -0500 Subject: [PATCH 289/716] try it again --- src/OceanSimulations/load_balanced_regional_grid.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index eada6bf2..bcb47cc1 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -154,6 +154,7 @@ end import Oceananigans.ImmersedBoundaries: ImmersedBoundaryGrid using Oceananigans.ImmersedBoundaries: map_interior_active_cells, architecture, topology, map_active_z_columns +using Oceananigans.BoundaryConditions function ImmersedBoundaryGrid(grid, ib::GridFittedBottom) @@ -176,7 +177,7 @@ function ImmersedBoundaryGrid(grid, ib::GridFittedBottom) @show "after new_ib" barrier!(arch) - + TX, TY, TZ = topology(grid) return ImmersedBoundaryGrid{TX, TY, TZ}(grid, new_ib) end From 51d75cd403dce89881b5f3f877b59aaf25c008c3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:42:53 -0500 Subject: [PATCH 290/716] try again --- src/OceanSimulations/load_balanced_regional_grid.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index bcb47cc1..826f14da 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -149,6 +149,10 @@ function load_balanced_regional_grid(arch::SlabDistributed; z, halo) + nx, ny, _ = Base.size(grid) + + bottom_height = partition_global_array(arch, bottom_height, (nx, ny, 1)) + return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end From 1b8fa06ce509bef7c35cf38777976704a0c38d6d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:45:42 -0500 Subject: [PATCH 291/716] another try? --- src/OceanSimulations/load_balanced_regional_grid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 826f14da..9b3ab9c0 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -2,7 +2,7 @@ using ClimaOcean.Bathymetry using Oceananigans using Oceananigans.Architectures: arch_array, device, architecture using Oceananigans.DistributedComputations -using Oceananigans.DistributedComputations: Sizes, child_architecture, barrier!, all_reduce +using Oceananigans.DistributedComputations: Sizes, child_architecture, barrier!, all_reduce, partition_global_array using Oceananigans.ImmersedBoundaries: immersed_cell using KernelAbstractions: @index, @kernel using JLD2 From 12ed322b946f5cd4361cc0e9ab3075b313e9f876 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:18:12 -0500 Subject: [PATCH 292/716] ok, now it works, remove workings --- .../load_balanced_regional_grid.jl | 68 +------------------ 1 file changed, 2 insertions(+), 66 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 9b3ab9c0..462560a1 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -115,7 +115,8 @@ function load_balanced_regional_grid(arch::SlabDistributed; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) # Cannot have two dimensional vectors - # set! a field on `Distributed`. TODO: fix in Oceananigans + # set! a field on `Distributed`. + # TODO: fix in Oceananigans if ndims(bottom_height) == 2 bottom_height = reshape(bottom_height, Base.size(bottom_height)..., 1) end @@ -156,71 +157,6 @@ function load_balanced_regional_grid(arch::SlabDistributed; return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end -import Oceananigans.ImmersedBoundaries: ImmersedBoundaryGrid -using Oceananigans.ImmersedBoundaries: map_interior_active_cells, architecture, topology, map_active_z_columns -using Oceananigans.BoundaryConditions - -function ImmersedBoundaryGrid(grid, ib::GridFittedBottom) - - arch = architecture(grid) - - @show "before setting field" - barrier!(arch) - - bottom_field = Field{Center, Center, Nothing}(grid) - set!(bottom_field, ib.bottom_height) - - @show "after setting field" - barrier!(arch) - - fill_halo_regions!(bottom_field) - - @show "after fill halo" - barrier!(arch) - new_ib = GridFittedBottom(bottom_field, ib.immersed_condition) - - @show "after new_ib" - barrier!(arch) - - TX, TY, TZ = topology(grid) - return ImmersedBoundaryGrid{TX, TY, TZ}(grid, new_ib) -end - -function ImmersedBoundaryGrid(grid, ib; active_cells_map::Bool = true) - - arch = architecture(grid) - - @show "before immersed boundary" - barrier!(arch) - - ibg = ImmersedBoundaryGrid(grid, ib) - TX, TY, TZ = topology(ibg) - - @show "I am here!" - barrier!(arch) - - # Create the cells map on the CPU, then switch it to the GPU - if active_cells_map - interior_map = map_interior_active_cells(ibg) - - @show "after interior map" - barrier!(arch) - - column_map = map_active_z_columns(ibg) - - @show "after column map" - barrier!(arch) - else - interior_map = nothing - column_map = nothing - end - - return ImmersedBoundaryGrid{TX, TY, TZ}(ibg.underlying_grid, - ibg.immersed_boundary, - interior_map, - column_map) -end - @kernel function assess_load!(load_per_slab, grid, idx) i1 = @index(Global, Linear) sz = ifelse(idx == 1, size(grid, 2), size(grid, 1)) From 10a217a520a7ab025ebdc42e080764f844b638e3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:26:26 -0500 Subject: [PATCH 293/716] let's go --- experiments/twelth_degree_latlong.jl | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 46968b9a..8ee4006f 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -15,8 +15,20 @@ using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using Printf +using CUDA: @allowscalar using JLD2 +# Calculate barotropic substeps based on barotropic CFL number and wave speed +function barotropic_substeps(Δt, grid; + g = Oceananigans.BuoyancyModels.g_Earth, + CFL = 0.75) + wave_speed = sqrt(g * grid.Lz) + local_Δ = @allowscalar 1 / sqrt(1 / grid.Δxᶜᶜᵃ[1]^2 + 1 / grid.Δyᶠᶜᵃ^2) + global_Δ = MPI.Allreduce(local_Δ, min, grid.architecture.communicator) + + return max(Int(ceil(2 * Δt / (CFL / wave_speed * global_Δ))), 10) +end + ##### ##### Global Ocean at 1/12th of a degree ##### @@ -46,14 +58,14 @@ grid = load_balanced_regional_grid(arch; minimum_depth = 10, connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea bathymetry_file) - -@show grid - + ##### ##### The Ocean component ##### -free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=270) +substeps = barotropic_substeps(270, grid) + +free_surface = SplitExplicitFreeSurface(; substeps) ocean = ocean_simulation(grid; Δt = 10, free_surface, closure = RiBasedVerticalDiffusivity()) model = ocean.model From ac7070386b8e8b6ae1bebcd9efc62fbfbaf48b2a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:35:18 -0500 Subject: [PATCH 294/716] better progress --- experiments/twelth_degree_latlong.jl | 32 +++++++++++++++++----------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 8ee4006f..ef1ba31a 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -85,23 +85,29 @@ radiation = Radiation() coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) -wall_time = [time_ns()] +start_time = [time_ns()] -function progress(sim) - u, v, w = sim.model.velocities - T, S = sim.model.tracers +function progress(sim) + wall_time = (time_ns() - start_time[1]) * 1e-9 - step_time = 1e-9 * (time_ns() - wall_time[1]) + u = interior(sim.model.velocities.u) + v = interior(sim.model.velocities.v) + w = interior(sim.model.velocities.w) + η = interior(sim.model.free_surface.η) + T = interior(sim.model.tracers.T) + S = interior(sim.model.tracers.S) - @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", - prettytime(sim.model.clock.time), - sim.model.clock.iteration, - prettytime(sim.Δt), - maximum(abs, u), maximum(abs, v), maximum(abs, w), - maximum(abs, T), maximum(abs, S), step_time) + rk = sim.model.grid.architecture.local_rank - wall_time[1] = time_ns() -end + @info @sprintf("R: %02d, T: % 12s, it: %d, Δt: %.2f, vels: %.2e %.2e %.2e %.2e, trac: %.2e %.2e, wt : %s", + rk, prettytime(sim.model.clock.time), sim.model.clock.iteration, sim.Δt, + maximum(u), maximum(v), maximum(w), minimum(w), maximum(T), maximum(S), + prettytime(wall_time)) + + start_time[1] = time_ns() + + return nothing + end ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) From 2989126af484dd8adc16456d1a432bd79f5ab45b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 00:49:29 -0500 Subject: [PATCH 295/716] hmmmm --- src/DataWrangling/ECCO2.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index a572f6d3..af128699 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -275,10 +275,10 @@ function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename=" child_arch = child_architecture(arch) name = ecco2_metadata.name - mask = ecco2_center_mask(child_arch) - f_ecco = if arch.local_rank == 0 # Make sure we read/write the file using only one core - inpainted_ecco2_field(name; filename, mask, + mask = ecco2_center_mask(child_arch) + + inpainted_ecco2_field(name; filename, mask, architecture = child_arch, kw...) else From 0e9de404a8adcf79ce6f3ba509445260fcc9aa10 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 09:22:07 -0500 Subject: [PATCH 296/716] now it will work? --- src/InitialConditions/InitialConditions.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 6f700f7e..69d42504 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -71,7 +71,7 @@ function three_dimensional_interpolate!(a, b) target_grid = a.grid isa ImmersedBoundaryGrid ? a.grid.underlying_grid : a.grid source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid - topo = topology(target_grid) + topo = topology(source_grid) arch = architecture(target_grid) arch = child_architecture(arch) From 4e907aa93b4072dc7205f741368f77d1e1389829 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:10:46 -0500 Subject: [PATCH 297/716] allow interpolation on distributed grids --- src/InitialConditions/InitialConditions.jl | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 69d42504..ccf33363 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -67,6 +67,39 @@ function three_dimensional_regrid!(a, b) return a end +import Oceananigans.Fields: interpolate! +using Oceananigans.Fields: _interpolate! +using Oceananigans.Architectures: child_architecture + +""" + interpolate!(to_field::Field, from_field::AbstractField) + +Interpolate `from_field` `to_field` and then fill the halo regions of `to_field`. +""" +function interpolate!(to_field::Field, from_field::AbstractField) + to_grid = to_field.grid + from_grid = from_field.grid + + to_arch = child_architecture(architecture(to_field)) + from_arch = child_architecture(architecture(from_field)) + if !isnothing(from_arch) && to_arch != from_arch + msg = "Cannot interpolate! because from_field is on $from_arch while to_field is on $to_arch." + throw(ArgumentError(msg)) + end + + # Make locations + from_location = Tuple(L() for L in location(from_field)) + to_location = Tuple(L() for L in location(to_field)) + + launch!(to_arch, to_grid, size(to_field), + _interpolate!, to_field, to_grid, to_location, + from_field, from_grid, from_location) + + fill_halo_regions!(to_field) + + return nothing +end + function three_dimensional_interpolate!(a, b) target_grid = a.grid isa ImmersedBoundaryGrid ? a.grid.underlying_grid : a.grid source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid From b2b8633601bf2e3e359511d2b918d416ba2d4a7d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:24:35 -0500 Subject: [PATCH 298/716] let's go! --- src/InitialConditions/InitialConditions.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index ccf33363..a8781494 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -68,9 +68,11 @@ function three_dimensional_regrid!(a, b) end import Oceananigans.Fields: interpolate! -using Oceananigans.Fields: _interpolate! -using Oceananigans.Architectures: child_architecture - +using Oceananigans.Fields: _interpolate!, AbstractField +using Oceananigans.Architectures: child_architecture, architecture +using Oceananigans.Utils: launch! +using Oceananigans.BoundaryConditions + """ interpolate!(to_field::Field, from_field::AbstractField) From 61f4e062eab871a5c7f7ab2f70078fdb5bbdad18 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 15:08:46 -0500 Subject: [PATCH 299/716] small test --- .../CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl | 6 ++++-- .../CrossRealmFluxes/three_dimensional_operators.jl | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index b12207eb..4680d1e4 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -423,12 +423,14 @@ end end end +include("three_dimensional_operators.jl") + @kernel function reconstruct_momentum_fluxes!(grid, J, Jᶜᶜᶜ) i, j = @index(Global, NTuple) @inbounds begin - J.u[i, j, 1] = ℑxᶠᵃᵃ(i, j, 1, grid, Jᶜᶜᶜ.u) - J.v[i, j, 1] = ℑyᵃᶠᵃ(i, j, 1, grid, Jᶜᶜᶜ.v) + J.u[i, j, 1] = ℑxᶠᶜᶜ(i, j, 1, grid, Jᶜᶜᶜ.u) + J.v[i, j, 1] = ℑyᶜᶠᶜ(i, j, 1, grid, Jᶜᶜᶜ.v) end end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl new file mode 100644 index 00000000..940ab1eb --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl @@ -0,0 +1,12 @@ +using Oceananigans.Operators +using Oceananigans.ImmersedBoundaries: c, f + +@inline ı(i, j, k, grid, f::Function, args...) = f(i, j, k, grid, args...) +@inline ı(i, j, k, grid, ϕ) = ϕ[i, j, k] + +# Defining Interpolation operators for the immersed boundaries +@inline conditional_ℑx_f(LY, LZ, i, j, k, grid, c) = ifelse(inactive_node(i, j, k, grid, c, LY, LZ), ı(i-1, j, k, grid, args...), ifelse(inactive_node(i-1, j, k, grid, c, LY, LZ), ı(i, j, k, grid, args...), ℑxᶠᵃᵃ(i, j, k, grid, args...))) +@inline conditional_ℑy_f(LX, LZ, i, j, k, grid, c) = ifelse(inactive_node(i, j, k, grid, LX, c, LZ), ı(i, j-1, k, grid, args...), ifelse(inactive_node(i, j-1, k, grid, LX, c, LZ), ı(i, j, k, grid, args...), ℑyᵃᶠᵃ(i, j, k, grid, args...))) + +ℑxᶠᶜᶜ(i, j, k, grid, c) = conditional_ℑx_f(c, c, i, j, k, grid, c) +ℑyᶜᶠᶜ(i, j, k, grid, c) = conditional_ℑy_f(c, c, i, j, k, grid, c) \ No newline at end of file From 3731a072c22c0147173ee94e40d674009e845ef9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 15:59:47 -0500 Subject: [PATCH 300/716] bugfix --- .../CrossRealmFluxes/three_dimensional_operators.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl index 940ab1eb..c3015265 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl @@ -5,8 +5,8 @@ using Oceananigans.ImmersedBoundaries: c, f @inline ı(i, j, k, grid, ϕ) = ϕ[i, j, k] # Defining Interpolation operators for the immersed boundaries -@inline conditional_ℑx_f(LY, LZ, i, j, k, grid, c) = ifelse(inactive_node(i, j, k, grid, c, LY, LZ), ı(i-1, j, k, grid, args...), ifelse(inactive_node(i-1, j, k, grid, c, LY, LZ), ı(i, j, k, grid, args...), ℑxᶠᵃᵃ(i, j, k, grid, args...))) -@inline conditional_ℑy_f(LX, LZ, i, j, k, grid, c) = ifelse(inactive_node(i, j, k, grid, LX, c, LZ), ı(i, j-1, k, grid, args...), ifelse(inactive_node(i, j-1, k, grid, LX, c, LZ), ı(i, j, k, grid, args...), ℑyᵃᶠᵃ(i, j, k, grid, args...))) +@inline conditional_ℑx_f(LY, LZ, i, j, k, grid, t) = ifelse(inactive_node(i, j, k, grid, c, LY, LZ), ı(i-1, j, k, grid, t), ifelse(inactive_node(i-1, j, k, grid, c, LY, LZ), ı(i, j, k, grid, t), ℑxᶠᵃᵃ(i, j, k, grid, t))) +@inline conditional_ℑy_f(LX, LZ, i, j, k, grid, t) = ifelse(inactive_node(i, j, k, grid, LX, c, LZ), ı(i, j-1, k, grid, t), ifelse(inactive_node(i, j-1, k, grid, LX, c, LZ), ı(i, j, k, grid, t), ℑyᵃᶠᵃ(i, j, k, grid, t))) -ℑxᶠᶜᶜ(i, j, k, grid, c) = conditional_ℑx_f(c, c, i, j, k, grid, c) -ℑyᶜᶠᶜ(i, j, k, grid, c) = conditional_ℑy_f(c, c, i, j, k, grid, c) \ No newline at end of file +ℑxᶠᶜᶜ(i, j, k, grid, t) = conditional_ℑx_f(c, c, i, j, k, grid, t) +ℑyᶜᶠᶜ(i, j, k, grid, t) = conditional_ℑy_f(c, c, i, j, k, grid, t) \ No newline at end of file From c6de168c572ef6834aab632263ab46cc090c0b86 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 16:52:10 -0500 Subject: [PATCH 301/716] try it like this --- .../CrossRealmFluxes/three_dimensional_operators.jl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl index c3015265..f8bfa53c 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl @@ -5,8 +5,13 @@ using Oceananigans.ImmersedBoundaries: c, f @inline ı(i, j, k, grid, ϕ) = ϕ[i, j, k] # Defining Interpolation operators for the immersed boundaries -@inline conditional_ℑx_f(LY, LZ, i, j, k, grid, t) = ifelse(inactive_node(i, j, k, grid, c, LY, LZ), ı(i-1, j, k, grid, t), ifelse(inactive_node(i-1, j, k, grid, c, LY, LZ), ı(i, j, k, grid, t), ℑxᶠᵃᵃ(i, j, k, grid, t))) -@inline conditional_ℑy_f(LX, LZ, i, j, k, grid, t) = ifelse(inactive_node(i, j, k, grid, LX, c, LZ), ı(i, j-1, k, grid, t), ifelse(inactive_node(i, j-1, k, grid, LX, c, LZ), ı(i, j, k, grid, t), ℑyᵃᶠᵃ(i, j, k, grid, t))) +@inline conditional_ℑx_f(LY, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, c, LY, LZ), ı(i-1, j, k, grid, t), ifelse(peripheral_node(i-1, j, k, grid, c, LY, LZ), ı(i, j, k, grid, t), ℑxᶠᵃᵃ(i, j, k, grid, t))) +@inline conditional_ℑy_f(LX, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, LX, c, LZ), ı(i, j-1, k, grid, t), ifelse(peripheral_node(i, j-1, k, grid, LX, c, LZ), ı(i, j, k, grid, t), ℑyᵃᶠᵃ(i, j, k, grid, t))) +@inline conditional_ℑx_c(LY, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, f, LY, LZ), ı(i+1, j, k, grid, t), ifelse(peripheral_node(i+1, j, k, grid, f, LY, LZ), ı(i, j, k, grid, t), ℑxᶜᵃᵃ(i, j, k, grid, t))) +@inline conditional_ℑy_c(LX, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, LX, f, LZ), ı(i, j+1, k, grid, t), ifelse(peripheral_node(i, j+1, k, grid, LX, f, LZ), ı(i, j, k, grid, t), ℑyᵃᶜᵃ(i, j, k, grid, t))) ℑxᶠᶜᶜ(i, j, k, grid, t) = conditional_ℑx_f(c, c, i, j, k, grid, t) -ℑyᶜᶠᶜ(i, j, k, grid, t) = conditional_ℑy_f(c, c, i, j, k, grid, t) \ No newline at end of file +ℑyᶜᶠᶜ(i, j, k, grid, t) = conditional_ℑy_f(c, c, i, j, k, grid, t) + +ℑxᶜᶜᶜ(i, j, k, grid, t) = conditional_ℑx_c(c, c, i, j, k, grid, t) +ℑyᶜᶜᶜ(i, j, k, grid, t) = conditional_ℑy_c(c, c, i, j, k, grid, t) \ No newline at end of file From e6afc9e2ee8391d6d2403fc4cd7da00d1265fc5b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 16:54:25 -0500 Subject: [PATCH 302/716] try like this? --- src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl | 2 +- .../CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 8a423205..e8c673c8 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -59,10 +59,10 @@ function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) return sfc_tracers end +include("three_dimensional_operators.jl") include("radiation.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") include("sea_ice_ocean_fluxes.jl") -# include("atmosphere_sea_ice_fluxes.jl") end # module diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 4680d1e4..bf4ce640 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -248,8 +248,8 @@ const f = Face() # 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ₒ = ℑxᶜᶜᶜ(i, j, 1, grid, ocean_state.u) + vₒ = ℑyᶜᶜᶜ(i, j, 1, grid, ocean_state.v) Tₒ = ocean_state.T[i, j, 1] Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) Sₒ = ocean_state.S[i, j, 1] @@ -423,8 +423,6 @@ end end end -include("three_dimensional_operators.jl") - @kernel function reconstruct_momentum_fluxes!(grid, J, Jᶜᶜᶜ) i, j = @index(Global, NTuple) From 565395b2182b8f206806a06880238b347d78e33d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 16:59:31 -0500 Subject: [PATCH 303/716] try it now --- .../three_dimensional_operators.jl | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl index f8bfa53c..c5187906 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl @@ -1,17 +1,16 @@ using Oceananigans.Operators -using Oceananigans.ImmersedBoundaries: c, f @inline ı(i, j, k, grid, f::Function, args...) = f(i, j, k, grid, args...) @inline ı(i, j, k, grid, ϕ) = ϕ[i, j, k] # Defining Interpolation operators for the immersed boundaries -@inline conditional_ℑx_f(LY, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, c, LY, LZ), ı(i-1, j, k, grid, t), ifelse(peripheral_node(i-1, j, k, grid, c, LY, LZ), ı(i, j, k, grid, t), ℑxᶠᵃᵃ(i, j, k, grid, t))) -@inline conditional_ℑy_f(LX, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, LX, c, LZ), ı(i, j-1, k, grid, t), ifelse(peripheral_node(i, j-1, k, grid, LX, c, LZ), ı(i, j, k, grid, t), ℑyᵃᶠᵃ(i, j, k, grid, t))) -@inline conditional_ℑx_c(LY, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, f, LY, LZ), ı(i+1, j, k, grid, t), ifelse(peripheral_node(i+1, j, k, grid, f, LY, LZ), ı(i, j, k, grid, t), ℑxᶜᵃᵃ(i, j, k, grid, t))) -@inline conditional_ℑy_c(LX, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, LX, f, LZ), ı(i, j+1, k, grid, t), ifelse(peripheral_node(i, j+1, k, grid, LX, f, LZ), ı(i, j, k, grid, t), ℑyᵃᶜᵃ(i, j, k, grid, t))) +@inline conditional_ℑx_f(LY, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, Center(), LY, LZ), ı(i-1, j, k, grid, t), ifelse(peripheral_node(i-1, j, k, grid, Center(), LY, LZ), ı(i, j, k, grid, t), ℑxᶠᵃᵃ(i, j, k, grid, t))) +@inline conditional_ℑy_f(LX, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, LX, Center(), LZ), ı(i, j-1, k, grid, t), ifelse(peripheral_node(i, j-1, k, grid, LX, Center(), LZ), ı(i, j, k, grid, t), ℑyᵃᶠᵃ(i, j, k, grid, t))) +@inline conditional_ℑx_c(LY, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, Face(), LY, LZ), ı(i+1, j, k, grid, t), ifelse(peripheral_node(i+1, j, k, grid, Face(), LY, LZ), ı(i, j, k, grid, t), ℑxᶜᵃᵃ(i, j, k, grid, t))) +@inline conditional_ℑy_c(LX, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, LX, Face(), LZ), ı(i, j+1, k, grid, t), ifelse(peripheral_node(i, j+1, k, grid, LX, Face(), LZ), ı(i, j, k, grid, t), ℑyᵃᶜᵃ(i, j, k, grid, t))) -ℑxᶠᶜᶜ(i, j, k, grid, t) = conditional_ℑx_f(c, c, i, j, k, grid, t) -ℑyᶜᶠᶜ(i, j, k, grid, t) = conditional_ℑy_f(c, c, i, j, k, grid, t) +ℑxᶠᶜᶜ(i, j, k, grid, t) = conditional_ℑx_f(Center(), Center(), i, j, k, grid, t) +ℑyᶜᶠᶜ(i, j, k, grid, t) = conditional_ℑy_f(Center(), Center(), i, j, k, grid, t) -ℑxᶜᶜᶜ(i, j, k, grid, t) = conditional_ℑx_c(c, c, i, j, k, grid, t) -ℑyᶜᶜᶜ(i, j, k, grid, t) = conditional_ℑy_c(c, c, i, j, k, grid, t) \ No newline at end of file +ℑxᶜᶜᶜ(i, j, k, grid, t) = conditional_ℑx_c(Center(), Center(), i, j, k, grid, t) +ℑyᶜᶜᶜ(i, j, k, grid, t) = conditional_ℑy_c(Center(), Center(), i, j, k, grid, t) \ No newline at end of file From 908da866970e638ada709f212405c8578359b9eb Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:33:42 -0500 Subject: [PATCH 304/716] another bugfix --- .../CrossRealmFluxes/three_dimensional_operators.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl index c5187906..9688ba25 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl @@ -1,4 +1,5 @@ using Oceananigans.Operators +using Oceananigans.Grids: peripheral_node @inline ı(i, j, k, grid, f::Function, args...) = f(i, j, k, grid, args...) @inline ı(i, j, k, grid, ϕ) = ϕ[i, j, k] From 40b24778c27dfafb4a6d4f9e0c344accc3f20223 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 7 Mar 2024 09:41:27 -0500 Subject: [PATCH 305/716] add drag --- src/OceanSimulations/OceanSimulations.jl | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index aca0bc19..a47cab62 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -34,6 +34,16 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), WENO(; order = 7), Centered()) +@inline ϕ²(i, j, k, grid, ϕ) = @inbounds ϕ[i, j, k]^2 +@inline speedᶠᶜᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.u[i, j, k]^2 + ℑxyᶠᶜᵃ(i, j, k, grid, ϕ², Φ.v)) +@inline speedᶜᶠᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.v[i, j, k]^2 + ℑxyᶜᶠᵃ(i, j, k, grid, ϕ², Φ.u)) + +@inline u_drag_bc(i, j, grid, Φ, μ) = @inbounds - μ * Φ.u[i, j, 1] * speedᶠᶜᶜ(i, j, 1, grid, Φ) +@inline v_drag_bc(i, j, grid, Φ, μ) = @inbounds - μ * Φ.v[i, j, 1] * speedᶜᶠᶜ(i, j, 1, grid, Φ) + +@inline u_immersed_drag_bc(i, j, k, grid, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * speedᶠᶜᶜ(i, j, k, grid, Φ) +@inline v_immersed_drag_bc(i, j, k, grid, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * speedᶜᶠᶜ(i, j, k, grid, Φ) + # 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; Δt = 5minutes, @@ -42,6 +52,7 @@ function ocean_simulation(grid; Δt = 5minutes, reference_density = 1020, rotation_rate = Ω_Earth, gravitational_acceleration = g_Earth, + drag_coefficient = 0.003, momentum_advection = default_momentum_advection(), tracer_advection = default_tracer_advection()) @@ -51,8 +62,13 @@ function ocean_simulation(grid; Δt = 5minutes, 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ᵛ)), + u_bottom_drag = FluxBoundaryCondition(u_drag_bc, discrete_form=true, parameters=drag_coefficient) + v_bottom_drag = FluxBoundaryCondition(v_drag_bc, discrete_form=true, parameters=drag_coefficient) + u_immersed_drag = FluxBoundaryCondition(u_immmersed_drag_bc, discrete_form=true, parameters=drag_coefficient) + v_immersed_drag = FluxBoundaryCondition(v_immmersed_drag_bc, discrete_form=true, parameters=drag_coefficient) + + ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵘ), bottom = u_bottom_drag, immersed = u_immersed_drag), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵛ), bottom = v_bottom_drag, immersed = v_immersed_drag), T = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵀ)), S = FieldBoundaryConditions(top=FluxBoundaryCondition(Jˢ))) From b56a1d1091e1aa683af2ea06b0f19976d159bc0e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 7 Mar 2024 09:41:47 -0500 Subject: [PATCH 306/716] add bottom drag --- src/OceanSimulations/OceanSimulations.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index a47cab62..60b8f863 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -62,8 +62,8 @@ function ocean_simulation(grid; Δt = 5minutes, top_ocean_heat_flux = Jᵀ = Field{Center, Center, Nothing}(grid) top_salt_flux = Jˢ = Field{Center, Center, Nothing}(grid) - u_bottom_drag = FluxBoundaryCondition(u_drag_bc, discrete_form=true, parameters=drag_coefficient) - v_bottom_drag = FluxBoundaryCondition(v_drag_bc, discrete_form=true, parameters=drag_coefficient) + u_bottom_drag = FluxBoundaryCondition(u_drag_bc, discrete_form=true, parameters=drag_coefficient) + v_bottom_drag = FluxBoundaryCondition(v_drag_bc, discrete_form=true, parameters=drag_coefficient) u_immersed_drag = FluxBoundaryCondition(u_immmersed_drag_bc, discrete_form=true, parameters=drag_coefficient) v_immersed_drag = FluxBoundaryCondition(v_immmersed_drag_bc, discrete_form=true, parameters=drag_coefficient) From 6744537c4cf6a6f333bf5fa0300b8d37deb67439 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 11 Mar 2024 09:29:03 -0400 Subject: [PATCH 307/716] small correction --- src/OceanSimulations/OceanSimulations.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 60b8f863..4d30bfcf 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -67,8 +67,11 @@ function ocean_simulation(grid; Δt = 5minutes, u_immersed_drag = FluxBoundaryCondition(u_immmersed_drag_bc, discrete_form=true, parameters=drag_coefficient) v_immersed_drag = FluxBoundaryCondition(v_immmersed_drag_bc, discrete_form=true, parameters=drag_coefficient) - ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵘ), bottom = u_bottom_drag, immersed = u_immersed_drag), - v = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵛ), bottom = v_bottom_drag, immersed = v_immersed_drag), + u_immersed_bc = ImmersedBoundaryCondition(bottom=u_immersed_drag) + v_immersed_bc = ImmersedBoundaryCondition(bottom=v_immersed_drag) + + ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵘ), bottom = u_bottom_drag, immersed = u_immersed_bc), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵛ), bottom = v_bottom_drag, immersed = v_immersed_bc), T = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵀ)), S = FieldBoundaryConditions(top=FluxBoundaryCondition(Jˢ))) From f06ea26b651bd41164c559f9d88e03b389e56076 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sun, 14 Apr 2024 16:14:48 -0400 Subject: [PATCH 308/716] bugfix --- src/DataWrangling/JRA55.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 72544329..dcf736d9 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -19,7 +19,7 @@ using JLD2 using Dates 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: @@ -170,7 +170,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) @@ -418,7 +417,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] From 2ec4a627f9c16c09943575ac319f8e649f6bdc0e Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sun, 14 Apr 2024 18:14:24 -0400 Subject: [PATCH 309/716] now this should work! --- experiments/twelth_degree_latlong.jl | 92 ++++++++----------- src/DataWrangling/JRA55.jl | 14 ++- .../ocean_sea_ice_surface_fluxes.jl | 35 ++++++- src/OceanSeaIceModels/ocean_only_model.jl | 2 +- src/OceanSimulations/OceanSimulations.jl | 17 ++-- 5 files changed, 90 insertions(+), 70 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index ef1ba31a..bc62332b 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -1,6 +1,3 @@ -using MPI -MPI.Init() - using Oceananigans using Oceananigans: architecture using ClimaOcean @@ -15,37 +12,27 @@ using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using Printf -using CUDA: @allowscalar -using JLD2 - -# Calculate barotropic substeps based on barotropic CFL number and wave speed -function barotropic_substeps(Δt, grid; - g = Oceananigans.BuoyancyModels.g_Earth, - CFL = 0.75) - wave_speed = sqrt(g * grid.Lz) - local_Δ = @allowscalar 1 / sqrt(1 / grid.Δxᶜᶜᵃ[1]^2 + 1 / grid.Δyᶠᶜᵃ^2) - global_Δ = MPI.Allreduce(local_Δ, min, grid.architecture.communicator) - - return max(Int(ceil(2 * Δt / (CFL / wave_speed * global_Δ))), 10) -end +using CUDA +using CairoMakie +using SixelTerm +# CUDA.device!(2) + +include("correct_oceananigans.jl") ##### ##### Global Ocean at 1/12th of a degree ##### -include("correct_oceananigans.jl") -bathymetry_file = "bathymetry12.jld2" +bathymetry_file = nothing # "bathymetry_tmp.jld2" # 100 vertical levels -z_faces = exponential_z_faces(Nz=100, depth=6000) +z_faces = exponential_z_faces(Nz=50, depth=6500) -Nx = 4320 -Ny = 1800 +Nx = 720 +Ny = 360 Nz = length(z_faces) - 1 -bottom = zeros(Nx, Ny, 1) - -arch = Distributed(GPU(), partition = Partition(8)) +arch = CPU() #Distributed(GPU(), partition = Partition(2)) grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), @@ -54,20 +41,19 @@ grid = load_balanced_regional_grid(arch; longitude = (0, 360), halo = (7, 7, 7), interpolation_passes = 20, - maximum_size = 650, minimum_depth = 10, connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea bathymetry_file) - + +@show grid + ##### ##### The Ocean component ##### -substeps = barotropic_substeps(270, grid) +free_surface = SplitExplicitFreeSurface(; grid, cfl=0.75, fixed_Δt = 15minutes) -free_surface = SplitExplicitFreeSurface(; substeps) - -ocean = ocean_simulation(grid; Δt = 10, free_surface, closure = RiBasedVerticalDiffusivity()) +ocean = ocean_simulation(grid; free_surface) model = ocean.model # Initializing the model @@ -79,62 +65,56 @@ set!(model, ##### The atmosphere ##### -backend = JRA55NetCDFBackend(5) +backend = JRA55NetCDFBackend(10) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation() coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) -start_time = [time_ns()] - -function progress(sim) - wall_time = (time_ns() - start_time[1]) * 1e-9 +wall_time = [time_ns()] - u = interior(sim.model.velocities.u) - v = interior(sim.model.velocities.v) - w = interior(sim.model.velocities.w) - η = interior(sim.model.free_surface.η) - T = interior(sim.model.tracers.T) - S = interior(sim.model.tracers.S) +function progress(sim) + u, v, w = sim.model.velocities + T, S = sim.model.tracers - rk = sim.model.grid.architecture.local_rank + step_time = 1e-9 * (time_ns() - wall_time[1]) - @info @sprintf("R: %02d, T: % 12s, it: %d, Δt: %.2f, vels: %.2e %.2e %.2e %.2e, trac: %.2e %.2e, wt : %s", - rk, prettytime(sim.model.clock.time), sim.model.clock.iteration, sim.Δt, - maximum(u), maximum(v), maximum(w), minimum(w), maximum(T), maximum(S), - prettytime(wall_time)) + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", + prettytime(sim.model.clock.time), + sim.model.clock.iteration, + prettytime(sim.Δt), + maximum(abs, u), maximum(abs, v), maximum(abs, w), + maximum(abs, T), maximum(abs, S), prettytime(step_time)) - start_time[1] = time_ns() - - return nothing - end + wall_time[1] = time_ns() +end -ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) +ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), schedule = TimeInterval(30days), overwrite_existing = true, array_type = Array{Float32}, - filename = "snapshots_$(arch.local_rank)") + filename = "snapshots") ocean.output_writers[:checkpoint] = Checkpointer(model, schedule = TimeInterval(60days), overwrite_existing = true, - prefix = "checkpoint_$(arch.local_rank)") + prefix = "checkpoint") # Simulation warm up! ocean.Δt = 10 ocean.stop_iteration = 1 -wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 90, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 20, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -stop_time = 5days +stop_time = 1days coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) run!(coupled_simulation) -wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 270, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 20minutes, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index dcf736d9..e1a15191 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -3,6 +3,7 @@ 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! @@ -14,6 +15,8 @@ using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, TwoStreamDownwellingRadiation +using CUDA: @allowscalar + using NCDatasets using JLD2 using Dates @@ -125,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 @@ -474,7 +479,9 @@ function JRA55_field_time_series(variable_name; @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(fts.grid; + 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, @@ -485,7 +492,8 @@ function JRA55_field_time_series(variable_name; 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() diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index bf4ce640..02b56db7 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -134,7 +134,6 @@ const f = Face() function compute_atmosphere_ocean_fluxes!(coupled_model) ocean = coupled_model.ocean - sea_ice = coupled_model.sea_ice atmosphere = coupled_model.atmosphere atmosphere_grid = atmosphere.grid @@ -156,7 +155,6 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) net_tracer_fluxes = coupled_model.fluxes.total.ocean.tracers similarity_theory = coupled_model.fluxes.turbulent - prescribed_fluxes = coupled_model.fluxes.prescribed radiation_properties = coupled_model.fluxes.radiation ocean_state = merge(ocean_velocities, ocean_tracers) @@ -449,6 +447,39 @@ end ##### Utility for interpolating tuples of fields ##### +# import Oceananigans.Fields: interpolate +# using Oceananigans: OffsetArray +# using Oceananigans.Grids: AbstractGrid + +# using Oceananigans.OutputReaders: fractional_indices, interpolator, interpolating_time_indices, memory_index, _interpolate + +# @inline function interpolate(at_node, at_time_index::Time, data::OffsetArray, +# from_loc, from_grid::AbstractGrid, times, backend, time_indexing) + +# at_time = at_time_index.time + +# # Build space interpolators +# ii, jj, kk = fractional_indices(at_node, from_grid, from_loc...) + +# ix = interpolator(ii) +# iy = interpolator(jj) +# iz = interpolator(kk) + +# ñ, n₁, n₂ = interpolating_time_indices(time_indexing, times, at_time) + +# Nt = length(times) +# m₁ = memory_index(backend, time_indexing, Nt, n₁) +# m₂ = memory_index(backend, time_indexing, Nt, n₂) + +# @show m₁, m₂, ñ, at_time, times +# ψ₁ = _interpolate(data, ix, iy, iz, m₁) +# ψ₂ = _interpolate(data, ix, iy, iz, m₂) +# ψ̃ = ψ₂ * ñ + ψ₁ * (1 - ñ) + +# # Don't interpolate if n₁ == n₂ +# return ifelse(n₁ == n₂, ψ₁, ψ̃) +# end + # Note: assumes loc = (c, c, nothing) (and the third location should # not matter.) @inline interp_atmos_time_series(J, X, time, grid, args...) = diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 7e8c71d8..c258b2c8 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -14,7 +14,7 @@ function time_step!(coupled_model::OceanOnlyModel, Δt; callbacks=[], compute_te time_step!(ocean) - tick!(coupled_model.clock, Δt) + tick!(coupled_model.clock, ocean.Δt) update_state!(coupled_model, callbacks; compute_tendencies) return nothing diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 4d30bfcf..ee1fcfe9 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -14,10 +14,11 @@ using SeawaterPolynomials.TEOS10: TEOS10EquationOfState using Oceananigans.BuoyancyModels: g_Earth using Oceananigans.Coriolis: Ω_Earth +using Oceananigans.Operators include("load_balanced_regional_grid.jl") -# Some defualts +# Some defaults default_free_surface(grid) = SplitExplicitFreeSurface(; cfl=0.7, grid) function default_ocean_closure() @@ -34,15 +35,15 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), WENO(; order = 7), Centered()) -@inline ϕ²(i, j, k, grid, ϕ) = @inbounds ϕ[i, j, k]^2 +@inline ϕ²(i, j, k, grid, ϕ) = @inbounds ϕ[i, j, k]^2 @inline speedᶠᶜᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.u[i, j, k]^2 + ℑxyᶠᶜᵃ(i, j, k, grid, ϕ², Φ.v)) @inline speedᶜᶠᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.v[i, j, k]^2 + ℑxyᶜᶠᵃ(i, j, k, grid, ϕ², Φ.u)) -@inline u_drag_bc(i, j, grid, Φ, μ) = @inbounds - μ * Φ.u[i, j, 1] * speedᶠᶜᶜ(i, j, 1, grid, Φ) -@inline v_drag_bc(i, j, grid, Φ, μ) = @inbounds - μ * Φ.v[i, j, 1] * speedᶜᶠᶜ(i, j, 1, grid, Φ) +@inline u_drag_bc(i, j, grid, clock, Φ, μ) = @inbounds - μ * Φ.u[i, j, 1] * speedᶠᶜᶜ(i, j, 1, grid, Φ) +@inline v_drag_bc(i, j, grid, clock, Φ, μ) = @inbounds - μ * Φ.v[i, j, 1] * speedᶜᶠᶜ(i, j, 1, grid, Φ) -@inline u_immersed_drag_bc(i, j, k, grid, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * speedᶠᶜᶜ(i, j, k, grid, Φ) -@inline v_immersed_drag_bc(i, j, k, grid, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * speedᶜᶠᶜ(i, j, k, grid, Φ) +@inline u_immersed_drag_bc(i, j, k, grid, clock, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * speedᶠᶜᶜ(i, j, k, grid, Φ) +@inline v_immersed_drag_bc(i, j, k, grid, clock, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * speedᶜᶠᶜ(i, j, k, grid, Φ) # 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... @@ -64,8 +65,8 @@ function ocean_simulation(grid; Δt = 5minutes, u_bottom_drag = FluxBoundaryCondition(u_drag_bc, discrete_form=true, parameters=drag_coefficient) v_bottom_drag = FluxBoundaryCondition(v_drag_bc, discrete_form=true, parameters=drag_coefficient) - u_immersed_drag = FluxBoundaryCondition(u_immmersed_drag_bc, discrete_form=true, parameters=drag_coefficient) - v_immersed_drag = FluxBoundaryCondition(v_immmersed_drag_bc, discrete_form=true, parameters=drag_coefficient) + u_immersed_drag = FluxBoundaryCondition(u_immersed_drag_bc, discrete_form=true, parameters=drag_coefficient) + v_immersed_drag = FluxBoundaryCondition(v_immersed_drag_bc, discrete_form=true, parameters=drag_coefficient) u_immersed_bc = ImmersedBoundaryCondition(bottom=u_immersed_drag) v_immersed_bc = ImmersedBoundaryCondition(bottom=v_immersed_drag) From 7423f488190ed03912cd9dfca9fc7d101bc12496 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sun, 14 Apr 2024 18:34:03 -0400 Subject: [PATCH 310/716] small correction --- experiments/twelth_degree_latlong.jl | 2 +- src/OceanSeaIceModels/ocean_only_model.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index bc62332b..fb125a1f 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -32,7 +32,7 @@ Nx = 720 Ny = 360 Nz = length(z_faces) - 1 -arch = CPU() #Distributed(GPU(), partition = Partition(2)) +arch = GPU() #Distributed(GPU(), partition = Partition(2)) grid = load_balanced_regional_grid(arch; size = (Nx, Ny, Nz), diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index c258b2c8..0cb8a4a1 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -14,7 +14,7 @@ function time_step!(coupled_model::OceanOnlyModel, Δt; callbacks=[], compute_te time_step!(ocean) - tick!(coupled_model.clock, ocean.Δt) + tick!(coupled_model.clock, ocean.Δt) # An Ocean-only model advances with the ocean time-step! update_state!(coupled_model, callbacks; compute_tendencies) return nothing From 577c6ea8827c730c6292d61fb8a6e5f143aa9ce9 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sun, 14 Apr 2024 18:36:43 -0400 Subject: [PATCH 311/716] ocean only model --- src/OceanSeaIceModels/ocean_only_model.jl | 46 ----------------------- 1 file changed, 46 deletions(-) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 0cb8a4a1..c92546b7 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -20,49 +20,3 @@ function time_step!(coupled_model::OceanOnlyModel, Δt; callbacks=[], compute_te return nothing end -#= -compute_ice_ocean_salinity_flux!(::OceanOnlyModel) = nothing -ice_ocean_latent_heat!(::OceanOnlyModel) = nothing - -##### -##### Air-sea fluxes -##### - -function time_step!(coupled_model::OceanOnlyModel, Δt; callbacks=nothing) - time_step!(ocean) - tick!(coupled_model.clock, Δt) - return nothing -end - -function update_state!(coupled_model::OceanOnlyModel; callbacks=nothing) - compute_air_sea_flux!(coupled_model) - return nothing -end - -function compute_air_sea_fluxes!(coupled_model::OceanOnlyModel) - ocean = coupled_model.ocean - forcing = coupled_model.atmospheric_forcing - - (; T, S) = ocean.model.tracers - (; u, v) = ocean.model.velocities - - grid = ocean.model.grid - clock = ocean.model.clock - fields = prognostic_fields(ocean.model) - - Qˢ = T.boundary_conditions.top.condition - Fˢ = S.boundary_conditions.top.condition - τˣ = u.boundary_conditions.top.condition - τʸ = v.boundary_conditions.top.condition - - ε = coupled_model.ocean_emissivity - ρₒ = coupled_model.ocean_reference_density - cₒ = coupled_model.ocean_heat_capacity - I₀ = coupled_model.solar_insolation - - launch!(ocean, :xy, _calculate_air_sea_fluxes!, Qˢ, Fˢ, τˣ, τʸ, ρₒ, cₒ, ε, Iₒ, - grid, clock, fields, forcing, nothing) - - return nothing -end -=# From b2f8c8f2ec0c3ab726dfd657391bb96d2a64a9ec Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sun, 14 Apr 2024 18:43:03 -0400 Subject: [PATCH 312/716] small fixes --- src/OceanSeaIceModels/ocean_only_model.jl | 2 -- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 10 +++++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index c92546b7..6b4a1e9c 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -1,7 +1,5 @@ const OceanOnlyModel = OceanSeaIceModel{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 8a0cb264..065fc933 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -59,12 +59,16 @@ end function OceanSeaIceModel(ocean, sea_ice=nothing; atmosphere = nothing, radiation = nothing, - ocean_reference_density = reference_density(ocean), - ocean_heat_capacity = heat_capacity(ocean), + reference_density = reference_density(ocean), + heat_capacity = heat_capacity(ocean), clock = deepcopy(ocean.model.clock)) # Contains information about flux contributions: bulk formula, prescribed fluxes, etc. - fluxes = OceanSeaIceSurfaceFluxes(ocean, sea_ice; atmosphere, radiation) + fluxes = OceanSeaIceSurfaceFluxes(ocean, sea_ice; + atmosphere, + reference_density, + heat_capacity, + radiation) ocean_sea_ice_model = OceanSeaIceModel(clock, ocean.model.grid, From 2123bafe0c28cc24f43374e98c567e3c85fc3fd4 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:02:37 -0400 Subject: [PATCH 313/716] try it out --- experiments/twelth_degree_latlong.jl | 34 ++++++++---- .../ocean_sea_ice_surface_fluxes.jl | 54 +++++++++++-------- src/OceanSeaIceModels/OceanSeaIceModels.jl | 1 + .../minimum_temperature_sea_ice.jl | 46 ++++++++++++++++ src/OceanSeaIceModels/ocean_only_model.jl | 5 +- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 8 +-- .../time_step_ocean_sea_ice_model.jl | 1 + src/OceanSimulations/OceanSimulations.jl | 3 +- 8 files changed, 113 insertions(+), 39 deletions(-) create mode 100644 src/OceanSeaIceModels/minimum_temperature_sea_ice.jl diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index fb125a1f..9a17d82c 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -26,10 +26,10 @@ include("correct_oceananigans.jl") bathymetry_file = nothing # "bathymetry_tmp.jld2" # 100 vertical levels -z_faces = exponential_z_faces(Nz=50, depth=6500) +z_faces = exponential_z_faces(Nz=60, depth=6500) Nx = 720 -Ny = 360 +Ny = 300 Nz = length(z_faces) - 1 arch = GPU() #Distributed(GPU(), partition = Partition(2)) @@ -51,9 +51,12 @@ grid = load_balanced_regional_grid(arch; ##### The Ocean component ##### -free_surface = SplitExplicitFreeSurface(; grid, cfl=0.75, fixed_Δt = 15minutes) +free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt = 20minutes) +vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = 5e-4) -ocean = ocean_simulation(grid; free_surface) +closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) + +ocean = ocean_simulation(grid; free_surface, closure) model = ocean.model # Initializing the model @@ -69,7 +72,9 @@ backend = JRA55NetCDFBackend(10) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation() -coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) +sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() + +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) wall_time = [time_ns()] @@ -105,20 +110,29 @@ ocean.output_writers[:checkpoint] = Checkpointer(model, # Simulation warm up! ocean.Δt = 10 ocean.stop_iteration = 1 -wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 20, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -stop_time = 1days +stop_time = 10days coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) -run!(coupled_simulation) +try + run!(coupled_simulation) +catch + +end -wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 20minutes, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 15minutes, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations coupled_model.ocean.stop_time = 7200days +coupled_simulation.stop_time = 7200days + +try + run!(coupled_simulation) +catch -run!(coupled_simulation) +end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 02b56db7..d3d47d59 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -136,6 +136,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) ocean = coupled_model.ocean atmosphere = coupled_model.atmosphere atmosphere_grid = atmosphere.grid + sea_ice = coupled_model.sea_ice # Basic model properties grid = ocean.model.grid @@ -180,7 +181,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) # kernel parameters that compute fluxes in 0:Nx+1 and 0:Ny+1 kernel_parameters = KernelParameters(kernel_size, (-1, -1)) - launch!(arch, grid, kernel_parameters, compute_atmosphere_ocean_similarity_theory_fluxes!, + launch!(arch, grid, kernel_parameters, _compute_atmosphere_ocean_similarity_theory_fluxes!, similarity_theory.fields, grid, clock, @@ -195,7 +196,12 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere.thermodynamics_parameters, similarity_theory.roughness_lengths) - launch!(arch, grid, kernel_parameters, assemble_atmosphere_ocean_fluxes!, + limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice, + similarity_theory.fields, + ocean_state.T, + ocean_state.S) + + launch!(arch, grid, kernel_parameters, _assemble_atmosphere_ocean_fluxes!, centered_velocity_fluxes, net_tracer_fluxes, grid, @@ -213,7 +219,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) radiation_properties, coupled_model.fluxes.ocean_reference_density, coupled_model.fluxes.ocean_heat_capacity, - coupled_model.fluxes.freshwater_density) + coupled_model.fluxes.freshwater_density, + sea_ice) launch!(arch, grid, :xy, reconstruct_momentum_fluxes!, grid, staggered_velocity_fluxes, centered_velocity_fluxes) @@ -224,7 +231,10 @@ end const c = Center() const f = Face() -@kernel function compute_atmosphere_ocean_similarity_theory_fluxes!(similarity_theory_fields, +# Fallback! +limit_fluxes_over_sea_ice!(args...) = nothing + +@kernel function _compute_atmosphere_ocean_similarity_theory_fluxes!(similarity_theory_fields, grid, clock, ocean_state, @@ -336,24 +346,24 @@ const f = Face() 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) +@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) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 90629718..ab7c6ca7 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -50,6 +50,7 @@ include("CrossRealmFluxes/CrossRealmFluxes.jl") using .CrossRealmFluxes +include("minimum_temperature_sea_ice.jl") include("ocean_sea_ice_model.jl") include("ocean_only_model.jl") include("time_step_ocean_sea_ice_model.jl") diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl new file mode 100644 index 00000000..5db63bdc --- /dev/null +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -0,0 +1,46 @@ +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: limit_fluxes_over_sea_ice! + +struct MinimumTemperatureSeaIce{T} + minimum_temperature :: T +end + +MinimumTemperatureSeaIce() = MinimumTemperatureSeaIce(-1.8) + +function limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice::MinimumTemperatureSeaIce, + similarity_theory_fields, + ocean_temperature, + ocean_salinity) + + launch!(grid, kernel_parameters, _cap_fluxes_on_sea_ice!, + similarity_theory_fields, + grid, + sea_ice.minimum_temperature, + ocean_temperature) + + return nothing +end + +@kernel function _cap_fluxes_on_sea_ice!(similarity_theory_fields, + grid, + minimum_temperature, + ocean_temperature) + + i, j = @index(Global, NTuple) + fields = similarity_theory_fields + + @inbounds begin + Tₒ = ocean_temperature[i, j, 1] + + Qc = fields.sensible_heat[i, j, 1] # sensible or "conductive" heat flux + Qv = fields.latent_heat[i, j, 1] # latent heat flux + Mv = fields.water_vapor[i, j, 1] # mass flux of water vapor + τx = fields.x_momentum[i, j, 1] # zonal momentum flux + τy = fields.y_momentum[i, j, 1] # meridional momentum flux + + fields.sensible_heat[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), Qc) # sensible or "conductive" heat flux + fields.latent_heat[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), Qv) # latent heat flux + fields.water_vapor[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), Mv) # mass flux of water vapor + fields.x_momentum[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), τx) # zonal momentum flux + fields.y_momentum[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), τy) # meridional momentum flux + end +end diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 6b4a1e9c..9fa3d99b 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -1,10 +1,11 @@ const OceanOnlyModel = OceanSeaIceModel{Nothing} +const OceanCappedSeaIceModel = OceanSeaIceModel{MinimumTemperatureSeaIce} ##### -##### No ice-ocean fluxes in this model!! +##### No ice-ocean fluxes in this models!! ##### -function time_step!(coupled_model::OceanOnlyModel, Δt; callbacks=[], compute_tendencies=true) +function time_step!(coupled_model::Union{OceanOnlyModel, OceanCappedSeaIceModel}, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean # Be paranoid and update state at iteration 0 diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 065fc933..af775fac 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -59,15 +59,15 @@ end function OceanSeaIceModel(ocean, sea_ice=nothing; atmosphere = nothing, radiation = nothing, - reference_density = reference_density(ocean), - heat_capacity = heat_capacity(ocean), + ocean_reference_density = reference_density(ocean), + ocean_heat_capacity = heat_capacity(ocean), clock = deepcopy(ocean.model.clock)) # Contains information about flux contributions: bulk formula, prescribed fluxes, etc. fluxes = OceanSeaIceSurfaceFluxes(ocean, sea_ice; atmosphere, - reference_density, - heat_capacity, + ocean_reference_density, + ocean_heat_capacity, radiation) ocean_sea_ice_model = OceanSeaIceModel(clock, diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index 0f8941e6..d150e8ab 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -39,6 +39,7 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_ # - 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 diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index ee1fcfe9..a32036b0 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -4,6 +4,7 @@ export load_balanced_regional_grid, ocean_simulation using Oceananigans.Units using Oceananigans.Advection: TracerAdvection +using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity, @@ -93,7 +94,7 @@ function ocean_simulation(grid; Δt = 5minutes, tracer_advection = (; T = tracer_advection, S = tracer_advection, e = nothing) end - coriolis = HydrostaticSphericalCoriolis(; rotation_rate) + coriolis = HydrostaticSphericalCoriolis(; rotation_rate, scheme = ActiveCellEnstrophyConserving()) ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, From 9ba6725ff4ef33d69586482833ea41066f0b89d7 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:04:38 -0400 Subject: [PATCH 314/716] try like this --- src/OceanSimulations/load_balanced_regional_grid.jl | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 462560a1..8af2074a 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -123,11 +123,11 @@ function load_balanced_regional_grid(arch::SlabDistributed; # Calculate the load for each i-slab if the partition is in x, # calculate the load for eahc j-slab if the partition is in y. - load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) + load_per_slab = on_architecture(child_arch, zeros(Int, size[idx])) loop! = assess_load!(device(child_arch), 512, size[idx]) loop!(load_per_slab, grid, idx) - load_per_slab = arch_array(CPU(), load_per_slab) + load_per_slab = on_architecture(CPU(), load_per_slab) # Redistribute the load to have the same number of # immersed cells in each core @@ -150,10 +150,6 @@ function load_balanced_regional_grid(arch::SlabDistributed; z, halo) - nx, ny, _ = Base.size(grid) - - bottom_height = partition_global_array(arch, bottom_height, (nx, ny, 1)) - return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) end From 450d3bf78d4c309a767c87daca30a58e6796da15 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:10:18 -0400 Subject: [PATCH 315/716] try this --- .../minimum_temperature_sea_ice.jl | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl index 5db63bdc..23546a68 100644 --- a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -37,10 +37,15 @@ end τx = fields.x_momentum[i, j, 1] # zonal momentum flux τy = fields.y_momentum[i, j, 1] # meridional momentum flux - fields.sensible_heat[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), Qc) # sensible or "conductive" heat flux - fields.latent_heat[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), Qv) # latent heat flux - fields.water_vapor[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), Mv) # mass flux of water vapor - fields.x_momentum[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), τx) # zonal momentum flux - fields.y_momentum[i, j, 1] = ifelse(Tₒ < minimum_temperature, zero(grid), τy) # meridional momentum flux + sea_ice = Tₒ < minimum_temperature + cooling_sea_ice = sea_ice & (Qc > 0) + evaporating_sea_ice = sea_ice & (Qv > 0) + + fields.sensible_heat[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), Qc) # sensible or "conductive" heat flux + fields.latent_heat[i, j, 1] = ifelse(evaporating_sea_ice, zero(grid), Qv) # latent heat flux + + fields.water_vapor[i, j, 1] = ifelse(sea_ice, zero(grid), Mv) # mass flux of water vapor + fields.x_momentum[i, j, 1] = ifelse(sea_ice, zero(grid), τx) # zonal momentum flux + fields.y_momentum[i, j, 1] = ifelse(sea_ice, zero(grid), τy) # meridional momentum flux end end From 2ba3394c72efed2c13303ef478aafc622bbd3912 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:11:06 -0400 Subject: [PATCH 316/716] try it like this --- src/OceanSeaIceModels/minimum_temperature_sea_ice.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl index 23546a68..17a3a343 100644 --- a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -41,9 +41,11 @@ end cooling_sea_ice = sea_ice & (Qc > 0) evaporating_sea_ice = sea_ice & (Qv > 0) + # Don't allow the ocean to cool below the minimum temperature! fields.sensible_heat[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), Qc) # sensible or "conductive" heat flux fields.latent_heat[i, j, 1] = ifelse(evaporating_sea_ice, zero(grid), Qv) # latent heat flux + # If we are in a "sea ice" region we remove all fluxes fields.water_vapor[i, j, 1] = ifelse(sea_ice, zero(grid), Mv) # mass flux of water vapor fields.x_momentum[i, j, 1] = ifelse(sea_ice, zero(grid), τx) # zonal momentum flux fields.y_momentum[i, j, 1] = ifelse(sea_ice, zero(grid), τy) # meridional momentum flux From 233a1e5f34253ced7c8babe961890eafa08e8b74 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:13:14 -0400 Subject: [PATCH 317/716] small bugfix --- .../CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl | 3 +-- src/OceanSeaIceModels/minimum_temperature_sea_ice.jl | 8 ++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index d3d47d59..2b6d8365 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -219,8 +219,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) radiation_properties, coupled_model.fluxes.ocean_reference_density, coupled_model.fluxes.ocean_heat_capacity, - coupled_model.fluxes.freshwater_density, - sea_ice) + coupled_model.fluxes.freshwater_density) launch!(arch, grid, :xy, reconstruct_momentum_fluxes!, grid, staggered_velocity_fluxes, centered_velocity_fluxes) diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl index 17a3a343..b1645388 100644 --- a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -1,5 +1,13 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: limit_fluxes_over_sea_ice! +""" + struct MinimumTemperatureSeaIce{T} + +A struct representing the minimum temperature of sea ice. + +# Fields +- `minimum_temperature`: The minimum temperature of sea ice. +""" struct MinimumTemperatureSeaIce{T} minimum_temperature :: T end From 5d82011b9fd382cac99f2b4d9600303cf5a641db Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:16:27 -0400 Subject: [PATCH 318/716] add docstring --- src/OceanSeaIceModels/minimum_temperature_sea_ice.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl index b1645388..3b050185 100644 --- a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -3,7 +3,8 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: limit_fluxes_over_sea_ice! """ struct MinimumTemperatureSeaIce{T} -A struct representing the minimum temperature of sea ice. +The most simple sea ice model that shuts down cooling and momentum fluxes +when the temperature of the ocean is below minimum_temperature # Fields - `minimum_temperature`: The minimum temperature of sea ice. From 09370fa2a0dcc2de88ba2b0ea84099faeb2bedd7 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:18:07 -0400 Subject: [PATCH 319/716] bugfix --- src/OceanSimulations/load_balanced_regional_grid.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 8af2074a..1b6a1f65 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -1,6 +1,6 @@ using ClimaOcean.Bathymetry using Oceananigans -using Oceananigans.Architectures: arch_array, device, architecture +using Oceananigans.Architectures: arch_array, device, architecture, on_architecture using Oceananigans.DistributedComputations using Oceananigans.DistributedComputations: Sizes, child_architecture, barrier!, all_reduce, partition_global_array using Oceananigans.ImmersedBoundaries: immersed_cell From ee2eb8d2eab521f4e0df4160de19d9468373a9f8 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:19:57 -0400 Subject: [PATCH 320/716] try again --- src/OceanSimulations/load_balanced_regional_grid.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl index 1b6a1f65..73c9ab02 100644 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ b/src/OceanSimulations/load_balanced_regional_grid.jl @@ -1,6 +1,6 @@ using ClimaOcean.Bathymetry using Oceananigans -using Oceananigans.Architectures: arch_array, device, architecture, on_architecture +using Oceananigans.Architectures: arch_array, device, architecture using Oceananigans.DistributedComputations using Oceananigans.DistributedComputations: Sizes, child_architecture, barrier!, all_reduce, partition_global_array using Oceananigans.ImmersedBoundaries: immersed_cell @@ -123,11 +123,11 @@ function load_balanced_regional_grid(arch::SlabDistributed; # Calculate the load for each i-slab if the partition is in x, # calculate the load for eahc j-slab if the partition is in y. - load_per_slab = on_architecture(child_arch, zeros(Int, size[idx])) + load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) loop! = assess_load!(device(child_arch), 512, size[idx]) loop!(load_per_slab, grid, idx) - load_per_slab = on_architecture(CPU(), load_per_slab) + load_per_slab = arch_array(CPU(), load_per_slab) # Redistribute the load to have the same number of # immersed cells in each core From ddeac0853fff2d52cb2c32e80c66cf619ff61e1f Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:47:41 -0400 Subject: [PATCH 321/716] bugfix --- src/OceanSeaIceModels/minimum_temperature_sea_ice.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl index 3b050185..c5e02fdb 100644 --- a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -1,3 +1,5 @@ +using Oceananigans.Architectures: architecture + import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: limit_fluxes_over_sea_ice! """ @@ -20,7 +22,7 @@ function limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice::MinimumTem ocean_temperature, ocean_salinity) - launch!(grid, kernel_parameters, _cap_fluxes_on_sea_ice!, + launch!(architecture(grid), grid, kernel_parameters, _cap_fluxes_on_sea_ice!, similarity_theory_fields, grid, sea_ice.minimum_temperature, From 155c40714e2ba534f9fd755a1028619734f58a0f Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:53:00 -0400 Subject: [PATCH 322/716] bugfix again --- src/OceanSeaIceModels/ocean_only_model.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 9fa3d99b..1bd8f4dd 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -19,3 +19,10 @@ function time_step!(coupled_model::Union{OceanOnlyModel, OceanCappedSeaIceModel} return nothing end +function update_state!(coupled_model::Union{OceanOnlyModel, OceanCappedSeaIceModel}, callbacks=[]; compute_tendencies=false) + time = Time(coupled_model.clock.time) + update_model_field_time_series!(coupled_model.atmosphere, time) + compute_atmosphere_ocean_fluxes!(coupled_model) + return nothing +end + From 2bd5f8bbc8e8b8653a086bc0a64367221e5e67fb Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 19:58:23 -0400 Subject: [PATCH 323/716] cmon!! --- src/OceanSeaIceModels/ocean_only_model.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 1bd8f4dd..c6a4c3bc 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -5,6 +5,11 @@ const OceanCappedSeaIceModel = OceanSeaIceModel{MinimumTemperatureSeaIce} ##### No ice-ocean fluxes in this models!! ##### +import ClimaOcean.OceanCappedSeaIceModels.CrossRealmFluxes: compute_sea_ice_ocean_fluxes! + +compute_sea_ice_ocean_fluxes!(coupled_model::OnlyOceanModel) = nothing +compute_sea_ice_ocean_fluxes!(coupled_model::OceanCappedSeaIceModel) = nothing + function time_step!(coupled_model::Union{OceanOnlyModel, OceanCappedSeaIceModel}, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean From d4c0ea804a5218ba158f184b77693c41dad50d59 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 20:00:35 -0400 Subject: [PATCH 324/716] typo --- src/OceanSeaIceModels/ocean_only_model.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index c6a4c3bc..2bc7acff 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -5,7 +5,7 @@ const OceanCappedSeaIceModel = OceanSeaIceModel{MinimumTemperatureSeaIce} ##### No ice-ocean fluxes in this models!! ##### -import ClimaOcean.OceanCappedSeaIceModels.CrossRealmFluxes: compute_sea_ice_ocean_fluxes! +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: compute_sea_ice_ocean_fluxes! compute_sea_ice_ocean_fluxes!(coupled_model::OnlyOceanModel) = nothing compute_sea_ice_ocean_fluxes!(coupled_model::OceanCappedSeaIceModel) = nothing From 0b27ffe0a7b62ed6cb7b55c945422e945806c141 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 20:03:36 -0400 Subject: [PATCH 325/716] tidying up a bit --- src/ClimaOcean.jl | 54 ---- .../NearGlobalSimulations.jl | 150 ----------- .../one_degree_global_simulation.jl | 244 ------------------ .../quarter_degree_global_simulation.jl | 212 --------------- .../twelth_degree_global_simulation.jl | 210 --------------- src/OceanSeaIceModels/ocean_only_model.jl | 4 +- 6 files changed, 2 insertions(+), 872 deletions(-) delete mode 100644 src/NearGlobalSimulations/NearGlobalSimulations.jl delete mode 100644 src/NearGlobalSimulations/one_degree_global_simulation.jl delete mode 100644 src/NearGlobalSimulations/quarter_degree_global_simulation.jl delete mode 100644 src/NearGlobalSimulations/twelth_degree_global_simulation.jl diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 24b43036..d9741838 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -13,66 +13,12 @@ using Oceananigans using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ using DataDeps -function __init__(; remove_existing_data=false) - - ## Data for the one_degree_global_simulation - branch_url = "https://github.com/CliMA/OceananigansArtifacts.jl/raw/glw/near-global-data" - dir = "lat_lon_bathymetry_and_fluxes" - bathymetry_name = "bathymetry_lat_lon_360_150.jld2" - initial_conditions_month_1 = "initial_conditions_month_01_360_150_48.jld2" - initial_conditions_month_2 = "initial_conditions_month_02_360_150_48.jld2" - surface_boundary_conditions_name = "surface_boundary_conditions_12_months_360_150.jld2" - - bathymetry_url = joinpath(branch_url, dir, bathymetry_name) - initial_conditions_1_url = joinpath(branch_url, dir, initial_conditions_month_1) - initial_conditions_2_url = joinpath(branch_url, dir, initial_conditions_month_2) - surface_boundary_conditions_url = joinpath(branch_url, dir, surface_boundary_conditions_name) - - dep = DataDep("near_global_one_degree", - "Bathymetry, initial conditions, and surface boundary conditions for " * - "near-global one degree simulations", - [bathymetry_url, initial_conditions_1_url, initial_conditions_2_url, surface_boundary_conditions_url]) - - DataDeps.register(dep) - - ## Data for the quarter_degree_global_simulation - path = "https://github.com/CliMA/OceananigansArtifacts.jl/raw/ss/new_hydrostatic_data_after_cleared_bugs/quarter_degree_near_global_input_data/" - - datanames = ["bathymetry-1440x600", - "temp-1440x600-latitude-75", - "salt-1440x600-latitude-75", - "tau_x-1440x600-latitude-75", - "tau_y-1440x600-latitude-75", - "initial_conditions"] - - dh_quarter = DataDep("near_global_quarter_degree", - "Forcing data for global latitude longitude simulation", - [path * data * ".jld2" for data in datanames] - ) - - DataDeps.register(dh_quarter) - - remove_existing_data && rm(datadep"near_global_one_degree", recursive=true, force=true) - remove_existing_data && rm(datadep"near_global_quarter_degree", recursive=true, force=true) -end - -@inline ϕ²(i, j, k, grid, ϕ) = @inbounds ϕ[i, j, k]^2 -@inline spᶠᶜᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.u[i, j, k]^2 + ℑxyᶠᶜᵃ(i, j, k, grid, ϕ², Φ.v)) -@inline spᶜᶠᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.v[i, j, k]^2 + ℑxyᶜᶠᵃ(i, j, k, grid, ϕ², Φ.u)) - -@inline u_bottom_drag(i, j, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, 1] * spᶠᶜᶜ(i, j, 1, grid, Φ) -@inline v_bottom_drag(i, j, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, 1] * spᶜᶠᶜ(i, j, 1, grid, Φ) - -@inline u_immersed_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * spᶠᶜᶜ(i, j, k, grid, Φ) -@inline v_immersed_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) - include("OceanSeaIceModels/OceanSeaIceModels.jl") include("VerticalGrids.jl") include("InitialConditions/InitialConditions.jl") include("DataWrangling/DataWrangling.jl") include("Bathymetry.jl") include("Diagnostics.jl") -include("NearGlobalSimulations/NearGlobalSimulations.jl") include("OceanSimulations/OceanSimulations.jl") using .VerticalGrids diff --git a/src/NearGlobalSimulations/NearGlobalSimulations.jl b/src/NearGlobalSimulations/NearGlobalSimulations.jl deleted file mode 100644 index c5eb276e..00000000 --- a/src/NearGlobalSimulations/NearGlobalSimulations.jl +++ /dev/null @@ -1,150 +0,0 @@ -module NearGlobalSimulations - -using Oceananigans -using Oceananigans.Units - -using Oceananigans.Operators: Δzᵃᵃᶜ, ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ -using Oceananigans.Architectures: arch_array -using Oceananigans.Coriolis: HydrostaticSphericalCoriolis -# using Oceananigans.Coriolis: ActiveCellEnstrophyConservingScheme -using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity, FluxTapering - -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: - CATKEVerticalDiffusivity, MixingLength - -using DataDeps -using Statistics -using JLD2 -using Printf -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState -using CUDA: @allowscalar - -import Oceananigans.Utils: prettysummary - -using ClimaOcean: u_bottom_drag, v_bottom_drag, u_immersed_bottom_drag, v_immersed_bottom_drag - -import ..VerticalGrids - -struct PiecewiseConstantVerticalDiffusivity <: Function - z_transition :: Float64 - top_diffusivity :: Float64 - bottom_diffusivity :: Float64 -end - -@inline function (pcd::PiecewiseConstantVerticalDiffusivity)(x, y, z, t) - zᵗ = pcd.z_transition - κᵗ = pcd.top_diffusivity - κᵇ = pcd.bottom_diffusivity - return ifelse(z > zᵗ, κᵗ, κᵇ) -end - -prettysummary(pcd::PiecewiseConstantVerticalDiffusivity) = - string("PiecewiseConstantVerticalDiffusivity(", - pcd.z_transition, ", ", - pcd.top_diffusivity, ", ", - pcd.bottom_diffusivity, ")") - -Base.summary(pcd::PiecewiseConstantVerticalDiffusivity) = prettysummary(pcd) - -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₁) - -@inline function surface_temperature_relaxation(i, j, grid, clock, fields, p) - time = clock.time - - n₁ = current_time_index(time, p.Nmonths) - n₂ = next_time_index(time, p.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, p.Nmonths) - n₂ = next_time_index(time, p.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 - -@inline function surface_wind_stress(i, j, grid, clock, fields, p) - time = clock.time - n₁ = current_time_index(time, p.Nmonths) - n₂ = next_time_index(time, p.Nmonths) - - @inbounds begin - τ₁ = p.τ[i, j, n₁] - τ₂ = p.τ[i, j, n₂] - end - - return cyclic_interpolate(τ₁, τ₂, time) -end - -using Oceananigans.Operators -using Oceananigans.TurbulenceClosures -using Oceananigans.Operators: Δx, Δy, ℑxyz - -@inline Δ²(i, j, k, grid, lx, ly, lz) = (1 / (1 / Δx(i, j, k, grid, lx, ly, lz)^2 + 1 / Δy(i, j, k, grid, lx, ly, lz)^2)) -@inline grid_dependent_biharmonic_viscosity(i, j, k, grid, lx, ly, lz, clock, fields, τ) = - Δ²(i, j, k, grid, lx, ly, lz)^2 / τ - -@inline function leith_dynamic_biharmonic_viscosity(i, j, k, grid, lx, ly, lz, clock, fields, p) - location = (lx, ly, lz) - from_∂xζ = (Center(), Face(), Center()) - from_∂yζ = (Face(), Center(), Center()) - from_∂xδ = (Face(), Center(), Center()) - from_∂yδ = (Center(), Face(), Center()) - - ∂xζ = ℑxyz(i, j, k, grid, from_∂xζ, location, ∂xᶜᶠᶜ, ζ₃ᶠᶠᶜ, fields.u, fields.v) - ∂yζ = ℑxyz(i, j, k, grid, from_∂yζ, location, ∂yᶠᶜᶜ, ζ₃ᶠᶠᶜ, fields.u, fields.v) - ∂xδ = ℑxyz(i, j, k, grid, from_∂xδ, location, ∂xᶠᶜᶜ, div_xyᶜᶜᶜ, fields.u, fields.v) - ∂yδ = ℑxyz(i, j, k, grid, from_∂yδ, location, ∂yᶜᶠᶜ, div_xyᶜᶜᶜ, fields.u, fields.v) - - dynamic_visc = sqrt( p.Cζ * (∂xζ^2 + ∂yζ^2) + p.Cδ * (∂xδ^2 + ∂yδ^2) ) - - return Δ²(i, j, k, grid, lx, ly, lz)^2.5 * dynamic_visc -end - -geometric_viscosity(formulation, timescale) = ScalarBiharmonicDiffusivity(formulation, ν = grid_dependent_biharmonic_viscosity, - discrete_form = true, - parameters = timescale) - -function leith_viscosity(formulation; C_vort = 3.0, C_div = 3.0) - - Cζ = (C_vort / π)^6 / 8 - Cδ = (C_div / π)^6 / 8 - - return ScalarBiharmonicDiffusivity(formulation, ν = leith_dynamic_biharmonic_viscosity, - discrete_form = true, - parameters = (; Cζ, Cδ)) -end - -include("one_degree_global_simulation.jl") -include("quarter_degree_global_simulation.jl") - -end # module diff --git a/src/NearGlobalSimulations/one_degree_global_simulation.jl b/src/NearGlobalSimulations/one_degree_global_simulation.jl deleted file mode 100644 index 5b2fc580..00000000 --- a/src/NearGlobalSimulations/one_degree_global_simulation.jl +++ /dev/null @@ -1,244 +0,0 @@ - -""" - one_degree_near_global_simulation(architecture = GPU(); kwargs...) - -Return an Oceananigans.Simulation of Earth's ocean at 1 degree resolution. -""" -function one_degree_near_global_simulation(architecture = GPU(); - size = (360, 150, 48), - boundary_layer_turbulence_closure = RiBasedVerticalDiffusivity(), - background_vertical_diffusivity = 1e-5, - horizontal_viscosity = 5e4, - horizontal_tke_diffusivity = 5e4, - surface_background_vertical_viscosity = 1e-2, - interior_background_vertical_viscosity = 1e-4, - vertical_viscosity_transition_depth = 49.0, - with_isopycnal_skew_symmetric_diffusivity = true, - surface_temperature_relaxation_time_scale = 30days, - surface_salinity_relaxation_time_scale = 90days, - isopycnal_κ_skew = 900.0, - isopycnal_κ_symmetric = 900.0, - max_isopycnal_slope = 1e-2, - bottom_drag_coefficient = 3e-3, - reference_density = 1029.0, - reference_heat_capacity = 3991.0, - reference_salinity = 34.0, - time_step = 20minutes, - stop_iteration = Inf, - start_time = 345days, - stop_time = Inf, - tracers = [:T, :S], - initial_conditions = datadep"near_global_one_degree/initial_conditions_month_01_360_150_48.jld2", - bathymetry_path = datadep"near_global_one_degree/bathymetry_lat_lon_360_150.jld2", - surface_boundary_conditions_path = datadep"near_global_one_degree/surface_boundary_conditions_12_months_360_150.jld2", - ) - - size == (360, 150, 48) || throw(ArgumentError("Only size = (360, 150, 48) is supported.")) - - ##### - ##### 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_path) - bathymetry = bathymetry_file["bathymetry"] - close(bathymetry_file) - - @info "Reading initial conditions..."; start=time_ns() - if initial_conditions isa String - initial_conditions_file = jldopen(initial_conditions) - T_init = initial_conditions_file["T"] - S_init = initial_conditions_file["S"] - close(initial_conditions_file) - else - T_init = initial_conditions[:T] - S_init = initial_conditions[:S] - end - @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_path) - τˣ = - 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 - τˣ = 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 - ##### - - νz = PiecewiseConstantVerticalDiffusivity(-vertical_viscosity_transition_depth, - surface_background_vertical_viscosity, - interior_background_vertical_viscosity) - - vitd = VerticallyImplicitTimeDiscretization() - - horizontal_κ = (T=0, S=0, e=horizontal_tke_diffusivity) - horizontal_diffusivity = HorizontalScalarDiffusivity(ν=horizontal_viscosity, κ=horizontal_κ) - vertical_viscosity = VerticalScalarDiffusivity(vitd, ν=νz, κ=background_vertical_diffusivity) - - closures = Any[horizontal_diffusivity, boundary_layer_turbulence_closure, vertical_viscosity] - - boundary_layer_turbulence_closure isa CATKEVerticalDiffusivity && - push!(tracers, :e) - - if with_isopycnal_skew_symmetric_diffusivity - issd = IsopycnalSkewSymmetricDiffusivity(κ_skew = isopycnal_κ_skew, - κ_symmetric = isopycnal_κ_symmetric, - slope_limiter = FluxTapering(max_isopycnal_slope)) - push!(closures, issd) - end - - # 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) - - equation_of_state = TEOS10EquationOfState(; reference_density) - buoyancy = SeawaterBuoyancy(; equation_of_state) - coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConservingScheme()) - free_surface = ImplicitFreeSurface() - - @info "Building a model..."; start=time_ns() - - model = HydrostaticFreeSurfaceModel(; grid, free_surface, buoyancy, coriolis, tracers, - momentum_advection = VectorInvariant(), - tracer_advection = WENO(underlying_grid), - closure = closures, - boundary_conditions = (u=u_bcs, v=v_bcs, T=T_bcs, S=S_bcs)) - - @info "... built $model." - @info "Model building time: " * prettytime(1e-9 * (time_ns() - start)) - - ##### - ##### Initial condition: - ##### - - set!(model, T=T_init, S=S_init) - - # Because MITgcm forcing starts at Jan 15 (?) - model.clock.time = start_time - - simulation = Simulation(model; Δt=time_step, stop_iteration, stop_time) - - start_time = [time_ns()] - - function progress(sim) - wall_time = (time_ns() - start_time[1]) * 1e-9 - - u = sim.model.velocities.u - w = sim.model.velocities.w - - intw = Array(interior(w)) - max_w = findmax(intw) - - mw = max_w[1] - iw = max_w[2] - - msg1 = @sprintf("Time: % 12s, iteration: %d, ", prettytime(sim), iteration(sim)) - msg2 = @sprintf("max(|u|): %.2e ms⁻¹, wmax: %.2e, loc: (%d, %d, %d), ", - maximum(abs, u), mw, iw[1], iw[2], iw[3]) - msg3 = @sprintf("wall time: %s", prettytime(wall_time)) - - @info msg1 * msg2 * msg3 - - start_time[1] = time_ns() - - return nothing - end - - simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - - return simulation -end - diff --git a/src/NearGlobalSimulations/quarter_degree_global_simulation.jl b/src/NearGlobalSimulations/quarter_degree_global_simulation.jl deleted file mode 100644 index 0b9ab672..00000000 --- a/src/NearGlobalSimulations/quarter_degree_global_simulation.jl +++ /dev/null @@ -1,212 +0,0 @@ -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 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★)...) - - @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[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 = ActiveCellEnstrophyConservingScheme()) - free_surface = ImplicitFreeSurface() - - model = HydrostaticFreeSurfaceModel(; grid, free_surface, coriolis, buoyancy, tracers, - momentum_advection = VectorInvariant(vorticity_scheme = WENO(), - divergence_scheme = WENO(), - vertical_scheme = WENO()), - closure = closures, - boundary_conditions = (u=u_bcs, v=v_bcs, T=T_bcs, S=S_bcs), - tracer_advection = WENO(underlying_grid)) - - @info "... built $model." - @info "Model building time: " * prettytime(1e-9 * (time_ns() - start)) - - ##### - ##### Initial condition: - ##### - - set!(model, T=T_init, S=S_init) - - # Because MITgcm forcing starts at Jan 15 (?) - model.clock.time = start_time - - simulation = Simulation(model; Δt=time_step, stop_iteration, stop_time) - - start_time = [time_ns()] - - function progress(sim) - wall_time = (time_ns() - start_time[1]) * 1e-9 - - u = sim.model.velocities.u - w = sim.model.velocities.w - - intw = Array(interior(w)) - max_w = findmax(intw) - - mw = max_w[1] - iw = max_w[2] - - msg1 = @sprintf("Time: % 12s, iteration: %d, ", prettytime(sim), iteration(sim)) - msg2 = @sprintf("max(|u|): %.2e ms⁻¹, wmax: %.2e, loc: (%d, %d, %d), ", - maximum(abs, u), mw, iw[1], iw[2], iw[3]) - msg3 = @sprintf("wall time: %s", prettytime(wall_time)) - - @info msg1 * msg2 * msg3 - - start_time[1] = time_ns() - - return nothing - end - - simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - - return simulation -end diff --git a/src/NearGlobalSimulations/twelth_degree_global_simulation.jl b/src/NearGlobalSimulations/twelth_degree_global_simulation.jl deleted file mode 100644 index b8494163..00000000 --- a/src/NearGlobalSimulations/twelth_degree_global_simulation.jl +++ /dev/null @@ -1,210 +0,0 @@ -using Oceananigans.Utils -using Oceananigans.MultiRegion: reconstruct_global_field, multi_region_object_from_array -using Oceananigans.TurbulenceClosures: HorizontalDivergenceFormulation -using Oceananigans.Advection: VelocityStencil - -""" - twelth_degree_near_global_simulation(architecture = GPU(); kwargs...) - -Return an Oceananigans.Simulation of Earth's ocean at 1/12 degree resolution. -The data for initial conditions, boundary conditions and bathymetry _MUST_ be locally available (momentarily too large for online storage) -""" -function twelth_degree_near_global_simulation(architecture = GPU(); - size = (4320, 1800, 48), - number_of_partions = 4, - boundary_layer_turbulence_closure = RiBasedVerticalDiffusivity(), - background_vertical_diffusivity = 1e-5, - background_vertical_viscosity = 1e-4, - horizontal_viscosity = leith_viscosity(HorizontalDivergenceFormulation(), C_vort = 2.0, C_div = 3.0), - surface_temperature_relaxation_time_scale = 7days, - surface_salinity_relaxation_time_scale = 7days, - bottom_drag_coefficient = 3e-3, - reference_density = 1029.0, - time_step = 2minutes, - stop_iteration = Inf, - start_time = 345days, - stop_time = Inf, - equation_of_state = TEOS10EquationOfState(; reference_density), - tracers = [:T, :S], - initial_conditions = "../data/evolved-initial-conditions-165days.jld2", - bathymetry_path = "../data/bathymetry-ad-hoc.jld2", - boundary_conditions_path = "../data/boundary_conditions_twelth_degree.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(boundary_conditions_path)["τˣ"] ./ reference_density - τʸ = - jldopen(boundary_conditions_path)["τʸ"] ./ reference_density - T★ = jldopen(boundary_conditions_path)["Tₛ"] - S★ = jldopen(boundary_conditions_path)["Sₛ"] - F★ = zeros(Base.size(S★)...) - Q★ = zeros(Base.size(T★)...) - close(boundary_conditions_path) - @info "... read boundary conditions (" * prettytime(1e-9 * (time_ns() - start)) * ")" - - # 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)) - - underlying_mrg = MultiRegionGrid(underlying_grid, partition = XPartition(number_of_partions), devices = number_of_partitions); - mrg = MultiRegionGrid(grid, partition = XPartition(number_of_partions), devices = number_of_partitions); - - @info "Created $grid" - - # Convert boundary conditions arrays to multi GPU - τˣ = multi_region_object_from_array(τˣ, mrg); - τʸ = multi_region_object_from_array(τʸ, mrg); - target_sea_surface_temperature = T★ = multi_region_object_from_array(T★, mrg); - target_sea_surface_salinity = S★ = multi_region_object_from_array(S★, mrg); - surface_temperature_flux = Q★ = multi_region_object_from_array(Q★, mrg); - surface_salt_flux = F★ = multi_region_object_from_array(F★, mrg); - - ##### - ##### 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 = ActiveCellEnstrophyConservingScheme()) - free_surface = ImplicitFreeSurface() - - model = HydrostaticFreeSurfaceModel(; grid = mrg, 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_mrg)) - - @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 = reconstruct_global_field(sim.model.velocities.u) - w = reconstruct_global_field(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)) - - return simulation -end diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 2bc7acff..f60d8041 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -7,8 +7,8 @@ const OceanCappedSeaIceModel = OceanSeaIceModel{MinimumTemperatureSeaIce} import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: compute_sea_ice_ocean_fluxes! -compute_sea_ice_ocean_fluxes!(coupled_model::OnlyOceanModel) = nothing -compute_sea_ice_ocean_fluxes!(coupled_model::OceanCappedSeaIceModel) = nothing +compute_sea_ice_ocean_fluxes!(::OceanOnlyModel) = nothing +compute_sea_ice_ocean_fluxes!(::OceanCappedSeaIceModel) = nothing function time_step!(coupled_model::Union{OceanOnlyModel, OceanCappedSeaIceModel}, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean From de99c18438a9013c8d4639b1110a1b1f27a4f68a Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 20:34:12 -0400 Subject: [PATCH 326/716] bugfix --- src/OceanSeaIceModels/ocean_only_model.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index f60d8041..b5d7fbf8 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -1,5 +1,5 @@ const OceanOnlyModel = OceanSeaIceModel{Nothing} -const OceanCappedSeaIceModel = OceanSeaIceModel{MinimumTemperatureSeaIce} +const OceanSimplifiedSeaIceModel = OceanSeaIceModel{<:MinimumTemperatureSeaIce} ##### ##### No ice-ocean fluxes in this models!! @@ -10,7 +10,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: compute_sea_ice_ocean_flux compute_sea_ice_ocean_fluxes!(::OceanOnlyModel) = nothing compute_sea_ice_ocean_fluxes!(::OceanCappedSeaIceModel) = nothing -function time_step!(coupled_model::Union{OceanOnlyModel, OceanCappedSeaIceModel}, Δt; callbacks=[], compute_tendencies=true) +function time_step!(coupled_model::Union{OceanOnlyModel, OceanSimplifiedSeaIceModel}, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean # Be paranoid and update state at iteration 0 @@ -24,7 +24,7 @@ function time_step!(coupled_model::Union{OceanOnlyModel, OceanCappedSeaIceModel} return nothing end -function update_state!(coupled_model::Union{OceanOnlyModel, OceanCappedSeaIceModel}, callbacks=[]; compute_tendencies=false) +function update_state!(coupled_model::Union{OceanOnlyModel, OceanSimplifiedSeaIceModel}, callbacks=[]; compute_tendencies=false) time = Time(coupled_model.clock.time) update_model_field_time_series!(coupled_model.atmosphere, time) compute_atmosphere_ocean_fluxes!(coupled_model) From 3525cc13e1ca818eeb0e5f293c02b74a779e15cb Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 20:38:54 -0400 Subject: [PATCH 327/716] another typo --- src/OceanSeaIceModels/ocean_only_model.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index b5d7fbf8..635b0bb1 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -8,7 +8,7 @@ const OceanSimplifiedSeaIceModel = OceanSeaIceModel{<:MinimumTemperatureSeaIce} import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: compute_sea_ice_ocean_fluxes! compute_sea_ice_ocean_fluxes!(::OceanOnlyModel) = nothing -compute_sea_ice_ocean_fluxes!(::OceanCappedSeaIceModel) = nothing +compute_sea_ice_ocean_fluxes!(::OceanSimplifiedSeaIceModel) = nothing function time_step!(coupled_model::Union{OceanOnlyModel, OceanSimplifiedSeaIceModel}, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean From 653699776b3546bf9ee0e1b9c3996db22898dcb3 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 20:56:03 -0400 Subject: [PATCH 328/716] limit _all_ the fluxes (also radiative ones) --- .../ocean_sea_ice_surface_fluxes.jl | 11 ++--- .../minimum_temperature_sea_ice.jl | 45 ++++++++++--------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 2b6d8365..0c79af6a 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -195,11 +195,6 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere.reference_height, # height at which the state is known atmosphere.thermodynamics_parameters, similarity_theory.roughness_lengths) - - limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice, - similarity_theory.fields, - ocean_state.T, - ocean_state.S) launch!(arch, grid, kernel_parameters, _assemble_atmosphere_ocean_fluxes!, centered_velocity_fluxes, @@ -221,6 +216,12 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) coupled_model.fluxes.ocean_heat_capacity, coupled_model.fluxes.freshwater_density) + limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice, + centered_velocity_fluxes, + net_tracer_fluxes, + ocean_state.T, + ocean_state.S) + launch!(arch, grid, :xy, reconstruct_momentum_fluxes!, grid, staggered_velocity_fluxes, centered_velocity_fluxes) diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl index c5e02fdb..c43efa8b 100644 --- a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -5,11 +5,13 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: limit_fluxes_over_sea_ice! """ struct MinimumTemperatureSeaIce{T} -The most simple sea ice model that shuts down cooling and momentum fluxes -when the temperature of the ocean is below minimum_temperature +Despite the name, this is not really a sea ice model! +However, it is the most simple way to make sure that temperature does not dip below +freezing temperature, by shutting down cooling temperature fluxes (and momentum fluxes) +when the temperature of the surface is below a `minimum_temperature` # Fields -- `minimum_temperature`: The minimum temperature of sea ice. +- `minimum_temperature`: The minimum temperature of water. """ struct MinimumTemperatureSeaIce{T} minimum_temperature :: T @@ -18,12 +20,14 @@ end MinimumTemperatureSeaIce() = MinimumTemperatureSeaIce(-1.8) function limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice::MinimumTemperatureSeaIce, - similarity_theory_fields, + centered_velocity_fluxes, + net_tracer_fluxes, ocean_temperature, ocean_salinity) launch!(architecture(grid), grid, kernel_parameters, _cap_fluxes_on_sea_ice!, - similarity_theory_fields, + centered_velocity_fluxes, + net_tracer_fluxes, grid, sea_ice.minimum_temperature, ocean_temperature) @@ -31,34 +35,31 @@ function limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice::MinimumTem return nothing end -@kernel function _cap_fluxes_on_sea_ice!(similarity_theory_fields, +@kernel function _cap_fluxes_on_sea_ice!(centered_velocity_fluxes, + net_tracer_fluxes, grid, minimum_temperature, ocean_temperature) i, j = @index(Global, NTuple) - fields = similarity_theory_fields @inbounds begin Tₒ = ocean_temperature[i, j, 1] - Qc = fields.sensible_heat[i, j, 1] # sensible or "conductive" heat flux - Qv = fields.latent_heat[i, j, 1] # latent heat flux - Mv = fields.water_vapor[i, j, 1] # mass flux of water vapor - τx = fields.x_momentum[i, j, 1] # zonal momentum flux - τy = fields.y_momentum[i, j, 1] # meridional momentum flux - + Jᵘ = centered_velocity_fluxes.u + Jᵛ = centered_velocity_fluxes.v + Jᵀ = net_tracer_fluxes.T + Jˢ = net_tracer_fluxes.S + sea_ice = Tₒ < minimum_temperature - cooling_sea_ice = sea_ice & (Qc > 0) - evaporating_sea_ice = sea_ice & (Qv > 0) - - # Don't allow the ocean to cool below the minimum temperature! - fields.sensible_heat[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), Qc) # sensible or "conductive" heat flux - fields.latent_heat[i, j, 1] = ifelse(evaporating_sea_ice, zero(grid), Qv) # latent heat flux + cooling_sea_ice = sea_ice & (Jᵀ[i, j, 1] > 0) + # Don't allow the ocean to cool below the minimum temperature! (make sure it heats up though!) + Jᵀ[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), Jᵀ[i, j, 1]) + # If we are in a "sea ice" region we remove all fluxes - fields.water_vapor[i, j, 1] = ifelse(sea_ice, zero(grid), Mv) # mass flux of water vapor - fields.x_momentum[i, j, 1] = ifelse(sea_ice, zero(grid), τx) # zonal momentum flux - fields.y_momentum[i, j, 1] = ifelse(sea_ice, zero(grid), τy) # meridional momentum flux + Jˢ[i, j, 1] = ifelse(sea_ice, zero(grid), Jˢ[i, j, 1]) + Jᵘ[i, j, 1] = ifelse(sea_ice, zero(grid), Jᵘ[i, j, 1]) + Jᵛ[i, j, 1] = ifelse(sea_ice, zero(grid), Jᵛ[i, j, 1]) end end From 3d445ad52b537ef2bf2aa9090a1aa1edb2a11621 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 16 Apr 2024 21:02:33 -0400 Subject: [PATCH 329/716] better explanation --- src/OceanSeaIceModels/minimum_temperature_sea_ice.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl index c43efa8b..3a3c8894 100644 --- a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -5,10 +5,10 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: limit_fluxes_over_sea_ice! """ struct MinimumTemperatureSeaIce{T} -Despite the name, this is not really a sea ice model! -However, it is the most simple way to make sure that temperature does not dip below -freezing temperature, by shutting down cooling temperature fluxes (and momentum fluxes) -when the temperature of the surface is below a `minimum_temperature` +The minimal possible sea ice representation, providing an "Insulating layer" on the surface. +Not really a ``model'' per se, however, it is the most simple way to make sure that temperature +does not dip below freezing temperature. +All fluxes are shut down when the surface is below the `minimum_temperature` except for heating. # Fields - `minimum_temperature`: The minimum temperature of water. From 74dff24e4de1a3202c838392040d87af21f04581 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 18 Apr 2024 09:06:02 -0400 Subject: [PATCH 330/716] working now --- .../ocean_sea_ice_surface_fluxes.jl | 9 ++++-- .../similarity_theory_turbulent_fluxes.jl | 28 +++++++------------ 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 0c79af6a..75a8a283 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -327,6 +327,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing g = default_gravitational_acceleration ϰ = 0.4 + turbulent_fluxes = compute_similarity_theory_fluxes(roughness_lengths, dynamic_ocean_state, dynamic_atmos_state, @@ -435,14 +436,16 @@ end i, j = @index(Global, NTuple) @inbounds begin - J.u[i, j, 1] = ℑxᶠᶜᶜ(i, j, 1, grid, Jᶜᶜᶜ.u) - J.v[i, j, 1] = ℑyᶜᶠᶜ(i, j, 1, grid, Jᶜᶜᶜ.v) + J.u[i, j, 1] = ℑxᶠᶜᶜ(i, j, 1, grid, Jᶜᶜᶜ.u) + J.v[i, j, 1] = ℑyᶜᶠᶜ(i, j, 1, grid, Jᶜᶜᶜ.v) end end @inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) α = stateindex(radiation.reflection.ocean, i, j, 1, time) - return @inbounds - (1 - α) * Qs - Qℓ + ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) + + return @inbounds - (1 - α) * Qs - ϵ * Qℓ end @inline function net_upwelling_radiation(i, j, grid, time, radiation, Tₒ) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 22fdb287..7873d20f 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -92,6 +92,13 @@ function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) end +function default_roughness_lengths(FT=Float64) + momentum = 1e-4 #GravityWaveRoughnessLength(FT) + temperature = convert(FT, 1e-4) + water_vapor = nothing + return SimilarityScales(momentum, temperature, water_vapor) +end + const PATP = PrescribedAtmosphereThermodynamicsParameters function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; @@ -207,16 +214,12 @@ end return (1 - s) / (1 - s + α * s) end - @inline update_turbulent_flux_fields!(::Nothing, args...) = nothing @inline function update_turbulent_flux_fields!(fields, i, j, grid, fluxes) return nothing end -@inline compute_similarity_theory_fluxes(turbulent_fluxes, atmos_state, surface_state) = - compute_similarity_theory_fluxes(turbulent_fluxes.roughness_lengths, turbulent_fluxes, atmos_state, surface_state) - ##### ##### Struct that represents a 3-tuple of momentum, heat, and water vapor ##### @@ -242,11 +245,8 @@ const NothingVaporRoughnessLength = SimilarityScales{<:Number, <:Number, Nothing atmos_state, thermodynamics_parameters, gravitational_acceleration, - von_karman_constant) - - # turbulent_fluxes, - # atmos_state, - # surface_state) + von_karman_constant, + turbulent_fluxes) FT = Float64 similarity_functions = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), @@ -422,6 +422,7 @@ end cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) + fluxes = (; water_vapor = - ρₐ * u★ * q★, sensible_heat = - ρₐ * cₚ * u★ * θ★, @@ -518,12 +519,3 @@ end return α * u★^2 / g + β * ν / u★ end - -function default_roughness_lengths(FT=Float64) - momentum = 1e-4 #GravityWaveRoughnessLength(FT) - temperature = convert(FT, 1e-4) - water_vapor = convert(FT, 1e-4) - return SimilarityScales(momentum, temperature, water_vapor) -end - - From 9a039963d0f51b04fe016a3518bf3df8b4e18df0 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 18 Apr 2024 09:44:04 -0400 Subject: [PATCH 331/716] remove duplicate definition --- src/OceanSeaIceModels/OceanSeaIceModels.jl | 2 -- src/OceanSeaIceModels/ocean_only_model.jl | 9 +++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index ab7c6ca7..b7ff23ea 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -61,10 +61,8 @@ import .CrossRealmFluxes: # "No atmosphere" implementation const NoAtmosphereModel = OceanSeaIceModel{<:Any, Nothing} -const NoSeaIceModel = OceanSeaIceModel{Nothing} compute_atmosphere_ocean_fluxes!(coupled_model::NoAtmosphereModel) = nothing -compute_sea_ice_ocean_fluxes!(coupled_model::NoSeaIceModel) = nothing ##### ##### A fairly dumb, but nevertheless effective "sea ice model" diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 635b0bb1..7d290a3f 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -1,16 +1,17 @@ const OceanOnlyModel = OceanSeaIceModel{Nothing} const OceanSimplifiedSeaIceModel = OceanSeaIceModel{<:MinimumTemperatureSeaIce} +const NoSeaIceModel = Union{OceanOnlyModel, OceanSimplifiedSeaIceModel} + ##### ##### No ice-ocean fluxes in this models!! ##### import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: compute_sea_ice_ocean_fluxes! -compute_sea_ice_ocean_fluxes!(::OceanOnlyModel) = nothing -compute_sea_ice_ocean_fluxes!(::OceanSimplifiedSeaIceModel) = nothing +compute_sea_ice_ocean_fluxes!(::NoSeaIceModel) = nothing -function time_step!(coupled_model::Union{OceanOnlyModel, OceanSimplifiedSeaIceModel}, Δt; callbacks=[], compute_tendencies=true) +function time_step!(coupled_model::NoSeaIceModel, Δt; callbacks=[], compute_tendencies=true) ocean = coupled_model.ocean # Be paranoid and update state at iteration 0 @@ -24,7 +25,7 @@ function time_step!(coupled_model::Union{OceanOnlyModel, OceanSimplifiedSeaIceMo return nothing end -function update_state!(coupled_model::Union{OceanOnlyModel, OceanSimplifiedSeaIceModel}, callbacks=[]; compute_tendencies=false) +function update_state!(coupled_model::NoSeaIceModel, callbacks=[]; compute_tendencies=false) time = Time(coupled_model.clock.time) update_model_field_time_series!(coupled_model.atmosphere, time) compute_atmosphere_ocean_fluxes!(coupled_model) From fcaaba03267638605b837e6a05343e36ef31d62f Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 18 Apr 2024 20:26:45 -0400 Subject: [PATCH 332/716] more changes --- experiments/twelth_degree_latlong.jl | 18 ++++++++++-------- .../similarity_theory_turbulent_fluxes.jl | 1 - src/OceanSimulations/OceanSimulations.jl | 8 ++++---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index 9a17d82c..dc16594d 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -15,7 +15,7 @@ using Printf using CUDA using CairoMakie using SixelTerm -# CUDA.device!(2) +CUDA.device!(1) include("correct_oceananigans.jl") @@ -52,7 +52,7 @@ grid = load_balanced_regional_grid(arch; ##### free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt = 20minutes) -vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = 5e-4) +vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = 5e-3) closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) @@ -60,9 +60,7 @@ ocean = ocean_simulation(grid; free_surface, closure) model = ocean.model # Initializing the model -set!(model, - T = ECCO2Metadata(:temperature), - S = ECCO2Metadata(:salinity)) +set!(model, "checkpoint_iteration497897.jld2") ##### ##### The atmosphere @@ -82,19 +80,21 @@ function progress(sim) u, v, w = sim.model.velocities T, S = sim.model.tracers + Tmax = maximum(abs, T) + Tmin = minimum(T) + umax = maximum(abs, u), maximum(abs, v), maximum(abs, w) step_time = 1e-9 * (time_ns() - wall_time[1]) @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", prettytime(sim.model.clock.time), sim.model.clock.iteration, prettytime(sim.Δt), - maximum(abs, u), maximum(abs, v), maximum(abs, w), - maximum(abs, T), maximum(abs, S), prettytime(step_time)) + umax..., Tmax, Tmin, prettytime(step_time)) wall_time[1] = time_ns() end -ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) +ocean.callbacks[:progress] = Callback(progress, IterationInterval(100)) ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), schedule = TimeInterval(30days), @@ -129,6 +129,8 @@ ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations coupled_model.ocean.stop_time = 7200days coupled_simulation.stop_time = 7200days +coupled_model.ocean.stop_iteration = Inf +coupled_simulation.stop_iteration = Inf try run!(coupled_simulation) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 7873d20f..5076ff77 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -354,7 +354,6 @@ end return b★ end - @inline function state_differences(ℂ, 𝒰₁, 𝒰₀) z₁ = 𝒰₁.z z₀ = 𝒰₀.z diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index a32036b0..2e15f4ad 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -72,10 +72,10 @@ function ocean_simulation(grid; Δt = 5minutes, u_immersed_bc = ImmersedBoundaryCondition(bottom=u_immersed_drag) v_immersed_bc = ImmersedBoundaryCondition(bottom=v_immersed_drag) - ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵘ), bottom = u_bottom_drag, immersed = u_immersed_bc), - v = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵛ), bottom = v_bottom_drag, immersed = v_immersed_bc), - T = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵀ)), - S = FieldBoundaryConditions(top=FluxBoundaryCondition(Jˢ))) + ocean_boundary_conditions = (u = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵘ), bottom = u_bottom_drag, immersed = u_immersed_bc), + v = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵛ), bottom = v_bottom_drag, immersed = v_immersed_bc), + T = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵀ)), + S = FieldBoundaryConditions(top = FluxBoundaryCondition(Jˢ))) # Use the TEOS10 equation of state teos10 = TEOS10EquationOfState(; reference_density) From fa8d4713dbe087fde05f54a66093d83470ed61a6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:34:25 -0400 Subject: [PATCH 333/716] omip branch --- quarter_degree_omip/Manifest.toml | 1793 +++++++++++++++++ quarter_degree_omip/Project.toml | 7 + .../correct_oceananigans.jl | 0 quarter_degree_omip/quarter_degree_omip.jl | 44 + 4 files changed, 1844 insertions(+) create mode 100644 quarter_degree_omip/Manifest.toml create mode 100644 quarter_degree_omip/Project.toml rename {experiments => quarter_degree_omip}/correct_oceananigans.jl (100%) create mode 100644 quarter_degree_omip/quarter_degree_omip.jl diff --git a/quarter_degree_omip/Manifest.toml b/quarter_degree_omip/Manifest.toml new file mode 100644 index 00000000..d3d73885 --- /dev/null +++ b/quarter_degree_omip/Manifest.toml @@ -0,0 +1,1793 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.2" +manifest_format = "2.0" +project_hash = "d412c6cb49202ad61a9e28c0d7d4a3658d51067c" + +[[deps.ANSIColoredPrinters]] +git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" +uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" +version = "0.0.1" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] +git-tree-sha1 = "c0d491ef0b135fd7d63cbc6404286bc633329425" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.36" + + [deps.Accessors.extensions] + AccessorsAxisKeysExt = "AxisKeys" + AccessorsIntervalSetsExt = "IntervalSets" + AccessorsStaticArraysExt = "StaticArrays" + AccessorsStructArraysExt = "StructArrays" + AccessorsUnitfulExt = "Unitful" + + [deps.Accessors.weakdeps] + AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.0.4" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "133a240faec6e074e07c31ee75619c90544179cf" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.10.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = "CUDSS" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random", "Test"] +git-tree-sha1 = "2c7cc21e8678eff479978a0a2ef5ce2f51b63dff" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.BitTwiddlingConvenienceFunctions]] +deps = ["Static"] +git-tree-sha1 = "0c5f81f47bbbcf4aea7b2959135713459170798b" +uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" +version = "0.1.5" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.5+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.3" + +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] +git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.4" + +[[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 = "dd1c682b372b6791b69f6823afe364fc92a0146c" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.3.1" +weakdeps = ["ChainRulesCore", "SpecialFunctions"] + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "dc172b558adbf17952001e15cf0d6364e6d78c2f" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.8.1+0" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "38f830504358e9972d2a0c3e5d51cb865e0733df" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.2.4" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "4ca7d6d92075906c2ce871ea8bba971fff20d00c" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.12.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.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", "FFMPEG", "ImageMorphology", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +git-tree-sha1 = "a28b7f70177dab671632e2c26ecc462fa8ea4fa9" +repo-rev = "ss/omip-simulation" +repo-url = ".." +uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +version = "0.1.0" + +[[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" + +[[deps.CloseOpenIntervals]] +deps = ["Static", "StaticArrayInterface"] +git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" +uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" +version = "0.1.12" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.5" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "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.CpuId]] +deps = ["Markdown"] +git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" +uuid = "adafc99b-e345-5852-983c-f28acb93d879" +version = "0.3.1" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] +git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.2.5" + +[[deps.CubicSplines]] +deps = ["Random", "Test"] +git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" +uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" +version = "0.2.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.20" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DiskArrays]] +deps = ["LRUCache", "OffsetArrays"] +git-tree-sha1 = "ef25c513cad08d7ebbed158c91768ae32f308336" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.3.23" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.8.6" + +[[deps.Documenter]] +deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] +git-tree-sha1 = "f15a91e6e3919055efa4f206f942a73fedf5dfe6" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "1.4.0" + +[[deps.DocumenterTools]] +deps = ["Base64", "DocStringExtensions", "LibGit2"] +git-tree-sha1 = "58db9d1c626de92318ee35cbaf466739f4b5a09a" +uuid = "35a29f4d-8980-5a13-9543-d66fff28ecb8" +version = "0.1.2" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.Elliptic]] +git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" +uuid = "b305315f-e792-5b7a-8f41-49f472929428" +version = "1.0.1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "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.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.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 = "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.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.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.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.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 = "68e8ff56a4a355a85d2784b94614491f8c900cde" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "10.1.0" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "1600477fba37c9fc067b9be21f5e8101f24a8865" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.26.4" + +[[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.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+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.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.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] +git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.16" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.10.0+0" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "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.ImageCore]] +deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "b2a7eaa169c13f5bcae8131a83bc30eff8f71be0" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.2" + +[[deps.ImageMorphology]] +deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] +git-tree-sha1 = "6f0a801136cb9c229aebea0df296cdcd471dbcd1" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.4.5" + +[[deps.IncompleteLU]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" +uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" +version = "0.2.1" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "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.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.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.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.LayoutPointers]] +deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "62edfee3211981241b57ff1cedf4d74d79519277" +uuid = "10f19ff3-798f-405d-979b-55457f8fc047" +version = "0.1.15" + +[[deps.LazilyInitializedFields]] +git-tree-sha1 = "8f7f3cabab0fd1800699663533b6d5cb3fc0e612" +uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf" +version = "1.2.2" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.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.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.LoopVectorization]] +deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] +git-tree-sha1 = "a13f3be5d84b9c95465d743c82af0b094ef9c2e2" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.169" +weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.9.4+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +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.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MarkdownAST]] +deps = ["AbstractTrees", "Markdown"] +git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" +uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" +version = "0.1.2" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f12a29c4400ba812841c6ace3f4efbb6dbb3ba01" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "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 = "aa709412dbde10fe375e4b729fc903166e7669bd" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.90.12" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "e64b4f5ea6b7389f6f046d13d4896a8f9c1ba71e" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.14.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.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.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.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.OrthogonalSphericalShellGrids]] +deps = ["Documenter", "DocumenterTools", "JLD2", "KernelAbstractions", "Oceananigans", "OffsetArrays"] +git-tree-sha1 = "2a6ca475836fcd46d986e34bf490da394a44bfb9" +repo-rev = "main" +repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl" +uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" +version = "0.1.0" + +[[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.PMIx_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] +git-tree-sha1 = "360f48126b5f2c2f0c833be960097f7c62705976" +uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" +version = "4.2.9+0" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.PencilArrays]] +deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] +git-tree-sha1 = "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.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.PolyesterWeave]] +deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] +git-tree-sha1 = "240d7170f5ffdb285f9427b92333c3463bf65bf6" +uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" +version = "0.2.1" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "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.RegistryInstances]] +deps = ["LazilyInitializedFields", "Pkg", "TOML", "Tar"] +git-tree-sha1 = "ffd19052caf598b8653b99404058fce14828be51" +uuid = "2792f1a3-b283-48e8-9a74-f99dce5104f3" +version = "0.1.0" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.RootSolvers]] +deps = ["ForwardDiff"] +git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.2" + +[[deps.Roots]] +deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] +git-tree-sha1 = "1ab580704784260ee5f45bffac810b152922747b" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.1.5" + + [deps.Roots.extensions] + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + + [deps.Roots.weakdeps] + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" + SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" + SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "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.SIMDTypes]] +git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" +uuid = "94e857df-77ce-4151-89e5-788b33177be4" +version = "0.1.0" + +[[deps.SLEEFPirates]] +deps = ["IfElse", "Static", "VectorizationBase"] +git-tree-sha1 = "3aac6d68c5e57449f5b9b865c9ba50ac2970c4cf" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.42" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.4" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "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.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.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.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 = "48098ebfee40374b8415b602163e02aa7c43d32b" +repo-rev = "glw/density-example" +repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.5" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.ThreadingUtilities]] +deps = ["ManualMemory"] +git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" +uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" +version = "0.5.2" + +[[deps.TiledIteration]] +deps = ["OffsetArrays", "StaticArrayInterface"] +git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" +uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" +version = "0.5.0" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "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.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.2.1" + +[[deps.UnsafeAtomicsLLVM]] +deps = ["LLVM", "UnsafeAtomics"] +git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.3" + +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "ac377f0a248753a1b1d58bbc92a64f5a726dfb71" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.66" + +[[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.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.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.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/quarter_degree_omip/Project.toml b/quarter_degree_omip/Project.toml new file mode 100644 index 00000000..9cabfad5 --- /dev/null +++ b/quarter_degree_omip/Project.toml @@ -0,0 +1,7 @@ +[deps] +ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +OrthogonalSphericalShellGrids = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" +SurfaceFluxes = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" diff --git a/experiments/correct_oceananigans.jl b/quarter_degree_omip/correct_oceananigans.jl similarity index 100% rename from experiments/correct_oceananigans.jl rename to quarter_degree_omip/correct_oceananigans.jl diff --git a/quarter_degree_omip/quarter_degree_omip.jl b/quarter_degree_omip/quarter_degree_omip.jl new file mode 100644 index 00000000..465544f6 --- /dev/null +++ b/quarter_degree_omip/quarter_degree_omip.jl @@ -0,0 +1,44 @@ +using Printf +using Oceananigans +using Oceananigans.Units +using ClimaOcean +using OrthogonalSphericalShellGrids +using Oceananigans +using Oceananigans: architecture +using ClimaOcean +using ClimaOcean.ECCO2 +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity +using Oceananigans.Coriolis: ActiveCellEnstrophyConserving +using Oceananigans.Units +using ClimaOcean.OceanSimulations +using ClimaOcean.OceanSeaIceModels +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation +using ClimaOcean.VerticalGrids: exponential_z_faces +using ClimaOcean.JRA55 +using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere + +include("correct_oceananigans.jl") + +##### +##### Global Ocean at 1/12th of a degree +##### + +bathymetry_file = nothing # "bathymetry_tmp.jld2" + +# 100 vertical levels +z_faces = exponential_z_faces(Nz=60, depth=6500) + +Nx = 720 +Ny = 300 +Nz = length(z_faces) - 1 + +arch = CPU() #Distributed(GPU(), partition = Partition(2)) + +underlying_grid = TripolarGrid(arch; size = (Nx, Ny, Nz), halo = (7, 7, 7)) + +bottom_height = retrieve_bathymetry(grid, bathymetry_file; + minimum_depth = 10, + interpolation_passes = 20, + connected_regions_allowed = 3) + +grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height); active_cells_map = true) \ No newline at end of file From e49973b6c62b39e5104cf7c419d2300e37c4694b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 19 Apr 2024 15:14:49 -0400 Subject: [PATCH 334/716] let's go --- quarter_degree_omip/Manifest.toml | 4 +-- quarter_degree_omip/quarter_degree_omip.jl | 29 ++++++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/quarter_degree_omip/Manifest.toml b/quarter_degree_omip/Manifest.toml index d3d73885..2fbcff9b 100644 --- a/quarter_degree_omip/Manifest.toml +++ b/quarter_degree_omip/Manifest.toml @@ -1114,8 +1114,8 @@ uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.6.3" [[deps.OrthogonalSphericalShellGrids]] -deps = ["Documenter", "DocumenterTools", "JLD2", "KernelAbstractions", "Oceananigans", "OffsetArrays"] -git-tree-sha1 = "2a6ca475836fcd46d986e34bf490da394a44bfb9" +deps = ["CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays"] +git-tree-sha1 = "60438101099daae28a1bba9135ac0b56d7493243" repo-rev = "main" repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl" uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" diff --git a/quarter_degree_omip/quarter_degree_omip.jl b/quarter_degree_omip/quarter_degree_omip.jl index 465544f6..2d3256ce 100644 --- a/quarter_degree_omip/quarter_degree_omip.jl +++ b/quarter_degree_omip/quarter_degree_omip.jl @@ -16,16 +16,17 @@ using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere +using ClimaOcean.Bathymetry include("correct_oceananigans.jl") ##### -##### Global Ocean at 1/12th of a degree +##### Global Ocean at 1/4th of a degree ##### bathymetry_file = nothing # "bathymetry_tmp.jld2" -# 100 vertical levels +# 60 vertical levels z_faces = exponential_z_faces(Nz=60, depth=6500) Nx = 720 @@ -34,11 +35,29 @@ Nz = length(z_faces) - 1 arch = CPU() #Distributed(GPU(), partition = Partition(2)) -underlying_grid = TripolarGrid(arch; size = (Nx, Ny, Nz), halo = (7, 7, 7)) +grid = TripolarGrid(arch; size = (Nx, Ny, Nz), halo = (7, 7, 7), z = z_faces) bottom_height = retrieve_bathymetry(grid, bathymetry_file; minimum_depth = 10, interpolation_passes = 20, - connected_regions_allowed = 3) + connected_regions_allowed = 1) -grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height); active_cells_map = true) \ No newline at end of file +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) + +##### +##### The Ocean component +##### + +const Lz = grid.Lz +const h = Nz / 4.5 + +@inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) +@inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) + +free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt = 20minutes) +vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = 5e-3) + +closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) + +ocean = ocean_simulation(grid; free_surface, closure) +model = ocean.model \ No newline at end of file From f816fbd7a29462aacbca58875535c2e39c832672 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 19 Apr 2024 15:31:55 -0400 Subject: [PATCH 335/716] progress --- quarter_degree_omip/Manifest.toml | 2 +- src/OceanSimulations/OceanSimulations.jl | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/quarter_degree_omip/Manifest.toml b/quarter_degree_omip/Manifest.toml index 2fbcff9b..92c11f06 100644 --- a/quarter_degree_omip/Manifest.toml +++ b/quarter_degree_omip/Manifest.toml @@ -1115,7 +1115,7 @@ version = "1.6.3" [[deps.OrthogonalSphericalShellGrids]] deps = ["CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays"] -git-tree-sha1 = "60438101099daae28a1bba9135ac0b56d7493243" +git-tree-sha1 = "ec6d87313f42d0c17e63f2dfd91b482f430ac57f" repo-rev = "main" repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl" uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 2e15f4ad..eb0229e4 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -46,6 +46,12 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), @inline u_immersed_drag_bc(i, j, k, grid, clock, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * speedᶠᶜᶜ(i, j, k, grid, Φ) @inline v_immersed_drag_bc(i, j, k, grid, clock, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * speedᶜᶠᶜ(i, j, k, grid, Φ) +default_boundary_conditions(grid; Jᵘ, Jᵛ, Jᵀ, Jˢ, u_bottom_drag, v_bottom_drag, u_immersed_bc, v_immersed_bc) = + (u = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵘ), bottom = u_bottom_drag, immersed = u_immersed_bc), + v = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵛ), bottom = v_bottom_drag, immersed = v_immersed_bc), + T = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵀ)), + S = FieldBoundaryConditions(top = FluxBoundaryCondition(Jˢ))) + # 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; Δt = 5minutes, @@ -72,10 +78,11 @@ function ocean_simulation(grid; Δt = 5minutes, u_immersed_bc = ImmersedBoundaryCondition(bottom=u_immersed_drag) v_immersed_bc = ImmersedBoundaryCondition(bottom=v_immersed_drag) - ocean_boundary_conditions = (u = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵘ), bottom = u_bottom_drag, immersed = u_immersed_bc), - v = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵛ), bottom = v_bottom_drag, immersed = v_immersed_bc), - T = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵀ)), - S = FieldBoundaryConditions(top = FluxBoundaryCondition(Jˢ))) + ocean_boundary_conditions = default_boundary_conditions(grid; Jᵘ, Jᵛ, Jᵀ, Jˢ, + u_bottom_drag, + v_bottom_drag, + u_immersed_bc, + v_immersed_bc) # Use the TEOS10 equation of state teos10 = TEOS10EquationOfState(; reference_density) From 0ff1516d5f583d367f07819d9cfc5cb751abb6d6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 20 Apr 2024 16:55:43 -0400 Subject: [PATCH 336/716] we're ready to go! --- experiments/twelth_degree_latlong.jl | 10 ++- quarter_degree_omip/Manifest.toml | 18 ++---- quarter_degree_omip/Project.toml | 1 + quarter_degree_omip/correct_oceananigans.jl | 62 ------------------- quarter_degree_omip/quarter_degree_omip.jl | 45 ++++++++++++-- .../three_dimensional_interpolate_tripolar.jl | 59 ++++++++++++++++++ src/DataWrangling/JRA55.jl | 38 +++++------- .../ocean_sea_ice_surface_fluxes.jl | 46 ++++---------- 8 files changed, 143 insertions(+), 136 deletions(-) delete mode 100644 quarter_degree_omip/correct_oceananigans.jl create mode 100644 quarter_degree_omip/three_dimensional_interpolate_tripolar.jl diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index dc16594d..b71535f2 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -51,6 +51,12 @@ grid = load_balanced_regional_grid(arch; ##### The Ocean component ##### +const Lz = grid.Lz +const h = Nz / 4.5 + +@inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) +@inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) + free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt = 20minutes) vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = 5e-3) @@ -60,7 +66,9 @@ ocean = ocean_simulation(grid; free_surface, closure) model = ocean.model # Initializing the model -set!(model, "checkpoint_iteration497897.jld2") +set!(model, + T = ECCOMetadata(:temperature), + S = ECCOMetadata(:salinity)) ##### ##### The atmosphere diff --git a/quarter_degree_omip/Manifest.toml b/quarter_degree_omip/Manifest.toml index 92c11f06..aa1d8791 100644 --- a/quarter_degree_omip/Manifest.toml +++ b/quarter_degree_omip/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.2" manifest_format = "2.0" -project_hash = "d412c6cb49202ad61a9e28c0d7d4a3658d51067c" +project_hash = "2b8dc0157e67ed69c1dbe71ccf1e8d7dd3d38b48" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" @@ -193,9 +193,7 @@ weakdeps = ["SparseArrays"] [[deps.ClimaOcean]] deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "FFMPEG", "ImageMorphology", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] -git-tree-sha1 = "a28b7f70177dab671632e2c26ecc462fa8ea4fa9" -repo-rev = "ss/omip-simulation" -repo-url = ".." +path = ".." uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" version = "0.1.0" @@ -696,15 +694,9 @@ version = "0.21.4" [[deps.JSON3]] deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] -git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -version = "1.14.0" - - [deps.JSON3.extensions] - JSON3ArrowExt = ["ArrowTypes"] - - [deps.JSON3.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" +version = "1.13.2" [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1115,7 +1107,7 @@ version = "1.6.3" [[deps.OrthogonalSphericalShellGrids]] deps = ["CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays"] -git-tree-sha1 = "ec6d87313f42d0c17e63f2dfd91b482f430ac57f" +git-tree-sha1 = "92f20b520de33f41a53efe943c5143924bf768b0" repo-rev = "main" repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl" uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" diff --git a/quarter_degree_omip/Project.toml b/quarter_degree_omip/Project.toml index 9cabfad5..2fa2bf04 100644 --- a/quarter_degree_omip/Project.toml +++ b/quarter_degree_omip/Project.toml @@ -1,6 +1,7 @@ [deps] ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" OrthogonalSphericalShellGrids = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" SurfaceFluxes = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" diff --git a/quarter_degree_omip/correct_oceananigans.jl b/quarter_degree_omip/correct_oceananigans.jl deleted file mode 100644 index d3269193..00000000 --- a/quarter_degree_omip/correct_oceananigans.jl +++ /dev/null @@ -1,62 +0,0 @@ - -#### -#### This file contains all the bug-fixes that still didn't get merged in Oceananigans.jl -#### - -using Oceananigans.BuoyancyModels: ∂z_b -using Oceananigans.Operators -using Oceananigans.Grids: peripheral_node, inactive_node -using Oceananigans.TurbulenceClosures: top_buoyancy_flux, getclosure, taper - -import Oceananigans.TurbulenceClosures: _compute_ri_based_diffusivities! - -@inline function _compute_ri_based_diffusivities!(i, j, k, diffusivities, grid, closure, - velocities, tracers, buoyancy, tracer_bcs, clock) - - # Ensure this works with "ensembles" of closures, in addition to ordinary single closures - closure_ij = getclosure(i, j, closure) - - ν₀ = closure_ij.ν₀ - κ₀ = closure_ij.κ₀ - κᶜᵃ = closure_ij.κᶜᵃ - Cᵃᵛ = closure_ij.Cᵃᵛ - Ri₀ = closure_ij.Ri₀ - Riᵟ = closure_ij.Riᵟ - tapering = closure_ij.Ri_dependent_tapering - - # Convection and entrainment - N² = ∂z_b(i, j, k, grid, buoyancy, tracers) - - # Conditions - convecting = N² < 0 # applies regardless of Qᵇ - - # Convective adjustment diffusivity - κᶜᵃ = ifelse(convecting, κᶜᵃ, zero(grid)) - - # Shear mixing diffusivity and viscosity - Ri = ℑxyᶜᶜᵃ(i, j, k, grid, ℑxyᶠᶠᵃ, diffusivities.Ri) - τ = taper(tapering, Ri, Ri₀, Riᵟ) - - κᶜ★ = κ₀ * τ - κᵘ★ = ν₀ * τ - - # Previous diffusivities - κᶜ = diffusivities.κᶜ - κᵘ = diffusivities.κᵘ - - # New diffusivities - κᶜ⁺ = κᶜ★ + κᶜᵃ - κᵘ⁺ = κᵘ★ - - # Set to zero on periphery and NaN within inactive region - on_periphery = peripheral_node(i, j, k, grid, Center(), Center(), Face()) - within_inactive = inactive_node(i, j, k, grid, Center(), Center(), Face()) - κᶜ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᶜ⁺)) - κᵘ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᵘ⁺)) - - # Update by averaging in time - @inbounds κᶜ[i, j, k] = (Cᵃᵛ * κᶜ[i, j, k] + κᶜ⁺) / (1 + Cᵃᵛ) - @inbounds κᵘ[i, j, k] = (Cᵃᵛ * κᵘ[i, j, k] + κᵘ⁺) / (1 + Cᵃᵛ) - - return nothing -end \ No newline at end of file diff --git a/quarter_degree_omip/quarter_degree_omip.jl b/quarter_degree_omip/quarter_degree_omip.jl index 2d3256ce..7cd7ef41 100644 --- a/quarter_degree_omip/quarter_degree_omip.jl +++ b/quarter_degree_omip/quarter_degree_omip.jl @@ -18,7 +18,7 @@ using ClimaOcean.JRA55 using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using ClimaOcean.Bathymetry -include("correct_oceananigans.jl") +include("three_dimensional_interpolate_tripolar.jl") ##### ##### Global Ocean at 1/4th of a degree @@ -39,8 +39,9 @@ grid = TripolarGrid(arch; size = (Nx, Ny, Nz), halo = (7, 7, 7), z = z_faces) bottom_height = retrieve_bathymetry(grid, bathymetry_file; minimum_depth = 10, + dir = "./", interpolation_passes = 20, - connected_regions_allowed = 1) + connected_regions_allowed = 0) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) @@ -54,10 +55,46 @@ const h = Nz / 4.5 @inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) @inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) -free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt = 20minutes) +free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt = 20minutes) vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = 5e-3) closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) ocean = ocean_simulation(grid; free_surface, closure) -model = ocean.model \ No newline at end of file +model = ocean.model + +set!(model, + T = ECCO2Metadata(:temperature), + S = ECCO2Metadata(:salinity)) + +##### +##### The atmosphere +##### + +backend = JRA55NetCDFBackend(10) +atmosphere = JRA55_prescribed_atmosphere(arch; backend) +radiation = Radiation() + +sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() + +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +wall_time = [time_ns()] + +function progress(sim) + u, v, w = sim.model.velocities + T, S = sim.model.tracers + + Tmax = maximum(abs, T) + Tmin = minimum(T) + umax = maximum(abs, u), maximum(abs, v), maximum(abs, w) + step_time = 1e-9 * (time_ns() - wall_time[1]) + + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", + prettytime(sim.model.clock.time), + sim.model.clock.iteration, + prettytime(sim.Δt), + umax..., Tmax, Tmin, prettytime(step_time)) + + wall_time[1] = time_ns() +end diff --git a/quarter_degree_omip/three_dimensional_interpolate_tripolar.jl b/quarter_degree_omip/three_dimensional_interpolate_tripolar.jl new file mode 100644 index 00000000..aa6fe004 --- /dev/null +++ b/quarter_degree_omip/three_dimensional_interpolate_tripolar.jl @@ -0,0 +1,59 @@ +using ClimaOcean +import ClimaOcean.InitialConditions: three_dimensional_interpolate! + +using Oceananigans +using Oceananigans.BoundaryConditions +using Oceananigans.Fields: OneField +using Oceananigans.Grids: peripheral_node +using Oceananigans.Utils: launch! +using Oceananigans.Fields: instantiated_location, interior, CenterField +using Oceananigans.Architectures: architecture, device, GPU, child_architecture + +using KernelAbstractions: @kernel, @index +using KernelAbstractions.Extras.LoopInfo: @unroll +using JLD2 + +# Implementation of 3-dimensional regridding +# TODO: move all the following to Oceananigans! + +using Oceananigans.Fields: regrid!, interpolate! +using Oceananigans.Grids: cpu_face_constructor_x, + cpu_face_constructor_y, + cpu_face_constructor_z, + topology + +using OrthogonalSphericalShellGrids: TRG +import OrthogonalSphericalShellGrids: sign + +sign(LX, LY) = 1 + +TField = Union{<:Field{<:Any, <:Any, <:Any, <:Any, <:TripolarGrid}, + <:Field{<:Any, <:Any, <:Any, <:Any, <:ImmersedBoundaryGrid{<:Any, <:Any, <:Any, <:Any, <:TripolarGrid}}} + +function three_dimensional_interpolate!(a::TField, b) + + interpolate!(a, b) + + return a +end + +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong, convert_to_native_grid + +# Here we assume that the tripolar grid is locally orthogonal +@inline function convert_to_latlong(i, j, grid::TRG, uₒ, vₒ) + λ₁ = λnode(i, j, 1, grid, Center(), Face(), Center()) + λ₂ = λnode(i, j+1, 1, grid, Center(), Face(), Center()) + + θ = λ₂ - λ₁ + + return uₒ * cos(θ) + vₒ * sin(θ), uₒ * sin(θ) + vₒ * cos(θ) +end + +@inline function convert_to_native_grid(i, j, grid::TRG, uₒ, vₒ) + λ₁ = λnode(i, j, 1, grid, Center(), Face(), Center()) + λ₂ = λnode(i, j+1, 1, grid, Center(), Face(), Center()) + + θ = λ₂ - λ₁ + + return uₒ * cos(θ) + vₒ * sin(θ), uₒ * sin(θ) + vₒ * cos(θ) +end diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index e1a15191..2075b794 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -26,10 +26,10 @@ 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, @@ -40,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 @@ -55,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 @@ -70,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 @@ -88,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/" * @@ -97,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/" * @@ -238,7 +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] data = ds[name][i₁:i₂, j₁:j₂, ti] close(ds) @@ -273,10 +272,10 @@ 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") + - `:river_freshwater_flux` ("friver") - `:rain_freshwater_flux` ("prra") - `:snow_freshwater_flux` ("prsn") - - `:freshwater_iceberg_flux` ("licalvf") + - `:iceberg_freshwater_flux` ("licalvf") - `:specific_humidity` ("huss") - `:sea_level_pressure` ("psl") - `:relative_humidity` ("rhuss") @@ -584,14 +583,11 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); 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, @@ -601,9 +597,9 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); q = qa) freshwater_flux = (rain = Fra, - snow = Fsn) - # rivers = Fv_JRA55, - # icebergs = Fi_JRA55) + snow = Fsn, + rivers = Fri, + icebergs = Fic) pressure = pa diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 75a8a283..78fcd377 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -231,6 +231,10 @@ end const c = Center() const f = Face() +# Fallback +@inline convert_to_latlong(i, j, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_native_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ + # Fallback! limit_fluxes_over_sea_ice!(args...) = nothing @@ -263,6 +267,8 @@ limit_fluxes_over_sea_ice!(args...) = nothing Sₒ = ocean_state.S[i, j, 1] end + uₒ, vₒ = convert_to_latlong(i, j, grid, uₒ, vₒ) + @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 @@ -335,6 +341,9 @@ limit_fluxes_over_sea_ice!(args...) = nothing kᴺ = size(grid, 3) # index of the top ocean cell + τˣ, τʸ = convert_to_native_grid(i, j, grid, turbulent_fluxes.x_momentum, + turbulent_fluxes.y_momentum) + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) @inbounds begin @@ -342,8 +351,8 @@ limit_fluxes_over_sea_ice!(args...) = nothing 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) + τx[i, j, 1] = ifelse(inactive, 0, τˣ) + τy[i, j, 1] = ifelse(inactive, 0, τʸ) end end @@ -460,39 +469,6 @@ end ##### Utility for interpolating tuples of fields ##### -# import Oceananigans.Fields: interpolate -# using Oceananigans: OffsetArray -# using Oceananigans.Grids: AbstractGrid - -# using Oceananigans.OutputReaders: fractional_indices, interpolator, interpolating_time_indices, memory_index, _interpolate - -# @inline function interpolate(at_node, at_time_index::Time, data::OffsetArray, -# from_loc, from_grid::AbstractGrid, times, backend, time_indexing) - -# at_time = at_time_index.time - -# # Build space interpolators -# ii, jj, kk = fractional_indices(at_node, from_grid, from_loc...) - -# ix = interpolator(ii) -# iy = interpolator(jj) -# iz = interpolator(kk) - -# ñ, n₁, n₂ = interpolating_time_indices(time_indexing, times, at_time) - -# Nt = length(times) -# m₁ = memory_index(backend, time_indexing, Nt, n₁) -# m₂ = memory_index(backend, time_indexing, Nt, n₂) - -# @show m₁, m₂, ñ, at_time, times -# ψ₁ = _interpolate(data, ix, iy, iz, m₁) -# ψ₂ = _interpolate(data, ix, iy, iz, m₂) -# ψ̃ = ψ₂ * ñ + ψ₁ * (1 - ñ) - -# # Don't interpolate if n₁ == n₂ -# return ifelse(n₁ == n₂, ψ₁, ψ̃) -# end - # Note: assumes loc = (c, c, nothing) (and the third location should # not matter.) @inline interp_atmos_time_series(J, X, time, grid, args...) = From 75e884f259961f1f014d05c0d41c6f3e7c6b9c8d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 20 Apr 2024 16:58:03 -0400 Subject: [PATCH 337/716] change name --- {quarter_degree_omip => prototype_omip_simulation}/Manifest.toml | 0 {quarter_degree_omip => prototype_omip_simulation}/Project.toml | 0 .../prototype_omip_simulation.jl | 0 .../three_dimensional_interpolate_tripolar.jl | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {quarter_degree_omip => prototype_omip_simulation}/Manifest.toml (100%) rename {quarter_degree_omip => prototype_omip_simulation}/Project.toml (100%) rename quarter_degree_omip/quarter_degree_omip.jl => prototype_omip_simulation/prototype_omip_simulation.jl (100%) rename {quarter_degree_omip => prototype_omip_simulation}/three_dimensional_interpolate_tripolar.jl (100%) diff --git a/quarter_degree_omip/Manifest.toml b/prototype_omip_simulation/Manifest.toml similarity index 100% rename from quarter_degree_omip/Manifest.toml rename to prototype_omip_simulation/Manifest.toml diff --git a/quarter_degree_omip/Project.toml b/prototype_omip_simulation/Project.toml similarity index 100% rename from quarter_degree_omip/Project.toml rename to prototype_omip_simulation/Project.toml diff --git a/quarter_degree_omip/quarter_degree_omip.jl b/prototype_omip_simulation/prototype_omip_simulation.jl similarity index 100% rename from quarter_degree_omip/quarter_degree_omip.jl rename to prototype_omip_simulation/prototype_omip_simulation.jl diff --git a/quarter_degree_omip/three_dimensional_interpolate_tripolar.jl b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl similarity index 100% rename from quarter_degree_omip/three_dimensional_interpolate_tripolar.jl rename to prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl From 001799f6c7d4f430abaf048824580e1d3c233070 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 20 Apr 2024 18:42:50 -0400 Subject: [PATCH 338/716] bugfix --- .../three_dimensional_interpolate_tripolar.jl | 7 ++++--- .../CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl index aa6fe004..0122c87c 100644 --- a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl +++ b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl @@ -20,7 +20,8 @@ using Oceananigans.Fields: regrid!, interpolate! using Oceananigans.Grids: cpu_face_constructor_x, cpu_face_constructor_y, cpu_face_constructor_z, - topology + topology, + λnode using OrthogonalSphericalShellGrids: TRG import OrthogonalSphericalShellGrids: sign @@ -46,7 +47,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong, conver θ = λ₂ - λ₁ - return uₒ * cos(θ) + vₒ * sin(θ), uₒ * sin(θ) + vₒ * cos(θ) + return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) end @inline function convert_to_native_grid(i, j, grid::TRG, uₒ, vₒ) @@ -55,5 +56,5 @@ end θ = λ₂ - λ₁ - return uₒ * cos(θ) + vₒ * sin(θ), uₒ * sin(θ) + vₒ * cos(θ) + return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 5076ff77..6b9bd328 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -421,11 +421,10 @@ end 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, + water_vapor = - ρₐ * u★ * q★, x_momentum = + ρₐ * τx, y_momentum = + ρₐ * τy, ) From 4349f541277ce330a88336d343cbc0ea01654d98 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 20 Apr 2024 18:48:59 -0400 Subject: [PATCH 339/716] bugfix --- .../three_dimensional_interpolate_tripolar.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl index 0122c87c..e7f8c532 100644 --- a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl +++ b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl @@ -9,10 +9,6 @@ using Oceananigans.Utils: launch! using Oceananigans.Fields: instantiated_location, interior, CenterField using Oceananigans.Architectures: architecture, device, GPU, child_architecture -using KernelAbstractions: @kernel, @index -using KernelAbstractions.Extras.LoopInfo: @unroll -using JLD2 - # Implementation of 3-dimensional regridding # TODO: move all the following to Oceananigans! From 8f64c34f25e9e3c4f9962489bc73cdbaadf50143 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 21 Apr 2024 21:08:10 -0400 Subject: [PATCH 340/716] add new stuff --- .../three_dimensional_interpolate_tripolar.jl | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl index e7f8c532..1f63f71d 100644 --- a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl +++ b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl @@ -19,15 +19,12 @@ using Oceananigans.Grids: cpu_face_constructor_x, topology, λnode -using OrthogonalSphericalShellGrids: TRG -import OrthogonalSphericalShellGrids: sign +using OrthogonalSphericalShellGrids: TRG, WRG, WarpedLatitude -sign(LX, LY) = 1 +const TField = Field{<:Any, <:Any, <:Any, <:Any, <:TRG} +const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} -TField = Union{<:Field{<:Any, <:Any, <:Any, <:Any, <:TripolarGrid}, - <:Field{<:Any, <:Any, <:Any, <:Any, <:ImmersedBoundaryGrid{<:Any, <:Any, <:Any, <:Any, <:TripolarGrid}}} - -function three_dimensional_interpolate!(a::TField, b) +function three_dimensional_interpolate!(a::Union{<:TField, <:WField}, b) interpolate!(a, b) @@ -36,6 +33,25 @@ end import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong, convert_to_native_grid +# Here we assume that the tripolar grid is locally orthogonal +@inline function convert_to_latlong(i, j, grid::WRG, uₒ, vₒ) + λ₁ = λnode(i, j, 1, grid, Center(), Face(), Center()) + λ₂ = λnode(i, j+1, 1, grid, Center(), Face(), Center()) + + θ = λ₂ - λ₁ + + return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) +end + +@inline function convert_to_native_grid(i, j, grid::WRG, uₒ, vₒ) + λ₁ = λnode(i, j, 1, grid, Center(), Face(), Center()) + λ₂ = λnode(i, j+1, 1, grid, Center(), Face(), Center()) + + θ = λ₂ - λ₁ + + return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) +end + # Here we assume that the tripolar grid is locally orthogonal @inline function convert_to_latlong(i, j, grid::TRG, uₒ, vₒ) λ₁ = λnode(i, j, 1, grid, Center(), Face(), Center()) From c815b45c687c9d967e10c3d5915dec2d8c9a81e7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 21 Apr 2024 21:12:32 -0400 Subject: [PATCH 341/716] bugfix --- .../three_dimensional_interpolate_tripolar.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl index 1f63f71d..56829714 100644 --- a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl +++ b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl @@ -19,7 +19,7 @@ using Oceananigans.Grids: cpu_face_constructor_x, topology, λnode -using OrthogonalSphericalShellGrids: TRG, WRG, WarpedLatitude +using OrthogonalSphericalShellGrids: TRG, WRG const TField = Field{<:Any, <:Any, <:Any, <:Any, <:TRG} const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} From 1037c77bc84e52da4510ef60fa85646a5fdf27fd Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 22 Apr 2024 22:59:26 -0400 Subject: [PATCH 342/716] convert correctly --- .../three_dimensional_interpolate_tripolar.jl | 33 ++++--------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl index 56829714..f29642f6 100644 --- a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl +++ b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl @@ -17,7 +17,7 @@ using Oceananigans.Grids: cpu_face_constructor_x, cpu_face_constructor_y, cpu_face_constructor_z, topology, - λnode + λnode, φnode using OrthogonalSphericalShellGrids: TRG, WRG @@ -33,40 +33,21 @@ end import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong, convert_to_native_grid -# Here we assume that the tripolar grid is locally orthogonal -@inline function convert_to_latlong(i, j, grid::WRG, uₒ, vₒ) - λ₁ = λnode(i, j, 1, grid, Center(), Face(), Center()) - λ₂ = λnode(i, j+1, 1, grid, Center(), Face(), Center()) - - θ = λ₂ - λ₁ - - return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) -end - -@inline function convert_to_native_grid(i, j, grid::WRG, uₒ, vₒ) - λ₁ = λnode(i, j, 1, grid, Center(), Face(), Center()) - λ₂ = λnode(i, j+1, 1, grid, Center(), Face(), Center()) - - θ = λ₂ - λ₁ - - return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) -end - # Here we assume that the tripolar grid is locally orthogonal @inline function convert_to_latlong(i, j, grid::TRG, uₒ, vₒ) - λ₁ = λnode(i, j, 1, grid, Center(), Face(), Center()) - λ₂ = λnode(i, j+1, 1, grid, Center(), Face(), Center()) + φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) + φ₂ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) - θ = λ₂ - λ₁ + θ = φ₂ - φ₁ return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) end @inline function convert_to_native_grid(i, j, grid::TRG, uₒ, vₒ) - λ₁ = λnode(i, j, 1, grid, Center(), Face(), Center()) - λ₂ = λnode(i, j+1, 1, grid, Center(), Face(), Center()) + φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) + φ₂ = φnode(i, j+1, 1, grid, Face(), Center(), Center()) - θ = λ₂ - λ₁ + θ = φ₂ - φ₁ return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) end From f06f53a320e7e7f1fd0d344c140a9c7a34c74c8e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:53:56 -0400 Subject: [PATCH 343/716] give it another try --- .../correct_oceananigans.jl | 61 +++++++++++++++++++ .../prototype_omip_simulation.jl | 56 +++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 prototype_omip_simulation/correct_oceananigans.jl diff --git a/prototype_omip_simulation/correct_oceananigans.jl b/prototype_omip_simulation/correct_oceananigans.jl new file mode 100644 index 00000000..3c3dab76 --- /dev/null +++ b/prototype_omip_simulation/correct_oceananigans.jl @@ -0,0 +1,61 @@ +#### +#### This file contains all the bug-fixes that still didn't get merged in Oceananigans.jl +#### + +using Oceananigans.BuoyancyModels: ∂z_b +using Oceananigans.Operators +using Oceananigans.Grids: peripheral_node, inactive_node +using Oceananigans.TurbulenceClosures: top_buoyancy_flux, getclosure, taper + +import Oceananigans.TurbulenceClosures: _compute_ri_based_diffusivities! + +@inline function _compute_ri_based_diffusivities!(i, j, k, diffusivities, grid, closure, + velocities, tracers, buoyancy, tracer_bcs, clock) + + # Ensure this works with "ensembles" of closures, in addition to ordinary single closures + closure_ij = getclosure(i, j, closure) + + ν₀ = closure_ij.ν₀ + κ₀ = closure_ij.κ₀ + κᶜᵃ = closure_ij.κᶜᵃ + Cᵃᵛ = closure_ij.Cᵃᵛ + Ri₀ = closure_ij.Ri₀ + Riᵟ = closure_ij.Riᵟ + tapering = closure_ij.Ri_dependent_tapering + + # Convection and entrainment + N² = ∂z_b(i, j, k, grid, buoyancy, tracers) + + # Conditions + convecting = N² < 0 # applies regardless of Qᵇ + + # Convective adjustment diffusivity + κᶜᵃ = ifelse(convecting, κᶜᵃ, zero(grid)) + + # Shear mixing diffusivity and viscosity + Ri = ℑxyᶜᶜᵃ(i, j, k, grid, ℑxyᶠᶠᵃ, diffusivities.Ri) + τ = taper(tapering, Ri, Ri₀, Riᵟ) + + κᶜ★ = κ₀ * τ + κᵘ★ = ν₀ * τ + + # Previous diffusivities + κᶜ = diffusivities.κᶜ + κᵘ = diffusivities.κᵘ + + # New diffusivities + κᶜ⁺ = κᶜ★ + κᶜᵃ + κᵘ⁺ = κᵘ★ + + # Set to zero on periphery and NaN within inactive region + on_periphery = peripheral_node(i, j, k, grid, Center(), Center(), Face()) + within_inactive = inactive_node(i, j, k, grid, Center(), Center(), Face()) + κᶜ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᶜ⁺)) + κᵘ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᵘ⁺)) + + # Update by averaging in time + @inbounds κᶜ[i, j, k] = (Cᵃᵛ * κᶜ[i, j, k] + κᶜ⁺) / (1 + Cᵃᵛ) + @inbounds κᵘ[i, j, k] = (Cᵃᵛ * κᵘ[i, j, k] + κᵘ⁺) / (1 + Cᵃᵛ) + + return nothing +end \ No newline at end of file diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 7cd7ef41..b8c12393 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -18,6 +18,7 @@ using ClimaOcean.JRA55 using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using ClimaOcean.Bathymetry +include("correct_oceananigans.jl") include("three_dimensional_interpolate_tripolar.jl") ##### @@ -98,3 +99,58 @@ function progress(sim) wall_time[1] = time_ns() end + +ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) + +# fluxes = (u = model.velocities.u.boundary_conditions.top.condition, +# v = model.velocities.v.boundary_conditions.top.condition, +# T = model.tracers.T.boundary_conditions.top.condition, +# S = model.tracers.S.boundary_conditions.top.condition) + +# ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, +# schedule = TimeInterval(0.5days), +# overwrite_existing = true, +# array_type = Array{Float32}, +# filename = "surface_fluxes") + +# ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), +# schedule = TimeInterval(0.5days), +# overwrite_existing = true, +# array_type = Array{Float32}, +# filename = "surface", +# indices = (:, :, grid.Nz)) + +# ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), +# schedule = TimeInterval(10days), +# overwrite_existing = true, +# array_type = Array{Float32}, +# filename = "snapshots") + +# ocean.output_writers[:checkpoint] = Checkpointer(model, +# schedule = TimeInterval(60days), +# overwrite_existing = true, +# prefix = "checkpoint") + +# Simulation warm up! +ocean.Δt = 10 +ocean.stop_iteration = 1 +wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) + +stop_time = 20days +stop_iteration = 1 + +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time, stop_iteration) + +run!(coupled_simulation) + +# wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 540, max_change = 1.1) +# ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) + +# # Let's reset the maximum number of iterations +# coupled_model.ocean.stop_time = 7200days +# coupled_simulation.stop_time = 7200days +# coupled_model.ocean.stop_iteration = Inf +# coupled_simulation.stop_iteration = Inf + +# run!(coupled_simulation) From 6d50adf8cf784f5e2da6617fc917b879c0c9759a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:59:32 -0400 Subject: [PATCH 344/716] all the stuff --- .../prototype_omip_simulation.jl | 77 +++++++++---------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index b8c12393..98b4c7ba 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -102,34 +102,34 @@ end ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) -# fluxes = (u = model.velocities.u.boundary_conditions.top.condition, -# v = model.velocities.v.boundary_conditions.top.condition, -# T = model.tracers.T.boundary_conditions.top.condition, -# S = model.tracers.S.boundary_conditions.top.condition) - -# ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, -# schedule = TimeInterval(0.5days), -# overwrite_existing = true, -# array_type = Array{Float32}, -# filename = "surface_fluxes") - -# ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), -# schedule = TimeInterval(0.5days), -# overwrite_existing = true, -# array_type = Array{Float32}, -# filename = "surface", -# indices = (:, :, grid.Nz)) - -# ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), -# schedule = TimeInterval(10days), -# overwrite_existing = true, -# array_type = Array{Float32}, -# filename = "snapshots") - -# ocean.output_writers[:checkpoint] = Checkpointer(model, -# schedule = TimeInterval(60days), -# overwrite_existing = true, -# prefix = "checkpoint") +fluxes = (u = model.velocities.u.boundary_conditions.top.condition, + v = model.velocities.v.boundary_conditions.top.condition, + T = model.tracers.T.boundary_conditions.top.condition, + S = model.tracers.S.boundary_conditions.top.condition) + +ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, + schedule = TimeInterval(0.5days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "surface_fluxes") + +ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(0.5days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "surface", + indices = (:, :, grid.Nz)) + +ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(10days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "snapshots") + +ocean.output_writers[:checkpoint] = Checkpointer(model, + schedule = TimeInterval(60days), + overwrite_existing = true, + prefix = "checkpoint") # Simulation warm up! ocean.Δt = 10 @@ -138,19 +138,18 @@ wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) stop_time = 20days -stop_iteration = 1 - -coupled_simulation = Simulation(coupled_model; Δt=1, stop_time, stop_iteration) +\\ +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) run!(coupled_simulation) -# wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 540, max_change = 1.1) -# ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 540, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) -# # Let's reset the maximum number of iterations -# coupled_model.ocean.stop_time = 7200days -# coupled_simulation.stop_time = 7200days -# coupled_model.ocean.stop_iteration = Inf -# coupled_simulation.stop_iteration = Inf +# Let's reset the maximum number of iterations +coupled_model.ocean.stop_time = 7200days +coupled_simulation.stop_time = 7200days +coupled_model.ocean.stop_iteration = Inf +coupled_simulation.stop_iteration = Inf -# run!(coupled_simulation) +run!(coupled_simulation) From ca29a4201c6b2504aed79040f2b6ff3366888ed0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:23:29 -0400 Subject: [PATCH 345/716] changes --- Manifest.toml | 158 ++++++++++++------------ experiments/twelth_degree_latlong.jl | 34 ++--- prototype_omip_simulation/Manifest.toml | 2 +- 3 files changed, 99 insertions(+), 95 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index da3664fb..3f6be95c 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -51,16 +51,19 @@ 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 = "133a240faec6e074e07c31ee75619c90544179cf" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.7.1" +version = "7.10.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = "CUDSS" + ArrayInterfaceChainRulesExt = "ChainRules" ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" ArrayInterfaceTrackerExt = "Tracker" @@ -68,7 +71,10 @@ version = "7.7.1" BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" @@ -83,9 +89,9 @@ version = "0.1.0" [[deps.BFloat16s]] deps = ["LinearAlgebra", "Printf", "Random", "Test"] -git-tree-sha1 = "dbf84058d0a8cbbadee18d25cf606934b22d7c66" +git-tree-sha1 = "2c7cc21e8678eff479978a0a2ef5ce2f51b63dff" uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" -version = "0.4.2" +version = "0.5.0" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" @@ -149,9 +155,9 @@ version = "0.7.0+1" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] -git-tree-sha1 = "2cb12f6b2209f40a4b8967697689a47c50485490" +git-tree-sha1 = "38f830504358e9972d2a0c3e5d51cb865e0733df" uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.2.3" +version = "0.2.4" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] @@ -160,10 +166,10 @@ 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", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" +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.16.1+1" +version = "1.18.0+1" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] @@ -197,9 +203,9 @@ version = "0.7.4" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.4" +version = "0.11.5" [[deps.ColorVectorSpace]] deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] @@ -260,15 +266,15 @@ weakdeps = ["InverseFunctions"] [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "9c4708e3ed2b799e6124b5673a712dda0b596a9b" +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.3.1" +version = "2.4.1" [[deps.ConstructionBase]] deps = ["LinearAlgebra"] -git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.4" +version = "1.5.5" [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" @@ -313,16 +319,16 @@ 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" +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 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.17.20" +version = "0.18.20" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -368,9 +374,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.DocStringExtensions]] deps = ["LibGit2"] -git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.3" +version = "0.8.6" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] @@ -425,9 +431,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" @@ -477,9 +483,9 @@ version = "6.2.1+6" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "47e4686ec18a9620850bad110b79966132f14283" +git-tree-sha1 = "68e8ff56a4a355a85d2784b94614491f8c900cde" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "10.0.2" +version = "10.1.0" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -501,9 +507,9 @@ 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" +git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.76.5+0" +version = "2.80.0+0" [[deps.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" @@ -512,9 +518,9 @@ version = "1.3.1" [[deps.GnuTLS_jll]] deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Nettle_jll", "P11Kit_jll", "Zlib_jll"] -git-tree-sha1 = "f3c0936dd685d57fa0b1eee7dbebf382b969ea63" +git-tree-sha1 = "383db7d3f900f4c1f47a8a04115b053c095e48d3" uuid = "0951126a-58fd-58f1-b5b3-b08c7c4a876d" -version = "3.8.3+0" +version = "3.8.4+0" [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -530,9 +536,9 @@ version = "1.14.2+1" [[deps.HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "ac7b73d562b8f4287c3b67b4c66a5395a19c1ae8" +git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.2" +version = "1.10.5" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -593,9 +599,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" @@ -668,9 +678,9 @@ version = "3.100.1+0" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "ddab4d40513bce53c8e3157825e245224f74fae7" +git-tree-sha1 = "839c82932db86740ae729779e610f07a1640be9a" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.6.0" +version = "6.6.3" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -775,16 +785,16 @@ uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" version = "1.17.0+0" [[deps.Libmount_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.35.0+0" +version = "2.39.3+0" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e5edc369a598dfde567269dc6add5812cfa10cd5" +git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.39.3+0" +version = "2.39.3+1" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -817,9 +827,9 @@ version = "1.0.3" [[deps.LoopVectorization]] deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "0f5648fbae0d015e3abe5867bca2b362f67a5894" +git-tree-sha1 = "a13f3be5d84b9c95465d743c82af0b094ef9c2e2" uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.166" +version = "0.12.169" weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] [deps.LoopVectorization.extensions] @@ -909,9 +919,9 @@ version = "10.1.4+2" [[deps.Missings]] deps = ["DataAPI"] -git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.1.0" +version = "1.2.0" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" @@ -979,9 +989,9 @@ version = "0.90.9" Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" [[deps.OffsetArrays]] -git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" +git-tree-sha1 = "e64b4f5ea6b7389f6f046d13d4896a8f9c1ba71e" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.13.0" +version = "1.14.0" weakdeps = ["Adapt"] [deps.OffsetArrays.extensions] @@ -1011,15 +1021,15 @@ version = "5.0.2+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2" +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.1" +version = "1.4.2" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "60e3045590bd104a16fefb12836c00c0ef8c7f8c" +git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.13+0" +version = "3.0.13+1" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1051,9 +1061,9 @@ version = "10.42.0+1" [[deps.PMIx_jll]] deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] -git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" +git-tree-sha1 = "360f48126b5f2c2f0c833be960097f7c62705976" uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" -version = "4.2.7+0" +version = "4.2.9+0" [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" @@ -1124,9 +1134,9 @@ 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"] @@ -1207,9 +1217,9 @@ version = "0.4.2" [[deps.Roots]] deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] -git-tree-sha1 = "754acd3031a9f2eaf6632ba4850b1c01fe4460c1" +git-tree-sha1 = "1ab580704784260ee5f45bffac810b152922747b" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.1.2" +version = "2.1.5" [deps.Roots.extensions] RootsForwardDiffExt = "ForwardDiff" @@ -1273,12 +1283,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" @@ -1499,9 +1503,9 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.23" [[deps.TranscodingStreams]] -git-tree-sha1 = "54194d92959d8ebaa8e26227dbe3cdefcdcd594f" +git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.3" +version = "0.10.7" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] @@ -1542,9 +1546,9 @@ version = "0.1.3" [[deps.VectorizationBase]] deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "7209df901e6ed7489fe9b7aa3e46fb788e15db85" +git-tree-sha1 = "ac377f0a248753a1b1d58bbc92a64f5a726dfb71" uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.65" +version = "0.21.66" [[deps.VersionParsing]] git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" @@ -1553,9 +1557,9 @@ version = "1.3.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "07e470dabc5a6a4254ffebc29a1b3fc01464e105" +git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.5+0" +version = "2.12.6+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] @@ -1565,9 +1569,9 @@ version = "1.1.34+0" [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "37195dcb94a5970397ad425b95a9a26d0befce3a" +git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.6.0+0" +version = "5.4.6+0" [[deps.Xorg_libX11_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] @@ -1624,9 +1628,9 @@ version = "1.2.13+1" [[deps.Zstd_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" +git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b" uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.5+0" +version = "1.5.6+0" [[deps.libaec_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1665,9 +1669,9 @@ version = "2.0.2+0" [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "1ea2ebe8ffa31f9c324e8c1d6e86b4165b84a024" +git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.43+0" +version = "1.6.43+1" [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl index b71535f2..088a3d15 100644 --- a/experiments/twelth_degree_latlong.jl +++ b/experiments/twelth_degree_latlong.jl @@ -121,28 +121,28 @@ ocean.stop_iteration = 1 wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -stop_time = 10days +# stop_time = 10days -coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) +# coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) -try - run!(coupled_simulation) -catch +# try +# run!(coupled_simulation) +# catch -end +# end -wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 15minutes, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +# wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 15minutes, max_change = 1.1) +# ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) -# Let's reset the maximum number of iterations -coupled_model.ocean.stop_time = 7200days -coupled_simulation.stop_time = 7200days -coupled_model.ocean.stop_iteration = Inf -coupled_simulation.stop_iteration = Inf +# # Let's reset the maximum number of iterations +# coupled_model.ocean.stop_time = 7200days +# coupled_simulation.stop_time = 7200days +# coupled_model.ocean.stop_iteration = Inf +# coupled_simulation.stop_iteration = Inf -try - run!(coupled_simulation) -catch +# try +# run!(coupled_simulation) +# catch -end +# end diff --git a/prototype_omip_simulation/Manifest.toml b/prototype_omip_simulation/Manifest.toml index aa1d8791..6686a66f 100644 --- a/prototype_omip_simulation/Manifest.toml +++ b/prototype_omip_simulation/Manifest.toml @@ -1107,7 +1107,7 @@ version = "1.6.3" [[deps.OrthogonalSphericalShellGrids]] deps = ["CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays"] -git-tree-sha1 = "92f20b520de33f41a53efe943c5143924bf768b0" +git-tree-sha1 = "9f55479bbaa571762ac02f7664125d342022d5d1" repo-rev = "main" repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl" uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" From a6f62d3ce52525b13f32405aeaf8dbfbff9a4243 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:07:08 -0400 Subject: [PATCH 346/716] go ahead --- src/OceanSimulations/OceanSimulations.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index eb0229e4..20df85bb 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -62,7 +62,8 @@ function ocean_simulation(grid; Δt = 5minutes, gravitational_acceleration = g_Earth, drag_coefficient = 0.003, momentum_advection = default_momentum_advection(), - tracer_advection = default_tracer_advection()) + tracer_advection = default_tracer_advection(), + verbose = false) # Set up boundary conditions using Field top_zonal_momentum_flux = Jᵘ = Field{Face, Center, Nothing}(grid) @@ -113,7 +114,7 @@ function ocean_simulation(grid; Δt = 5minutes, coriolis, boundary_conditions = ocean_boundary_conditions) - ocean = Simulation(ocean_model; Δt, verbose=false) + ocean = Simulation(ocean_model; Δt, verbose) return ocean end From 6a17c02e5598499b4608d8542036b8aae6fdb8bc Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:29:27 -0400 Subject: [PATCH 347/716] tests --- .../comparison_to_coare.jl | 133 +++++++++++++++++ .../ecco2_immersed_grid.jl | 20 +++ .../prototype_omip_simulation.jl | 2 +- src/DataWrangling/ECCO2.jl | 140 +++++++++++++----- .../ocean_sea_ice_surface_fluxes.jl | 10 +- .../similarity_theory_turbulent_fluxes.jl | 4 +- 6 files changed, 263 insertions(+), 46 deletions(-) create mode 100644 prototype_omip_simulation/comparison_to_coare.jl create mode 100644 prototype_omip_simulation/ecco2_immersed_grid.jl diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl new file mode 100644 index 00000000..93920f5b --- /dev/null +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -0,0 +1,133 @@ +using Printf +using Oceananigans.Units +using ClimaOcean +using Oceananigans +using Oceananigans.Operators +using ClimaOcean.ECCO2 +using ClimaOcean.OceanSimulations +using Oceananigans.Units +using ClimaOcean.JRA55: JRA55_prescribed_atmosphere +using KernelAbstractions: @index, @kernel +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + +import Oceananigans.OutputReaders: interpolate!, FieldTimeSeries +using Oceananigans.Grids: architecture, location, node, with_halo +using Oceananigans.BoundaryConditions +using Oceananigans.Utils: launch!, Time +using Oceananigans.Fields: interpolate, instantiate + +@kernel function _interpolate_field_time_series_new!(target_fts, target_grid, target_location, target_times, + source_fts, source_grid, source_location) + + # 4D index, cool! + i, j, k, n = @index(Global, NTuple) + + target_node = node(i, j, k, target_grid, target_location...) + at_time = @inbounds target_times[n] + + @inbounds target_fts[i, j, k, n] = interpolate(target_node, at_time, + source_fts, source_location, source_grid) +end + +function interpolate!(target_fts::FieldTimeSeries, source_fts::FieldTimeSeries) + + 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 = map(instantiate, location(source_fts)) + target_location = map(instantiate, location(target_fts)) + + target_times = target_fts.times + + launch!(arch, target_grid, size(target_fts), + _interpolate_field_time_series_new!, + target_fts.data, target_grid, target_location, Time.(target_times), + source_fts, source_grid, source_location) + + fill_halo_regions!(target_fts) + + return nothing +end + +# Upload ECCO2 fields +T = ECCO2.ecco2_field(:temperature) +S = ECCO2.ecco2_field(:salinity) +u = ECCO2.ecco2_field(:u_velocity) +v = ECCO2.ecco2_field(:v_velocity) + +include("ecco2_immersed_grid.jl") +grid = ecco2_immersed_grid() + +# Let's leave out the radiation for the moment (too simple to test) +atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory(), grid = grid.underlying_grid) + +ocean = ocean_simulation(grid; momentum_advection = nothing, + tracer_advection = nothing) + +ocean_model = ocean.model + +# setting ecco variables in the model +set!(ocean_model, T = T, S = S, u = u, v = v) + +coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation = nothing) + +function centered_surface_u_velocity(u) + 𝒰ᶜᶜᶜ = KernelFunctionOperation{Center, Center, Center}(ℑxᶜᵃᵃ, grid, u) + uᶜᶜᶜ = Field(𝒰ᶜᶜᶜ) + compute!(uᶜᶜᶜ) + + Nz = size(uᶜᶜᶜ.grid, 3) + + return Array(interior(uᶜᶜᶜ, :, :, Nz)) +end + +function centered_surface_v_velocity(v) + 𝒱ᶜᶜᶜ = KernelFunctionOperation{Center, Center, Center}(ℑyᵃᶜᵃ, grid, v) + vᶜᶜᶜ = Field(𝒱ᶜᶜᶜ) + compute!(vᶜᶜᶜ) + + Nz = size(vᶜᶜᶜ.grid, 3) + + return Array(interior(vᶜᶜᶜ, :, :, Nz)) +end + +# Write down variables to be read by MATLAB! +using MAT + +matfile = matopen("surface_fluxes.mat", "w") + +# Ocean variables +uo = centered_surface_u_velocity(ocean_model.velocities.u) +vo = centered_surface_v_velocity(ocean_model.velocities.v) +To = Array(interior(ocean_model.tracers.T, :, :, grid.Nz)) +So = Array(interior(ocean_model.tracers.T, :, :, grid.Nz)) +write(matfile, "uo", uo) +write(matfile, "vo", vo) +write(matfile, "To", To) +write(matfile, "So", So) + +# Atmospheric variables +ua = Array(interior(atmosphere.velocities.u[1], :, :, 1)) +va = Array(interior(atmosphere.velocities.v[1], :, :, 1)) +Ta = Array(interior(atmosphere.tracers.T[1], :, :, 1)) +qa = Array(interior(atmosphere.tracers.q[1], :, :, 1)) +write(matfile, "ua", ua) +write(matfile, "va", va) +write(matfile, "Ta", Ta) +write(matfile, "qa", qa) + +# Turbulent fluxes +Ql = Array(interior(coupled_model.fluxes.turbulent.fields.latent_heat, :, :, 1)) +Qs = Array(interior(coupled_model.fluxes.turbulent.fields.sensible_heat, :, :, 1)) +Mv = Array(interior(coupled_model.fluxes.turbulent.fields.water_vapor, :, :, 1)) +tx = Array(interior(coupled_model.fluxes.turbulent.fields.x_momentum, :, :, 1)) +ty = Array(interior(coupled_model.fluxes.turbulent.fields.y_momentum, :, :, 1)) +write(matfile, "Ql", Ql) +write(matfile, "Qs", Qs) +write(matfile, "Mv", Mv) +write(matfile, "tx", tx) +write(matfile, "ty", ty) diff --git a/prototype_omip_simulation/ecco2_immersed_grid.jl b/prototype_omip_simulation/ecco2_immersed_grid.jl new file mode 100644 index 00000000..fc7125fb --- /dev/null +++ b/prototype_omip_simulation/ecco2_immersed_grid.jl @@ -0,0 +1,20 @@ +function ecco2_immersed_grid() + mask = ecco2_center_mask() + grid = with_halo((3, 3, 3), mask.grid) + + Nx, Ny, Nz = size(grid) + bathymetry = zeros(Nx, Ny) + + for i in 1:Nx, j in 1:Ny + for k in Nz:-1:1 + if mask[i, j, k] + bathymetry[i, j] = 0.5 .* (grid.zᵃᵃᶜ[k] + grid.zᵃᵃᶠ[k+1]) + break; + elseif k == 1 + bathymetry[i, j] = - grid.Lz - 1 + end + end + end + + return ImmersedBoundaryGrid(grid, GridFittedBottom(bathymetry)) +end \ No newline at end of file diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 98b4c7ba..49af1da7 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -138,7 +138,7 @@ wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) stop_time = 20days -\\ + coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) run!(coupled_simulation) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index af128699..04c6d209 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -24,51 +24,113 @@ struct ECCO2Metadata day :: Int end +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, +] + # We only have 1992 at the moment ECCO2Metadata(name::Symbol) = ECCO2Metadata(name, 1992, 1, 2) filename(data::ECCO2Metadata) = "ecco2_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).nc" -ecco2_short_names = Dict( - :temperature => "THETA", - :salinity => "SALT", - :effective_ice_thickness => "SIheff" -) - -ecco2_location = Dict( - :temperature => (Center, Center, Center), - :salinity => (Center, Center, Center), - :effective_ice_thickness => (Center, Center, Nothing) -) - -ecco2_depth_names = Dict( - :temperature => "DEPTH_T", - :salinity => "DEPTH_T", +ecco2_file_names = Dict( + :temperature => "THETA.1440x720x50.19920102.nc", + :salinity => "SALT.1440x720x50.19920102.nc", + :sea_ice_thickness => "SIheff.1440x720.19920102.nc", + :sea_ice_area_fraction => "SIarea.1440x720.19920102.nc", + :u_velocity => "UVEL.1440x720.19920102.nc", + :v_velocity => "VVEL.1440x720.19920102.nc", ) variable_is_three_dimensional = Dict( :temperature => true, :salinity => true, - :effective_ice_thickness => false, + :u_velocity => true, + :v_velocity => true, + :sea_ice_thickness => false, + :sea_ice_area_fraction => false, ) -ecco2_file_names = Dict( - :temperature => "ecco2_temperature_19920102.nc", - :salinity => "ecco2_salinity_19920102.nc", - :effective_ice_thickness => "ecco2_effective_ice_thickness_19920102.nc", +ecco2_short_names = Dict( + :temperature => "THETA", + :salinity => "SALT", + :u_velocity => "UVEL", + :v_velocity => "VVEL", + :sea_ice_thickness => "SIheff", + :sea_ice_area_fraction => "SIarea" ) -# Downloaded from https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N +ecco2_location = Dict( + :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_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", - - :effective_ice_thickness => "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/" * - "SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am&dl=0" + :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", ) surface_variable(variable_name) = variable_name == :sea_ice_thickness @@ -100,24 +162,19 @@ function empty_ecco2_field(data::ECCO2Metadata; latitude = (-90, 90) TX, TY = (Periodic, Bounded) - filename = ecco2_file_names[variable_name] - - ds = Dataset(filename) - if variable_is_three_dimensional[variable_name] - depth_name = ecco2_depth_names[variable_name] - z = construct_vertical_interfaces(ds, depth_name) + z = ECCO2_z # add vertical halo for 3D fields halo = (horizontal_halo..., 1) LZ = Center TZ = Bounded - N = (1440, 720, 50) + N = (ECCO2_Nx, ECCO2_Ny, ECCO2_Nz) else z = nothing halo = horizontal_halo LZ = Nothing TZ = Flat - N = (1440, 720) + N = (ECCO2_Nx, ECCO2_Ny) end # Flat in z if the variable is two-dimensional @@ -159,7 +216,6 @@ function ecco2_field(variable_name; if user_data isa Nothing ds = Dataset(filename) - if variable_is_three_dimensional[variable_name] data = ds[short_name][:, :, :, 1] # The surface layer in three-dimensional ECCO fields is at `k = 1` @@ -173,7 +229,13 @@ function ecco2_field(variable_name; field = empty_ecco2_field(ecco2_data; architecture, horizontal_halo) FT = eltype(field) - data = convert.(FT, data) + data = if location(field)[2] == Face + new_data = zeros(FT, size(field)) + new_data[:, 1:end-1, :] .= data + new_data + else + convert.(FT, data) + end set!(field, data) fill_halo_regions!(field) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 78fcd377..34627774 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -174,6 +174,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) Qs = atmosphere.downwelling_radiation.shortwave Ql = atmosphere.downwelling_radiation.longwave + downwelling_radiation = (shortwave=Qs.data, longwave=Ql.data) kernel_size = (size(grid, 1) + 2, size(grid, 2) + 2) @@ -228,9 +229,6 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) return nothing end -const c = Center() -const f = Face() - # Fallback @inline convert_to_latlong(i, j, grid, uₒ, vₒ) = uₒ, vₒ @inline convert_to_native_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ @@ -450,6 +448,10 @@ end end end +# Fallback for a `Nothing` radiation scheme +@inline net_upwelling_radiation(i, j, grid, time, ::Nothing, Tₒ) = zero(0) +@inline net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, ::Nothing) = zero(0) + @inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) α = stateindex(radiation.reflection.ocean, i, j, 1, time) ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) @@ -464,7 +466,7 @@ end # Note: positive implies _upward_ heat flux, and therefore cooling. return ϵ * σ * Tₒ^4 end - + ##### ##### Utility for interpolating tuples of fields ##### diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 6b9bd328..6ce712c0 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -93,9 +93,9 @@ function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) end function default_roughness_lengths(FT=Float64) - momentum = 1e-4 #GravityWaveRoughnessLength(FT) + momentum = convert(FT, 1e-4) #GravityWaveRoughnessLength(FT) temperature = convert(FT, 1e-4) - water_vapor = nothing + water_vapor = convert(FT, 1e-4) return SimilarityScales(momentum, temperature, water_vapor) end From e9aeda3b09315ffb5d972c2d569a6c1d138f84d1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:08:49 -0400 Subject: [PATCH 348/716] comparison to coare --- prototype_omip_simulation/comparison_to_coare.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index 93920f5b..1e2d59a6 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -115,10 +115,12 @@ ua = Array(interior(atmosphere.velocities.u[1], :, :, 1)) va = Array(interior(atmosphere.velocities.v[1], :, :, 1)) Ta = Array(interior(atmosphere.tracers.T[1], :, :, 1)) qa = Array(interior(atmosphere.tracers.q[1], :, :, 1)) +pa = Array(interior(atmosphere.pressure[1], :, :, 1)) write(matfile, "ua", ua) write(matfile, "va", va) write(matfile, "Ta", Ta) write(matfile, "qa", qa) +write(matfile, "pa", pa) # Turbulent fluxes Ql = Array(interior(coupled_model.fluxes.turbulent.fields.latent_heat, :, :, 1)) @@ -131,3 +133,5 @@ write(matfile, "Qs", Qs) write(matfile, "Mv", Mv) write(matfile, "tx", tx) write(matfile, "ty", ty) + +close(matfile) From bfc38a6169e0b8d001e708bbaf0c7134fb9afa9e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:13:31 -0400 Subject: [PATCH 349/716] adding main --- Manifest.toml | 6 ++- .../comparison_to_coare.jl | 45 ------------------- .../ecco2_immersed_grid.jl | 2 + 3 files changed, 6 insertions(+), 47 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 3f6be95c..548c3a75 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -978,9 +978,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 = "1910b8553f78cdd9a8496f51ea693b3adbd6b984" +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.9" +version = "0.90.12" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index 1e2d59a6..0c598a65 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -7,51 +7,6 @@ using ClimaOcean.ECCO2 using ClimaOcean.OceanSimulations using Oceananigans.Units using ClimaOcean.JRA55: JRA55_prescribed_atmosphere -using KernelAbstractions: @index, @kernel -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState - -import Oceananigans.OutputReaders: interpolate!, FieldTimeSeries -using Oceananigans.Grids: architecture, location, node, with_halo -using Oceananigans.BoundaryConditions -using Oceananigans.Utils: launch!, Time -using Oceananigans.Fields: interpolate, instantiate - -@kernel function _interpolate_field_time_series_new!(target_fts, target_grid, target_location, target_times, - source_fts, source_grid, source_location) - - # 4D index, cool! - i, j, k, n = @index(Global, NTuple) - - target_node = node(i, j, k, target_grid, target_location...) - at_time = @inbounds target_times[n] - - @inbounds target_fts[i, j, k, n] = interpolate(target_node, at_time, - source_fts, source_location, source_grid) -end - -function interpolate!(target_fts::FieldTimeSeries, source_fts::FieldTimeSeries) - - 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 = map(instantiate, location(source_fts)) - target_location = map(instantiate, location(target_fts)) - - target_times = target_fts.times - - launch!(arch, target_grid, size(target_fts), - _interpolate_field_time_series_new!, - target_fts.data, target_grid, target_location, Time.(target_times), - source_fts, source_grid, source_location) - - fill_halo_regions!(target_fts) - - return nothing -end # Upload ECCO2 fields T = ECCO2.ecco2_field(:temperature) diff --git a/prototype_omip_simulation/ecco2_immersed_grid.jl b/prototype_omip_simulation/ecco2_immersed_grid.jl index fc7125fb..64977ccc 100644 --- a/prototype_omip_simulation/ecco2_immersed_grid.jl +++ b/prototype_omip_simulation/ecco2_immersed_grid.jl @@ -1,3 +1,5 @@ +using Oceananigans.Grids: architecture, location, node, with_halo + function ecco2_immersed_grid() mask = ecco2_center_mask() grid = with_halo((3, 3, 3), mask.grid) From ee606a7bf7487837b8bcd89c8271846f1cd65e2c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:10:32 -0400 Subject: [PATCH 350/716] some changes --- src/OceanSimulations/OceanSimulations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 20df85bb..365af634 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -20,7 +20,7 @@ using Oceananigans.Operators include("load_balanced_regional_grid.jl") # Some defaults -default_free_surface(grid) = SplitExplicitFreeSurface(; cfl=0.7, grid) +default_free_surface(grid) = SplitExplicitFreeSurface(grid; cfl=0.7) function default_ocean_closure() mixing_length = MixingLength(Cᵇ=0.01) From 98bb98e1cc96275df6f7c9d8710303c8da48523e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 21:25:26 -0400 Subject: [PATCH 351/716] chnages --- prototype_omip_simulation/Manifest.toml | 4 +++- prototype_omip_simulation/comparison_to_coare.jl | 4 +++- src/DataWrangling/JRA55.jl | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/prototype_omip_simulation/Manifest.toml b/prototype_omip_simulation/Manifest.toml index 6686a66f..43145043 100644 --- a/prototype_omip_simulation/Manifest.toml +++ b/prototype_omip_simulation/Manifest.toml @@ -1035,7 +1035,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" diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index 0c598a65..2e162ca0 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -59,7 +59,7 @@ matfile = matopen("surface_fluxes.mat", "w") uo = centered_surface_u_velocity(ocean_model.velocities.u) vo = centered_surface_v_velocity(ocean_model.velocities.v) To = Array(interior(ocean_model.tracers.T, :, :, grid.Nz)) -So = Array(interior(ocean_model.tracers.T, :, :, grid.Nz)) +So = Array(interior(ocean_model.tracers.S, :, :, grid.Nz)) write(matfile, "uo", uo) write(matfile, "vo", vo) write(matfile, "To", To) @@ -70,11 +70,13 @@ ua = Array(interior(atmosphere.velocities.u[1], :, :, 1)) va = Array(interior(atmosphere.velocities.v[1], :, :, 1)) Ta = Array(interior(atmosphere.tracers.T[1], :, :, 1)) qa = Array(interior(atmosphere.tracers.q[1], :, :, 1)) +ra = Array(interior(atmosphere.tracers.r[1], :, :, 1)) pa = Array(interior(atmosphere.pressure[1], :, :, 1)) write(matfile, "ua", ua) write(matfile, "va", va) write(matfile, "Ta", Ta) write(matfile, "qa", qa) +write(matfile, "ra", ra) write(matfile, "pa", pa) # Turbulent fluxes diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 2075b794..0efbed39 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -580,6 +580,7 @@ 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...) @@ -594,7 +595,8 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); v = va) tracers = (T = Ta, - q = qa) + q = qa, + r = ra) freshwater_flux = (rain = Fra, snow = Fsn, From ecba76c36c47491ff883156a565031dd04fa62eb Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:29:07 -0400 Subject: [PATCH 352/716] maybe now it works? --- .../ocean_sea_ice_surface_fluxes.jl | 38 ++++++------ .../similarity_theory_turbulent_fluxes.jl | 59 ------------------- 2 files changed, 19 insertions(+), 78 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 34627774..a4e61364 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -230,25 +230,25 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) end # Fallback -@inline convert_to_latlong(i, j, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_latlon_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ @inline convert_to_native_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ # Fallback! limit_fluxes_over_sea_ice!(args...) = nothing @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) + 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) @@ -265,7 +265,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing Sₒ = ocean_state.S[i, j, 1] end - uₒ, vₒ = convert_to_latlong(i, j, grid, uₒ, vₒ) + uₒ, vₒ = convert_to_latlon_grid(i, j, grid, uₒ, vₒ) @inbounds begin # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) @@ -321,12 +321,12 @@ limit_fluxes_over_sea_ice!(args...) = nothing end # Compute initial guess based on previous fluxes - ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) - cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity + # ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) + # cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity - u★ = sqrt(sqrt(τxᵢ^2 + τyᵢ^2)) - θ★ = - Qcᵢ / (ρₐ * cₚ * u★) - q★ = - Fvᵢ / (ρₐ * u★) + u★ = 0 # sqrt(sqrt(τxᵢ^2 + τyᵢ^2)) + θ★ = 0 # - Qcᵢ / (ρₐ * cₚ * u★) + q★ = 0 # - Fvᵢ / (ρₐ * u★) Σ★ = SimilarityScales(u★, θ★, q★) g = default_gravitational_acceleration diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 6ce712c0..d35f4f8a 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -214,12 +214,6 @@ end return (1 - s) / (1 - s + α * s) end -@inline update_turbulent_flux_fields!(::Nothing, args...) = nothing - -@inline function update_turbulent_flux_fields!(fields, i, j, grid, fluxes) - return nothing -end - ##### ##### Struct that represents a 3-tuple of momentum, heat, and water vapor ##### @@ -233,59 +227,6 @@ end # Convenience default with water_vapor component = nothing SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature, nothing) -##### -##### Interface into SurfaceFluxes.jl -##### - -# This is the case that SurfaceFluxes.jl can do -const NothingVaporRoughnessLength = SimilarityScales{<:Number, <:Number, Nothing} - -@inline function compute_similarity_theory_fluxes(roughness_lengths::NothingVaporRoughnessLength, - surface_state, - atmos_state, - thermodynamics_parameters, - gravitational_acceleration, - von_karman_constant, - turbulent_fluxes) - - FT = Float64 - similarity_functions = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), - a_m = convert(FT, 4.7), - a_h = convert(FT, 4.7), - ζ_a = convert(FT, 2.5), - γ = convert(FT, 4.42)) - - turbulent_fluxes = SimilarityTheoryTurbulentFluxes(gravitational_acceleration, - von_karman_constant, - nothing, - similarity_functions, - thermodynamics_parameters, - nothing, - nothing, - nothing, - nothing) - - # Constant roughness lengths - ℓu = roughness_lengths.momentum - ℓθ = roughness_lengths.temperature - - # Solve for the surface fluxes with initial roughness length guess - Uᵍ = zero(ℓu) # gustiness - β = one(ℓu) # surface "resistance" - values = SurfaceFluxes.ValuesOnly(atmos_state, surface_state, ℓu, ℓθ, Uᵍ, β) - conditions = SurfaceFluxes.surface_conditions(turbulent_fluxes, values) - - fluxes = (; - sensible_heat = conditions.shf, - latent_heat = conditions.lhf, - water_vapor = conditions.evaporation, - x_momentum = conditions.ρτxz, - y_momentum = conditions.ρτyz, - ) - - return fluxes -end - ##### ##### Fixed-point iteration for roughness length ##### From c15d95b8cfde43c1c4abbfdc2c9d4d6a21efe0c5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:36:09 -0400 Subject: [PATCH 353/716] try it like this? --- src/OceanSimulations/OceanSimulations.jl | 42 ++++++++++-------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 365af634..6d6aae85 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -36,21 +36,15 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), WENO(; order = 7), Centered()) -@inline ϕ²(i, j, k, grid, ϕ) = @inbounds ϕ[i, j, k]^2 -@inline speedᶠᶜᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.u[i, j, k]^2 + ℑxyᶠᶜᵃ(i, j, k, grid, ϕ², Φ.v)) -@inline speedᶜᶠᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.v[i, j, k]^2 + ℑxyᶜᶠᵃ(i, j, k, grid, ϕ², Φ.u)) +@inline ϕ²(i, j, k, grid, ϕ) = @inbounds ϕ[i, j, k]^2 +@inline spᶠᶜᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.u[i, j, k]^2 + ℑxyᶠᶜᵃ(i, j, k, grid, ϕ², Φ.v)) +@inline spᶜᶠᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.v[i, j, k]^2 + ℑxyᶜᶠᵃ(i, j, k, grid, ϕ², Φ.u)) -@inline u_drag_bc(i, j, grid, clock, Φ, μ) = @inbounds - μ * Φ.u[i, j, 1] * speedᶠᶜᶜ(i, j, 1, grid, Φ) -@inline v_drag_bc(i, j, grid, clock, Φ, μ) = @inbounds - μ * Φ.v[i, j, 1] * speedᶜᶠᶜ(i, j, 1, grid, Φ) +@inline u_quadratic_bottom_drag(i, j, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, 1] * spᶠᶜᶜ(i, j, 1, grid, Φ) +@inline v_quadratic_bottom_drag(i, j, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, 1] * spᶜᶠᶜ(i, j, 1, grid, Φ) -@inline u_immersed_drag_bc(i, j, k, grid, clock, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * speedᶠᶜᶜ(i, j, k, grid, Φ) -@inline v_immersed_drag_bc(i, j, k, grid, clock, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * speedᶜᶠᶜ(i, j, k, grid, Φ) - -default_boundary_conditions(grid; Jᵘ, Jᵛ, Jᵀ, Jˢ, u_bottom_drag, v_bottom_drag, u_immersed_bc, v_immersed_bc) = - (u = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵘ), bottom = u_bottom_drag, immersed = u_immersed_bc), - v = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵛ), bottom = v_bottom_drag, immersed = v_immersed_bc), - T = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵀ)), - S = FieldBoundaryConditions(top = FluxBoundaryCondition(Jˢ))) +@inline u_immersed_quadratic_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * spᶠᶜᶜ(i, j, k, grid, Φ) +@inline v_immersed_quadratic_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) # 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... @@ -71,19 +65,19 @@ function ocean_simulation(grid; Δt = 5minutes, top_ocean_heat_flux = Jᵀ = Field{Center, Center, Nothing}(grid) top_salt_flux = Jˢ = Field{Center, Center, Nothing}(grid) - u_bottom_drag = FluxBoundaryCondition(u_drag_bc, discrete_form=true, parameters=drag_coefficient) - v_bottom_drag = FluxBoundaryCondition(v_drag_bc, discrete_form=true, parameters=drag_coefficient) - u_immersed_drag = FluxBoundaryCondition(u_immersed_drag_bc, discrete_form=true, parameters=drag_coefficient) - v_immersed_drag = FluxBoundaryCondition(v_immersed_drag_bc, discrete_form=true, parameters=drag_coefficient) + u_bot_bc = FluxBoundaryCondition(u_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) + v_bot_bc = FluxBoundaryCondition(v_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) + + u_immersed_bot_bc = FluxBoundaryCondition(u_immersed_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) + v_immersed_bot_bc = FluxBoundaryCondition(v_immersed_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) - u_immersed_bc = ImmersedBoundaryCondition(bottom=u_immersed_drag) - v_immersed_bc = ImmersedBoundaryCondition(bottom=v_immersed_drag) + u_immersed_bc = ImmersedBoundaryCondition(bottom = u_immersed_bot_bc) + v_immersed_bc = ImmersedBoundaryCondition(bottom = v_immersed_bot_bc) - ocean_boundary_conditions = default_boundary_conditions(grid; Jᵘ, Jᵛ, Jᵀ, Jˢ, - u_bottom_drag, - v_bottom_drag, - u_immersed_bc, - v_immersed_bc) + ocean_boundary_conditions = (u = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵘ), bottom = u_bot_bc, immersed = u_immersed_bc), + v = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵛ), bottom = v_bot_bc, immersed = v_immersed_bc), + T = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵀ)), + S = FieldBoundaryConditions(top = FluxBoundaryCondition(Jˢ))) # Use the TEOS10 equation of state teos10 = TEOS10EquationOfState(; reference_density) From 6af635c3d8023cea9672e39b6b1b49db0040326f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:37:36 -0400 Subject: [PATCH 354/716] hail mary! --- .../prototype_omip_simulation.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 49af1da7..4cb6a6f2 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -30,11 +30,11 @@ bathymetry_file = nothing # "bathymetry_tmp.jld2" # 60 vertical levels z_faces = exponential_z_faces(Nz=60, depth=6500) -Nx = 720 -Ny = 300 +Nx = 2160 +Ny = 1100 Nz = length(z_faces) - 1 -arch = CPU() #Distributed(GPU(), partition = Partition(2)) +arch = GPU() #Distributed(GPU(), partition = Partition(2)) grid = TripolarGrid(arch; size = (Nx, Ny, Nz), halo = (7, 7, 7), z = z_faces) @@ -57,7 +57,7 @@ const h = Nz / 4.5 @inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt = 20minutes) -vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = 5e-3) +vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = νz) closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) @@ -72,7 +72,7 @@ set!(model, ##### The atmosphere ##### -backend = JRA55NetCDFBackend(10) +backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation() @@ -137,7 +137,7 @@ ocean.stop_iteration = 1 wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -stop_time = 20days +stop_time = 30days coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) From b5d1ba5bdc32c112d89bb293fc4f34d2ec32301e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:38:58 -0400 Subject: [PATCH 355/716] go now! --- prototype_omip_simulation/prototype_omip_simulation.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 4cb6a6f2..791de761 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -86,9 +86,9 @@ function progress(sim) u, v, w = sim.model.velocities T, S = sim.model.tracers - Tmax = maximum(abs, T) - Tmin = minimum(T) - umax = maximum(abs, u), maximum(abs, v), maximum(abs, w) + Tmax = maximum(interior(T)) + Tmin = minimum(interior(T)) + umax = maximum(interior(u)), maximum(interior(v)), maximum(interior(w)) step_time = 1e-9 * (time_ns() - wall_time[1]) @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", @@ -100,7 +100,7 @@ function progress(sim) wall_time[1] = time_ns() end -ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) +ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) fluxes = (u = model.velocities.u.boundary_conditions.top.condition, v = model.velocities.v.boundary_conditions.top.condition, From c96f7c43158721b549b1cadbbf32475021f29267 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Apr 2024 08:33:02 -0400 Subject: [PATCH 356/716] try with forcing instead of immersed boundary --- src/DataWrangling/JRA55.jl | 30 +++++++++++++++--------- src/OceanSimulations/OceanSimulations.jl | 24 ++++++++++++------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 0efbed39..07f68ac7 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -364,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. @@ -480,24 +480,32 @@ 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] all_Nt = length(all_datetimes) - chunk = last(preprocess_chunk_size) 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, + times = all_times, + path = jld2_filename, + name = fts_name) + while n <= all_Nt print(" ... processing time index $n of $all_Nt \r") @@ -525,7 +533,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 diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 6d6aae85..be4f6721 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -5,6 +5,7 @@ export load_balanced_regional_grid, ocean_simulation using Oceananigans.Units using Oceananigans.Advection: TracerAdvection using Oceananigans.Coriolis: ActiveCellEnstrophyConserving +using Oceananigans.ImmersedBoundaries: immersed_peripheral_node, inactive_node using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity, @@ -46,6 +47,13 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), @inline u_immersed_quadratic_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * spᶠᶜᶜ(i, j, k, grid, Φ) @inline v_immersed_quadratic_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) +@inline is_immersed_drag_u(i, j, k, grid) = Int(immersed_peripheral_node(i, j, k-1, grid, f, c, c) & !inactive_node(i, j, k, grid, f, c, c)) +@inline is_immersed_drag_v(i, j, k, grid) = Int(immersed_peripheral_node(i, j, k-1, grid, c, f, c) & !inactive_node(i, j, k, grid, c, f, c)) + +# Keep a constant linear drag parameter independent on vertical level +@inline u_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.u[i, j, k] * is_immersed_drag_u(i, j, k, grid) * spᶠᶜᶜ(i, j, k, grid, fields) / Δzᵃᵃᶜ(i, j, k, grid) +@inline v_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.v[i, j, k] * is_immersed_drag_v(i, j, k, grid) * spᶜᶠᶜ(i, j, k, grid, fields) / Δzᵃᵃᶜ(i, j, k, grid) + # 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; Δt = 5minutes, @@ -68,17 +76,16 @@ function ocean_simulation(grid; Δt = 5minutes, u_bot_bc = FluxBoundaryCondition(u_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) v_bot_bc = FluxBoundaryCondition(v_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) - u_immersed_bot_bc = FluxBoundaryCondition(u_immersed_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) - v_immersed_bot_bc = FluxBoundaryCondition(v_immersed_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) - - u_immersed_bc = ImmersedBoundaryCondition(bottom = u_immersed_bot_bc) - v_immersed_bc = ImmersedBoundaryCondition(bottom = v_immersed_bot_bc) - - ocean_boundary_conditions = (u = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵘ), bottom = u_bot_bc, immersed = u_immersed_bc), - v = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵛ), bottom = v_bot_bc, immersed = v_immersed_bc), + ocean_boundary_conditions = (u = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵘ), bottom = u_bot_bc), + v = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵛ), bottom = v_bot_bc), T = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵀ)), S = FieldBoundaryConditions(top = FluxBoundaryCondition(Jˢ))) + Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) + Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) + + forcing = (; u = Fu, v = Fv) + # Use the TEOS10 equation of state teos10 = TEOS10EquationOfState(; reference_density) buoyancy = SeawaterBuoyancy(; gravitational_acceleration, equation_of_state=teos10) @@ -106,6 +113,7 @@ function ocean_simulation(grid; Δt = 5minutes, tracers, free_surface, coriolis, + forcing, boundary_conditions = ocean_boundary_conditions) ocean = Simulation(ocean_model; Δt, verbose) From 0ded51b396206ee7c7cbe55ac5a04649d943878e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:33:37 -0400 Subject: [PATCH 357/716] set connected regions to zero --- src/Bathymetry.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index bd92198e..b78c3397 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -265,8 +265,9 @@ function remove_lakes!(h_data; connected_regions_allowed = Inf) batneg = zeros(Bool, size(bathtmp)...) batneg[bathtmp.<0] .= true + connectivity = ImageMorphology.strel_box((3, 3)) - labels = ImageMorphology.label_components(batneg) + labels = ImageMorphology.label_components(batneg, connectivity) total_elements = zeros(maximum(labels)) label_elements = zeros(maximum(labels)) From ca5458f0c0884a1eab00852a9e7619515afa0076 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:07:03 -0400 Subject: [PATCH 358/716] remove small lakes? --- src/Bathymetry.jl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index b78c3397..3b75d4d3 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -265,9 +265,9 @@ function remove_lakes!(h_data; connected_regions_allowed = Inf) batneg = zeros(Bool, size(bathtmp)...) batneg[bathtmp.<0] .= true - connectivity = ImageMorphology.strel_box((3, 3)) - - labels = ImageMorphology.label_components(batneg, connectivity) + + connectivity = ImageMorphology.strel(batneg) + labels = ImageMorphology.label_components(connectivity) total_elements = zeros(maximum(labels)) label_elements = zeros(maximum(labels)) @@ -305,6 +305,10 @@ function remove_lakes!(h_data; connected_regions_allowed = Inf) bathtmp .+= labels bathtmp[isnan.(bathtmp)] .= 0 + batneg = zeros(Bool, size(bathtmp)...) + + batneg[bathtmp.<0] .= true + return bathtmp end From 6eaebfcd4ba541d055ba081645d468b1864fc5ff Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:42:22 -0400 Subject: [PATCH 359/716] let's go with connected regions! --- src/Bathymetry.jl | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 3b75d4d3..2d7c6ac6 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -254,6 +254,15 @@ other possibly disconnected regions like the Mediterranean and the Bering sea). Default is `Inf`, which means all connected regions are kept. """ +function remove_lakes!(h_data::Field; kw...) + data = Array(interior(h_data, :, :, 1)) + data = remove_lakes!(data; kw...) + + set!(h_data, data) + + return h_data +end + function remove_lakes!(h_data; connected_regions_allowed = Inf) if connected_regions_allowed == Inf @@ -273,7 +282,7 @@ function remove_lakes!(h_data; connected_regions_allowed = Inf) label_elements = zeros(maximum(labels)) for i in 1:lastindex(total_elements) - total_elements[i] = sum(labels[labels .== i]) + total_elements[i] = length(labels[labels .== i]) label_elements[i] = i end @@ -295,20 +304,17 @@ function remove_lakes!(h_data; connected_regions_allowed = Inf) for i in 1:maximum(labels) remove_lake = (&).(Tuple(i != idx for idx in all_idx)...) if remove_lake - labels[labels .== i] .= NaN + labels[labels .== i] .= 1e10 # Fictitious super large number end end # Removing land? - labels[labels.==0] .= NaN + labels[labels .< 1e10] .= 0 + labels[labels .== 1e10] .= NaN bathtmp .+= labels bathtmp[isnan.(bathtmp)] .= 0 - batneg = zeros(Bool, size(bathtmp)...) - - batneg[bathtmp.<0] .= true - return bathtmp end From 1a545ff6977c4d59a2559788ce02dbecbf7f184e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 17:52:20 -0400 Subject: [PATCH 360/716] Let's go! --- .../CrossRealmFluxes/CrossRealmFluxes.jl | 17 +- .../latitude_dependent_albedo.jl | 131 +++++++++ .../ocean_sea_ice_surface_fluxes.jl | 31 +- .../CrossRealmFluxes/radiation.jl | 6 +- .../similarity_theory_turbulent_fluxes.jl | 266 +++++++++++------- .../PrescribedAtmospheres.jl | 6 +- src/OceanSimulations/OceanSimulations.jl | 7 +- 7 files changed, 332 insertions(+), 132 deletions(-) create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index e8c673c8..733f9edc 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -14,20 +14,20 @@ import ..OceanSeaIceModels: surface_velocities, ##### 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 stateindex(a::Number, i, j, k, grid, time) = a +@inline stateindex(a::SKOFTS, i, j, k, grid, time) = @inbounds a[i, j, k, time] +@inline stateindex(a::AbstractArray, i, j, k, grid, time) = @inbounds a[i, j, k] +@inline Δϕt²(i, j, k, grid, ϕ1, ϕ2, time) = (stateindex(ϕ1, i, j, k, grid, time) - stateindex(ϕ2, i, j, k, grid, time))^2 -@inline function stateindex(a::Tuple, i, j, k, time) +@inline function stateindex(a::Tuple, i, j, k, grid, time) N = length(a) ntuple(Val(N)) do n - stateindex(a[n], i, j, k, time) + stateindex(a[n], i, j, k, grid, time) end end -@inline function stateindex(a::NamedTuple, i, j, k, time) - vals = stateindex(values(a), i, j, k, time) +@inline function stateindex(a::NamedTuple, i, j, k, grid, time) + vals = stateindex(values(a), i, j, k, grid, time) names = keys(a) return NamedTuple{names}(vals) end @@ -61,6 +61,7 @@ end include("three_dimensional_operators.jl") include("radiation.jl") +include("latitude_dependent_albedo.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") include("sea_ice_ocean_fluxes.jl") diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl new file mode 100644 index 00000000..a02e5f84 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl @@ -0,0 +1,131 @@ +using Oceananigans.Fields: interpolator +using Oceananigans.Grids: on_architecture + +using ClimaOcean.OceanSeaIceModels: + PrescribedAtmosphere, + TwoStreamDownwellingRadiation + +# Bilinear interpolation of the albedo α in α_table based on a +# transmissivity value (𝓉_values) and latitude (φ_values) +struct TabulatedAlbedo{M, A, FT} + α_table :: M + φ_values :: A + 𝓉_values :: A + S₀ :: FT # Solar constant W / m^2 +end + +# Tabulated from Payne (1972) https://doi.org/10.1175/1520-0469(1972)029<0959:AOTSS>2.0.CO;2 +const α_payne = [ 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.06 + 0.062 0.062 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.06 + 0.072 0.070 0.068 0.065 0.065 0.063 0.062 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.060 0.061 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.06 + 0.087 0.083 0.079 0.073 0.070 0.068 0.066 0.065 0.064 0.063 0.062 0.061 0.061 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.06 + 0.115 0.108 0.098 0.086 0.082 0.077 0.072 0.071 0.067 0.067 0.065 0.063 0.062 0.061 0.061 0.060 0.060 0.060 0.060 0.061 0.061 0.061 0.061 0.060 0.059 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.060 0.059 0.059 0.05 + 0.163 0.145 0.130 0.110 0.101 0.092 0.084 0.079 0.072 0.072 0.068 0.067 0.064 0.063 0.062 0.061 0.061 0.061 0.060 0.060 0.060 0.060 0.060 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.05 + 0.235 0.198 0.174 0.150 0.131 0.114 0.103 0.094 0.083 0.080 0.074 0.074 0.070 0.067 0.065 0.064 0.063 0.062 0.061 0.060 0.060 0.060 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.058 0.058 0.05 + 0.318 0.263 0.228 0.192 0.168 0.143 0.127 0.113 0.099 0.092 0.084 0.082 0.076 0.072 0.070 0.067 0.065 0.064 0.062 0.062 0.060 0.060 0.060 0.059 0.059 0.059 0.059 0.059 0.059 0.059 0.058 0.058 0.058 0.058 0.058 0.058 0.058 0.058 0.057 0.058 0.058 0.058 0.058 0.057 0.057 0.05 + 0.395 0.336 0.290 0.248 0.208 0.176 0.151 0.134 0.117 0.107 0.097 0.091 0.085 0.079 0.075 0.071 0.068 0.067 0.065 0.063 0.062 0.061 0.060 0.060 0.060 0.059 0.059 0.058 0.058 0.058 0.057 0.057 0.057 0.057 0.057 0.057 0.057 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.056 0.05 + 0.472 0.415 0.357 0.306 0.252 0.210 0.176 0.154 0.135 0.125 0.111 0.102 0.094 0.086 0.081 0.076 0.072 0.071 0.068 0.066 0.065 0.063 0.062 0.061 0.060 0.059 0.058 0.057 0.057 0.057 0.056 0.055 0.055 0.055 0.055 0.055 0.055 0.054 0.053 0.054 0.053 0.053 0.054 0.054 0.053 0.05 + 0.542 0.487 0.424 0.360 0.295 0.242 0.198 0.173 0.150 0.136 0.121 0.110 0.101 0.093 0.086 0.081 0.076 0.073 0.069 0.067 0.065 0.064 0.062 0.060 0.059 0.058 0.057 0.056 0.055 0.055 0.054 0.053 0.053 0.052 0.052 0.052 0.051 0.051 0.050 0.050 0.050 0.050 0.051 0.050 0.050 0.05 + 0.604 0.547 0.498 0.407 0.331 0.272 0.219 0.185 0.160 0.141 0.127 0.116 0.105 0.097 0.089 0.083 0.077 0.074 0.069 0.066 0.063 0.061 0.059 0.057 0.056 0.055 0.054 0.053 0.053 0.052 0.051 0.050 0.050 0.049 0.049 0.049 0.048 0.047 0.047 0.047 0.046 0.046 0.047 0.047 0.046 0.04 + 0.655 0.595 0.556 0.444 0.358 0.288 0.236 0.190 0.164 0.145 0.130 0.119 0.107 0.098 0.090 0.084 0.076 0.073 0.068 0.064 0.060 0.058 0.056 0.054 0.053 0.051 0.050 0.049 0.048 0.048 0.047 0.046 0.046 0.045 0.045 0.045 0.044 0.043 0.043 0.043 0.042 0.042 0.043 0.042 0.042 0.04 + 0.693 0.631 0.588 0.469 0.375 0.296 0.245 0.193 0.165 0.145 0.131 0.118 0.106 0.097 0.088 0.081 0.074 0.069 0.065 0.061 0.057 0.055 0.052 0.050 0.049 0.047 0.046 0.046 0.044 0.044 0.043 0.042 0.042 0.041 0.041 0.040 0.040 0.039 0.039 0.039 0.038 0.038 0.038 0.038 0.038 0.03 + 0.719 0.656 0.603 0.480 0.385 0.300 0.250 0.193 0.164 0.145 0.131 0.116 0.103 0.092 0.084 0.076 0.071 0.065 0.061 0.057 0.054 0.051 0.049 0.047 0.045 0.043 0.043 0.042 0.041 0.040 0.039 0.039 0.038 0.038 0.037 0.036 0.036 0.035 0.035 0.034 0.034 0.034 0.034 0.034 0.034 0.03 + 0.732 0.670 0.592 0.474 0.377 0.291 0.246 0.190 0.162 0.144 0.130 0.114 0.100 0.088 0.080 0.072 0.067 0.062 0.058 0.054 0.050 0.047 0.045 0.043 0.041 0.039 0.039 0.038 0.037 0.036 0.036 0.035 0.035 0.034 0.033 0.032 0.032 0.032 0.031 0.031 0.031 0.030 0.030 0.030 0.030 0.03 + 0.730 0.652 0.556 0.444 0.356 0.273 0.235 0.188 0.160 0.143 0.129 0.113 0.097 0.086 0.077 0.069 0.064 0.060 0.055 0.051 0.047 0.044 0.042 0.039 0.037 0.035 0.035 0.035 0.034 0.033 0.033 0.032 0.032 0.032 0.029 0.029 0.029 0.029 0.028 0.028 0.028 0.028 0.027 0.027 0.028 0.02 + 0.681 0.602 0.488 0.386 0.320 0.252 0.222 0.185 0.159 0.142 0.127 0.111 0.096 0.084 0.075 0.067 0.062 0.058 0.054 0.050 0.046 0.042 0.040 0.036 0.035 0.033 0.032 0.032 0.031 0.030 0.030 0.030 0.030 0.029 0.027 0.027 0.027 0.027 0.026 0.026 0.026 0.026 0.026 0.026 0.026 0.02 + 0.581 0.494 0.393 0.333 0.288 0.237 0.211 0.182 0.158 0.141 0.126 0.110 0.095 0.083 0.074 0.066 0.061 0.057 0.053 0.049 0.045 0.041 0.039 0.034 0.033 0.032 0.031 0.030 0.029 0.028 0.028 0.028 0.028 0.027 0.026 0.026 0.026 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.02 + 0.453 0.398 0.342 0.301 0.266 0.226 0.205 0.180 0.157 0.140 0.125 0.109 0.095 0.083 0.074 0.065 0.061 0.057 0.052 0.048 0.044 0.040 0.038 0.033 0.032 0.031 0.030 0.029 0.028 0.027 0.027 0.026 0.026 0.026 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.02 + 0.425 0.370 0.325 0.290 0.255 0.220 0.200 0.178 0.157 0.140 0.122 0.108 0.095 0.083 0.074 0.065 0.061 0.056 0.052 0.048 0.044 0.040 0.038 0.033 0.032 0.031 0.030 0.029 0.028 0.027 0.026 0.026 0.026 0.026 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.02] + +function TabulatedAlbedo(arch = CPU(), FT = Float64; + S₀ = convert(FT, 1365), + α_table = α_payne, + φ_values = (0:2:90) ./ 180 * π, + 𝓉_values = 0:0.05:1) + + # Make everything GPU - ready + α_table = on_architecture(arch, α_table) + φ_values = on_architecture(arch, φ_values) + 𝓉_values = on_architecture(arch, 𝓉_values) + + return TabulatedAlbedo(α_table, φ_values, 𝓉_values, S₀) +end + +@inline ϕ₁(ξ, η) = (1 - ξ) * (1 - η) +@inline ϕ₂(ξ, η) = (1 - ξ) * η +@inline ϕ₃(ξ, η) = ξ * (1 - η) +@inline ϕ₄(ξ, η) = ξ * η + +# To allow the use with KernelFunctionOperation +@inline function net_downwelling_radiation(i, j, k, grid, time, + atmos_radiation::TwoStreamDownwellingRadiation, + atmos_grid, + atmos_times, + atmos_backend, + atmos_time_indexing, + radiative_properties) + + X = node(i, j, 1, grid, c, c, f) + + atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) + + Qs = interp_atmos_time_series(atmos_radiation.shortwave, X, time, atmos_args...) + Qℓ = interp_atmos_time_series(atmos_radiation.longwave, X, time, atmos_args...) + + return net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiative_properties) +end + +@inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}) + α = radiation.reflection.ocean + + λ, φ, z = node(i, j, 1, grid, Center(), Center(), Center()) + + φ = deg2rad(φ) + λ = deg2rad(λ) + time = time.time + + day = time ÷ 86400 + day2rad = 2π / 86400 + + noon_in_sec = 86400 ÷ 2 + sec_of_day = time - day * 86400 + + # Hour angle h + h = (sec_of_day - noon_in_sec) * day2rad + λ + + # Declination angle δ + march_first = 80.0 + δ = deg2rad((23 + 27/60) * sind(360 * (day - march_first) / 365.25)) + + # Zenith angle of the sun (if smaller than 0 we are in the dark) + cosθₛ = max(0, sin(φ) * sin(δ) + cos(h) * cos(δ) * cos(φ)) + + # Maximum downwelling solar radiation for + # a transparent atmosphere + Qmax = α.S₀ * cosθₛ + + # Finding the transmissivity and capping it to 1 + 𝓉 = ifelse(Qmax > 0, min(1, Qs / Qmax), 0) + + # finding the i-index in the table (depending on transmissivity) + # assuming the transmissivity is tabulated with constant values + 𝓉₁ = @inbounds α.𝓉_values[1] + Δ𝓉 = @inbounds α.𝓉_values[2] - 𝓉₁ + i⁻, i⁺, ξ = interpolator((𝓉 - 𝓉₁) / Δ𝓉) + + # finding the i-index in the table (depending on latitude) + # assuming the transmissivity is tabulated with constant values + φ₁ = @inbounds α.φ_values[1] + Δφ = @inbounds α.φ_values[2] - φ₁ + j⁻, j⁺, η = interpolator((abs(φ) - φ₁) / Δφ) + + # Bilinear interpolation! + α = @inbounds ϕ₁(ξ, η) * getindex(α.α_table, i⁻, j⁻) + + ϕ₂(ξ, η) * getindex(α.α_table, i⁻, j⁺) + + ϕ₃(ξ, η) * getindex(α.α_table, i⁺, j⁻) + + ϕ₄(ξ, η) * getindex(α.α_table, i⁺, j⁺) + + ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) + + return α +end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index a4e61364..010a9dcb 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -195,7 +195,8 @@ 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.similarity_functions) launch!(arch, grid, kernel_parameters, _assemble_atmosphere_ocean_fluxes!, centered_velocity_fluxes, @@ -248,7 +249,8 @@ limit_fluxes_over_sea_ice!(args...) = nothing atmos_time_indexing, atmosphere_reference_height, atmos_thermodynamics_parameters, - roughness_lengths) + roughness_lengths, + similarity_functions) i, j = @index(Global, NTuple) kᴺ = size(grid, 3) @@ -265,6 +267,9 @@ limit_fluxes_over_sea_ice!(args...) = nothing Sₒ = ocean_state.S[i, j, 1] end + # Convert the native grid velocities to a zonal - meridional + # frame of reference (assuming the frame of reference is + # latitude - longitude here, we might want to change it) uₒ, vₒ = convert_to_latlon_grid(i, j, grid, uₒ, vₒ) @inbounds begin @@ -321,24 +326,28 @@ limit_fluxes_over_sea_ice!(args...) = nothing end # Compute initial guess based on previous fluxes - # ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) - # cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity + ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) + cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity - u★ = 0 # sqrt(sqrt(τxᵢ^2 + τyᵢ^2)) - θ★ = 0 # - Qcᵢ / (ρₐ * cₚ * u★) - q★ = 0 # - Fvᵢ / (ρₐ * u★) + u★ = sqrt(sqrt(τxᵢ^2 + τyᵢ^2)) + u★ = ifelse(u★ == 0, 1e-2, u★) + θ★ = - Qcᵢ / (ρₐ * cₚ * u★) + q★ = - Fvᵢ / (ρₐ * u★) Σ★ = SimilarityScales(u★, θ★, q★) g = default_gravitational_acceleration ϰ = 0.4 - + turbulent_fluxes = compute_similarity_theory_fluxes(roughness_lengths, + similarity_functions, dynamic_ocean_state, dynamic_atmos_state, ℂₐ, g, ϰ, Σ★) kᴺ = size(grid, 3) # index of the top ocean cell + # Convert back from a zonal - meridional flux to the frame of + # reference of the native ocean grid τˣ, τʸ = convert_to_native_grid(i, j, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) @@ -453,15 +462,15 @@ end @inline net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, ::Nothing) = zero(0) @inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) - α = stateindex(radiation.reflection.ocean, i, j, 1, time) - ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) + α = stateindex(radiation.reflection.ocean, i, j, 1, grid, time) + ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) return @inbounds - (1 - α) * Qs - ϵ * Qℓ end @inline function net_upwelling_radiation(i, j, grid, time, radiation, Tₒ) σ = radiation.stefan_boltzmann_constant - ϵ = stateindex(radiation.emission.ocean, i, j, 1, time) + ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) # Note: positive implies _upward_ heat flux, and therefore cooling. return ϵ * σ * Tₒ^4 diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index f9ca57be..26789041 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -4,10 +4,10 @@ struct Radiation{FT, E, R} stefan_boltzmann_constant :: FT end -function Radiation(FT=Float64; +function Radiation(arch = CPU(), FT=Float64; ocean_emissivity = 0.97, sea_ice_emissivity = 1.0, - ocean_albedo = 0.3, + ocean_albedo = TabulatedAlbedo(arch, FT), sea_ice_albedo = 0.7, stefan_boltzmann_constant = 5.67e-8) @@ -25,7 +25,7 @@ function Radiation(FT=Float64; end Base.summary(r::Radiation) = "Radiation" -Base.show(io::IO, r::Radiation) = print(io, summary(osf)) +Base.show(io::IO, r::Radiation) = print(io, summary(r)) struct SurfaceProperties{O, I} ocean :: O diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index d35f4f8a..80573cc9 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -12,6 +12,8 @@ using KernelAbstractions.Extras.LoopInfo: @unroll using ..PrescribedAtmospheres: PrescribedAtmosphereThermodynamicsParameters +using Statistics: norm + import Thermodynamics as AtmosphericThermodynamics import Thermodynamics.Parameters: molmass_ratio @@ -93,9 +95,9 @@ function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) end function default_roughness_lengths(FT=Float64) - momentum = convert(FT, 1e-4) #GravityWaveRoughnessLength(FT) - temperature = convert(FT, 1e-4) - water_vapor = convert(FT, 1e-4) + momentum = GravityWaveRoughnessLength(FT) + temperature = GravityWaveRoughnessLength(FT) + water_vapor = GravityWaveRoughnessLength(FT) return SimilarityScales(momentum, temperature, water_vapor) end @@ -135,13 +137,6 @@ function SimilarityTheoryTurbulentFluxes(grid::AbstractGrid; kw...) return SimilarityTheoryTurbulentFluxes(eltype(grid); kw..., fields) end -# See SurfaceFluxes.jl for other parameter set options. -default_businger_parameters(FT=Float64) = BusingerParams{FT}(Pr_0 = convert(FT, 0.74), - a_m = convert(FT, 4.7), - a_h = convert(FT, 4.7), - ζ_a = convert(FT, 2.5), - γ = convert(FT, 4.42)) - @inline function seawater_saturation_specific_humidity(atmosphere_thermodynamics_parameters, surface_temperature, surface_salinity, @@ -231,26 +226,110 @@ SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature ##### Fixed-point iteration for roughness length ##### -const ConstantRoughnessLength = SimilarityScales{<:Number, <:Number, <:Number} +@inline function compute_similarity_theory_fluxes(roughness_lengths, + similarity_functions, + surface_state, + atmos_state, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant, + Σ₀ = SimilarityScales(1e-3, 1e-3, 1e-3)) + + # Prescribed difference between two states + ℂₐ = thermodynamics_parameters + Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, surface_state) + differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) + + # Solve for the characteristic scales u★, θ★, q★, and thus for fluxes. + Σ★ = Σ₀ + + for _ in 1:10 + Σ★ = refine_characteristic_scales(Σ★, + roughness_lengths, + similarity_functions, + surface_state, + differences, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) + end -struct SimilarityFunction{FT, C} + 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 = (; + sensible_heat = - ρₐ * cₚ * u★ * θ★, + latent_heat = - ρₐ * u★ * q★ * ℰv, + water_vapor = - ρₐ * u★ * q★, + x_momentum = + ρₐ * τx, + y_momentum = + ρₐ * τy, + ) + + return fluxes +end + +struct Momentum end +struct Scalar end + +struct SimilarityFunction{M, FT, C} a :: FT b :: FT c :: C + + SimilarityFunction{M}(a::FT, b::FT, c::C) where {M, FT, C} = new{M, FT, C}(a, b, c) +end + +Adapt.adapt_structure(to, ψ::SimilarityFunction{M}) where M = SimilarityFunction{M}(ψ.a, ψ.b, ψ.c) + +function businger_similarity_functions(FT = Float64) + + # Computed from Businger et al. (1971) + ψu = SimilarityFunction{Momentum}(4.7, 15.0, OneQuarter()) + ψc = SimilarityFunction{Scalar}(6.35, 9.0, OneHalf()) + + return SimilarityScales(ψu, ψc, ψc) end -@inline function (ψ::SimilarityFunction)(Ri) +# This seems to come from "SURFACE FLUXES FOR PRACTITIONERS OF GLOBAL OCEAN DATA ASSIMILATION" +# Of William Large, but a couple of coefficients and signs are off. +# Also in that paper momentum and scalar stability functions are different, here they are the same?? +# Fairell et al implement a different formulation with a "convective" and "stable" stability function +@inline function (ψ::SimilarityFunction{<:Momentum})(ζ) 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 + ζ⁻ = min(zero(ζ), ζ) + fₘ = (1 - b * ζ⁻)^c - ψ_stable = - a * Ri + ψ_unstable = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2 + ψ_stable = - a * ζ - return ifelse(Ri < 0, ψ_unstable, ψ_stable) + return ifelse(ζ < 0, ψ_unstable, ψ_stable) +end + +@inline function (ψ::SimilarityFunction{<:Scalar})(ζ) + a = ψ.a + b = ψ.b + c = ψ.c + + ζ⁻ = min(zero(ζ), ζ) + fₕ = (1 - b * ζ⁻)^c + + ψ_unstable = 2 * log((1 + fₕ^2) / 2) + ψ_stable = - a * ζ + + return ifelse(ζ < 0, ψ_unstable, ψ_stable) end struct OneQuarter end @@ -260,36 +339,31 @@ 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) +@inline function bulk_factor(ψ, h, ℓ, L★) - ψq = ψh + # Non-dimensional height in Obukhov length units + ζ = ifelse(L★ == 0, zero(h), h / L★) - return SimilarityScales(ψu, ψh, ψq) -end + # Non-dimensional roughness height in Obukhov length units + ζᵣ = ifelse(L★ == 0, zero(h), ℓ / L★) -@inline function bulk_factor(ψ, h, ℓ, Ri) - L★ = h / Ri - χ⁻¹ = log(h / ℓ) - ψ(Ri) + ψ(ℓ / L★) - return 1 / χ⁻¹ + χ⁻¹ = log(h / ℓ) - ψ(ζ) + ψ(ζᵣ) + + return ifelse(χ⁻¹ == 0, zero(h), 1 / χ⁻¹) end +# The M-O characteristic length is calculated as +# L★ = - u★² / (κ ⋅ b★) +# where b★ is the characteristic buoyancy scale calculated from this function @inline function buoyancy_scale(θ★, q★, 𝒬, ℂ, g) 𝒯₀ = AtmosphericThermodynamics.virtual_temperature(ℂ, 𝒬) θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬) ε = AtmosphericThermodynamics.Parameters.molmass_ratio(ℂ) - δ = ε - 1 + δ = ε - 1 # typically equal to 0.608 + # Where does this come from? Probably Fairell et al. 1996, b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * θ₀ * q★) return b★ @@ -323,61 +397,17 @@ end 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, - Σ₀ = SimilarityScales(1e-3, 1e-3, 1e-3)) - - # Prescribed difference between two states - ℂₐ = thermodynamics_parameters - Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, surface_state) - differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) - - # Solve for the characteristic scales u★, θ★, q★, and thus for fluxes. - Σ★ = Σ₀ - - @unroll for iter = 1:10 - Σ★ = refine_characteristic_scales(Σ★, - roughness_lengths, - surface_state, - differences, - thermodynamics_parameters, - gravitational_acceleration, - von_karman_constant) - end - - u★ = Σ★.momentum - θ★ = Σ★.temperature - q★ = Σ★.water_vapor - - # u★² ≡ sqrt(τx² + τy²) - τx = - u★^2 * Δu / sqrt(Δu^2 + Δv^2) - τy = - u★^2 * Δv / sqrt(Δu^2 + Δv^2) +@inline momentum_roughness_length(ℓ, Σ★) = ℓ(Σ★) +@inline water_vapor_roughness_length(ℓ, ℓu, Σ★) = ℓ(Σ★) +@inline temperature_roughness_length(ℓ, ℓq, Σ★) = ℓ(Σ★) - 𝒬ₐ = atmos_state.ts - ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) - cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity - ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) - - fluxes = (; - sensible_heat = - ρₐ * cₚ * u★ * θ★, - latent_heat = - ρₐ * u★ * q★ * ℰv, - water_vapor = - ρₐ * u★ * q★, - x_momentum = + ρₐ * τx, - y_momentum = + ρₐ * τy, - ) - - return fluxes -end - -@inline compute_roughness_length(ℓ::Number, Σ★) = ℓ -@inline compute_roughness_length(ℓ, Σ★) = ℓ(Σ★) +@inline momentum_roughness_length(ℓ::Number, Σ★) = ℓ +@inline water_vapor_roughness_length(ℓ::Number, ℓu, Σ★) = ℓ +@inline temperature_roughness_length(ℓ::Number, ℓq, Σ★) = ℓ @inline function refine_characteristic_scales(estimated_characteristic_scales, roughness_lengths, + similarity_functions, surface_state, differences, thermodynamics_parameters, @@ -390,40 +420,43 @@ end q★ = estimated_characteristic_scales.water_vapor Σ★ = estimated_characteristic_scales + # Similarity functions from Businger et al. (1971) + ψu = similarity_functions.momentum + ψθ = similarity_functions.temperature + ψq = similarity_functions.water_vapor + # 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 + # Compute Monin-Obukhov length scale h = differences.h ϰ = von_karman_constant + ℓu₀ = momentum_roughness_length(ℓu, h, Σ★) + ℓq₀ = water_vapor_roughness_length(ℓq, h, Σ★) + ℓθ₀ = temperature_roughness_length(ℓθ, h, Σ★) + ℂ = thermodynamics_parameters g = gravitational_acceleration - 𝒬ₒ = surface_state.ts # thermodyanmic state + 𝒬ₒ = surface_state.ts # thermodynamic state b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, ℂ, g) - Riₕ = - ϰ * h * b★ / u★^2 - Riₕ = ifelse(isnan(Riₕ), zero(Riₕ), Riₕ) - # Compute similarity functions - ψu = SimilarityFunction(4.7, 15.0, OneQuarter()) - ψc = SimilarityFunction(6.35, 9.0, OneHalf()) + # Monin-Obhukov characteristic length + L★ = ifelse(b★ == 0, zero(b★), - u★^2 / (ϰ * b★)) - χ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₀, L★) + χθ = bulk_factor(ψθ, h, ℓθ₀, L★) + χq = bulk_factor(ψq, h, ℓq₀, L★) Δu = differences.u Δv = differences.v Δθ = differences.θ Δq = differences.q - u★ = ϰ * χu * sqrt(Δu^2 + Δv^2) + # Maybe we should add gustiness here? + u★ = ϰ * χu * sqrt(Δu^2 + Δv^2) θ★ = ϰ * χθ * Δθ q★ = ϰ * χq * Δq @@ -449,12 +482,37 @@ function GravityWaveRoughnessLength(FT=Float64; convert(FT, laminar_parameter)) end -@inline function compute_roughness_length(ℓ::GravityWaveRoughnessLength, Σ★) +# Momentum roughness length should be different from scalar roughness length. +# Apparently temperature and water vapor can be considered the same (Edison et al 2013) +@inline function momentum_roughness_length(ℓ::GravityWaveRoughnessLength{FT}, h, Σ★) where FT u★ = Σ★.momentum g = ℓ.gravitational_acceleration ν = ℓ.air_kinematic_viscosity α = ℓ.gravity_wave_parameter β = ℓ.laminar_parameter - return α * u★^2 / g + β * ν / u★ + # We need to prevent `Inf` that pops up when `u★ == 0`. + # However, if we leave `z₀ᴿ == 0` we will have a non-ending zero loop + # For this reason, if `u★ == 0` we prescribe the roughness length to be + # equal to `1e-4` as an initial guess + z₀ᴿ = ifelse(u★ == 0, convert(FT, 1.5e-4), β * ν / u★) + + return min(α * u★^2 / g + z₀ᴿ, h / 2) end + +@inline water_vapor_roughness_length(ℓ, h, Σ★) = momentum_roughness_length(ℓ, h, Σ★) +@inline temperature_roughness_length(ℓ, h, Σ★) = momentum_roughness_length(ℓ, h, Σ★) + +# This, for example is what is implemented in COARE 3.6 +# @inline function water_vapor_roughness_length(ℓ::GravityWaveRoughnessLength{FT}, ℓu, Σ★) where FT +# u★ = Σ★.momentum +# ν = ℓ.air_kinematic_viscosity + +# r = ℓu * u★ / ν +# ℓq = ifelse(r == 0, 1e-4, 5.8e-5 / r ^ 0.72) + +# return min(1.6e-4, ℓq); +# end + +# @inline temperature_roughness_length(ℓ::GravityWaveRoughnessLength, ℓq, Σ★) = ℓq + diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 3e738589..0a845024 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -210,9 +210,9 @@ end const PATP{FT} = PrescribedAtmosphereThermodynamicsParameters{FT} where FT Base.eltype(::PATP{FT}) where FT = FT -Base.eltype(::CP{FT}) where FT = FT -Base.eltype(::HCP{FT}) where FT = FT -Base.eltype(::PTP{FT}) where FT = FT +Base.eltype(::CP{FT}) where FT = FT +Base.eltype(::HCP{FT}) where FT = FT +Base.eltype(::PTP{FT}) where FT = FT Base.summary(::PATP{FT}) where FT = "PrescribedAtmosphereThermodynamicsParameters{$FT}" diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index be4f6721..40d2a1c0 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -3,9 +3,10 @@ module OceanSimulations export load_balanced_regional_grid, ocean_simulation using Oceananigans.Units +using Oceananigans.Operators using Oceananigans.Advection: TracerAdvection using Oceananigans.Coriolis: ActiveCellEnstrophyConserving -using Oceananigans.ImmersedBoundaries: immersed_peripheral_node, inactive_node +using Oceananigans.ImmersedBoundaries: immersed_peripheral_node, inactive_node, c, f using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity, @@ -51,8 +52,8 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), @inline is_immersed_drag_v(i, j, k, grid) = Int(immersed_peripheral_node(i, j, k-1, grid, c, f, c) & !inactive_node(i, j, k, grid, c, f, c)) # Keep a constant linear drag parameter independent on vertical level -@inline u_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.u[i, j, k] * is_immersed_drag_u(i, j, k, grid) * spᶠᶜᶜ(i, j, k, grid, fields) / Δzᵃᵃᶜ(i, j, k, grid) -@inline v_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.v[i, j, k] * is_immersed_drag_v(i, j, k, grid) * spᶜᶠᶜ(i, j, k, grid, fields) / Δzᵃᵃᶜ(i, j, k, grid) +@inline u_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.u[i, j, k] * is_immersed_drag_u(i, j, k, grid) * spᶠᶜᶜ(i, j, k, grid, fields) / Δzᶠᶜᶜ(i, j, k, grid) +@inline v_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.v[i, j, k] * is_immersed_drag_v(i, j, k, grid) * spᶜᶠᶜ(i, j, k, grid, fields) / Δzᶜᶠᶜ(i, j, k, grid) # 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... From 79410a49466dd8d77e17d274f61f9bcd1bf229a4 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 18:13:58 -0400 Subject: [PATCH 361/716] should be ready to run? --- .../latitude_dependent_albedo.jl | 21 +---- .../CrossRealmFluxes/radiation.jl | 19 +++++ .../similarity_theory_turbulent_fluxes.jl | 80 ++++++++++++------- 3 files changed, 72 insertions(+), 48 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl index a02e5f84..98196a79 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl @@ -56,25 +56,6 @@ end @inline ϕ₃(ξ, η) = ξ * (1 - η) @inline ϕ₄(ξ, η) = ξ * η -# To allow the use with KernelFunctionOperation -@inline function net_downwelling_radiation(i, j, k, grid, time, - atmos_radiation::TwoStreamDownwellingRadiation, - atmos_grid, - atmos_times, - atmos_backend, - atmos_time_indexing, - radiative_properties) - - X = node(i, j, 1, grid, c, c, f) - - atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) - - Qs = interp_atmos_time_series(atmos_radiation.shortwave, X, time, atmos_args...) - Qℓ = interp_atmos_time_series(atmos_radiation.longwave, X, time, atmos_args...) - - return net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiative_properties) -end - @inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}) α = radiation.reflection.ocean @@ -127,5 +108,5 @@ end ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) - return α + return - (1 - α) * Qs - ε * Qℓ end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index 26789041..6bc81bae 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -27,6 +27,25 @@ end Base.summary(r::Radiation) = "Radiation" Base.show(io::IO, r::Radiation) = print(io, summary(r)) +# To allow the use with KernelFunctionOperation +@inline function net_downwelling_radiation(i, j, k, grid, time, + atmos_radiation, + atmos_grid, + atmos_times, + atmos_backend, + atmos_time_indexing, + radiative_properties) + + X = node(i, j, 1, grid, c, c, f) + + atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) + + Qs = interp_atmos_time_series(atmos_radiation.shortwave, X, time, atmos_args...) + Qℓ = interp_atmos_time_series(atmos_radiation.longwave, X, time, atmos_args...) + + return net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiative_properties) +end + struct SurfaceProperties{O, I} ocean :: O sea_ice :: I diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 80573cc9..13161f35 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -95,9 +95,9 @@ function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) end function default_roughness_lengths(FT=Float64) - momentum = GravityWaveRoughnessLength(FT) - temperature = GravityWaveRoughnessLength(FT) - water_vapor = GravityWaveRoughnessLength(FT) + momentum = GravityMomentumRoughnessLength(FT) + temperature = GravityScalarRoughnessLength(FT) + water_vapor = GravityScalarRoughnessLength(FT) return SimilarityScales(momentum, temperature, water_vapor) end @@ -434,7 +434,7 @@ end h = differences.h ϰ = von_karman_constant - ℓu₀ = momentum_roughness_length(ℓu, h, Σ★) + ℓu₀ = momentum_roughness_length(ℓu, Σ★) ℓq₀ = water_vapor_roughness_length(ℓq, h, Σ★) ℓθ₀ = temperature_roughness_length(ℓθ, h, Σ★) @@ -463,15 +463,35 @@ end return SimilarityScales(u★, θ★, q★) end -struct GravityWaveRoughnessLength{FT} +struct GravityMomentumRoughnessLength{FT} gravitational_acceleration :: FT air_kinematic_viscosity :: FT gravity_wave_parameter :: FT laminar_parameter :: FT + maximum_roughness_length :: FT end -function GravityWaveRoughnessLength(FT=Float64; +struct GravityScalarRoughnessLength{FT, R} + air_kinematic_viscosity :: FT + reynolds_number_scaling_function :: R + maximum_roughness_length :: FT +end + +@inline liu_katsaros_businger_scaling_function(Rr) = ifelse(Rr == 0, 0, 5.8e-5 / Rr^0.72) + +function GravityScalarRoughnessLength(FT=Float64; + air_kinematic_viscosity = 1.5e-5, + reynolds_number_scaling_function = liu_katsaros_businger_scaling_function, + maximum_roughness_length = 1.64e-4) # Values from COARE3.6 + + return GravityScalarRoughnessLength(convert(FT, air_kinematic_viscosity), + reynolds_number_scaling_function, + convert(FT, maximum_roughness_length)) +end + +function GravityMomentumRoughnessLength(FT=Float64; gravitational_acceleration = default_gravitational_acceleration, + maximum_roughness_length = 1, air_kinematic_viscosity = 1.5e-5, gravity_wave_parameter = 0.011, laminar_parameter = 0.11) @@ -479,40 +499,44 @@ function GravityWaveRoughnessLength(FT=Float64; return GravityWaveRoughnessLength(convert(FT, gravitational_acceleration), convert(FT, air_kinematic_viscosity), convert(FT, gravity_wave_parameter), - convert(FT, laminar_parameter)) + convert(FT, laminar_parameter), + convert(FT, maximum_roughness_length)) end # Momentum roughness length should be different from scalar roughness length. # Apparently temperature and water vapor can be considered the same (Edison et al 2013) -@inline function momentum_roughness_length(ℓ::GravityWaveRoughnessLength{FT}, h, Σ★) where FT +@inline function momentum_roughness_length(ℓ::GravityMomentumRoughnessLength{FT}, Σ★) where FT u★ = Σ★.momentum - g = ℓ.gravitational_acceleration - ν = ℓ.air_kinematic_viscosity - α = ℓ.gravity_wave_parameter - β = ℓ.laminar_parameter + g = ℓ.gravitational_acceleration + ν = ℓ.air_kinematic_viscosity + α = ℓ.gravity_wave_parameter + β = ℓ.laminar_parameter + ℓm = ℓ.maximum_roughness_length # We need to prevent `Inf` that pops up when `u★ == 0`. - # However, if we leave `z₀ᴿ == 0` we will have a non-ending zero loop # For this reason, if `u★ == 0` we prescribe the roughness length to be - # equal to `1e-4` as an initial guess - z₀ᴿ = ifelse(u★ == 0, convert(FT, 1.5e-4), β * ν / u★) + # equal to a `maximum` roughness length + ℓᴿ = ifelse(u★ == 0, ℓm, β * ν / u★) - return min(α * u★^2 / g + z₀ᴿ, h / 2) + return min(α * u★^2 / g + ℓᴿ, ℓm) end -@inline water_vapor_roughness_length(ℓ, h, Σ★) = momentum_roughness_length(ℓ, h, Σ★) -@inline temperature_roughness_length(ℓ, h, Σ★) = momentum_roughness_length(ℓ, h, Σ★) - # This, for example is what is implemented in COARE 3.6 -# @inline function water_vapor_roughness_length(ℓ::GravityWaveRoughnessLength{FT}, ℓu, Σ★) where FT -# u★ = Σ★.momentum -# ν = ℓ.air_kinematic_viscosity - -# r = ℓu * u★ / ν -# ℓq = ifelse(r == 0, 1e-4, 5.8e-5 / r ^ 0.72) +@inline function water_vapor_roughness_length(ℓ::GravityScalarRoughnessLength{FT}, ℓu, Σ★) where FT + u★ = Σ★.momentum + ν = ℓ.air_kinematic_viscosity + ℓm = ℓ.maximum_roughness_length + R = ℓ.reynolds_number_scaling_function -# return min(1.6e-4, ℓq); -# end + # Roughness Reynolds number based + # on momentum roughness length + ℓᴿ = R(ℓu * u★ / ν) + + # If u★ is small we cap the scalar roughness length + ℓq = ifelse(u★ == 0, ℓm, ν / u★ * ℓᴿ) + + return min(ℓq, ℓm); +end -# @inline temperature_roughness_length(ℓ::GravityWaveRoughnessLength, ℓq, Σ★) = ℓq +@inline temperature_roughness_length(ℓ::GravityScalarRoughnessLength, ℓq, Σ★) = ℓq From a065e3fdb2444f65c55484eaf3d04123f2a4a7df Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 18:20:42 -0400 Subject: [PATCH 362/716] this should work! --- .../CrossRealmFluxes/latitude_dependent_albedo.jl | 6 ++++++ src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl | 8 ++++++++ .../similarity_theory_turbulent_fluxes.jl | 12 ++++++------ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl index 98196a79..fc4b26a4 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl @@ -14,6 +14,12 @@ struct TabulatedAlbedo{M, A, FT} S₀ :: FT # Solar constant W / m^2 end +Adapt.adapt_structure(to, α :: TabulatedAlbedo) = + TabulatedAlbedo(Adapt.adapt(to, α.α_table), + Adapt.adapt(to, α.φ_values), + Adapt.adapt(to, α.𝓉_values), + Adapt.adapt(to, α.S₀)) + # Tabulated from Payne (1972) https://doi.org/10.1175/1520-0469(1972)029<0959:AOTSS>2.0.CO;2 const α_payne = [ 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.06 0.062 0.062 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.06 diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index 6bc81bae..9a953e59 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -4,6 +4,11 @@ struct Radiation{FT, E, R} stefan_boltzmann_constant :: FT end +Adapt.adapt_structure(to, r :: Radiation) = + Radiation(Adapt.adapt(to, r.emission), + Adapt.adapt(to, r.reflection), + Adapt.adapt(to, r.stefan_boltzmann_constant)) + function Radiation(arch = CPU(), FT=Float64; ocean_emissivity = 0.97, sea_ice_emissivity = 1.0, @@ -51,3 +56,6 @@ struct SurfaceProperties{O, I} sea_ice :: I end +Adapt.adapt_structure(to, s :: SurfaceProperties) = + SurfaceProperties(Adapt.adapt(to, s.ocean), + Adapt.adapt(to, s.sea_ice)) \ No newline at end of file diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 13161f35..cf27516a 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -477,7 +477,7 @@ struct GravityScalarRoughnessLength{FT, R} maximum_roughness_length :: FT end -@inline liu_katsaros_businger_scaling_function(Rr) = ifelse(Rr == 0, 0, 5.8e-5 / Rr^0.72) +@inline liu_katsaros_businger_scaling_function(Rr :: FT) where FT = ifelse(Rr == 0, FT(0), covert(FT, 5.8e-5 / Rr^0.72)) function GravityScalarRoughnessLength(FT=Float64; air_kinematic_viscosity = 1.5e-5, @@ -496,11 +496,11 @@ function GravityMomentumRoughnessLength(FT=Float64; 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), - convert(FT, maximum_roughness_length)) + return GravityMomentumRoughnessLength(convert(FT, gravitational_acceleration), + convert(FT, air_kinematic_viscosity), + convert(FT, gravity_wave_parameter), + convert(FT, laminar_parameter), + convert(FT, maximum_roughness_length)) end # Momentum roughness length should be different from scalar roughness length. From 775539f90758a374a4335d3440f4624395277ca5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Sat, 27 Apr 2024 18:21:56 -0400 Subject: [PATCH 363/716] small bugfix --- src/OceanSimulations/OceanSimulations.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 40d2a1c0..0d81c407 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -3,10 +3,9 @@ module OceanSimulations export load_balanced_regional_grid, ocean_simulation using Oceananigans.Units -using Oceananigans.Operators using Oceananigans.Advection: TracerAdvection using Oceananigans.Coriolis: ActiveCellEnstrophyConserving -using Oceananigans.ImmersedBoundaries: immersed_peripheral_node, inactive_node, c, f +using Oceananigans.ImmersedBoundaries: immersed_peripheral_node, inactive_node using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity, @@ -38,6 +37,9 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), WENO(; order = 7), Centered()) +const c = Center() +const f = Face() + @inline ϕ²(i, j, k, grid, ϕ) = @inbounds ϕ[i, j, k]^2 @inline spᶠᶜᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.u[i, j, k]^2 + ℑxyᶠᶜᵃ(i, j, k, grid, ϕ², Φ.v)) @inline spᶜᶠᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.v[i, j, k]^2 + ℑxyᶜᶠᵃ(i, j, k, grid, ϕ², Φ.u)) From 628bcdfbd4ccfaa04ace8cdccf408f8e69002cb5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 18:24:15 -0400 Subject: [PATCH 364/716] using Adapt --- src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 733f9edc..cadd20c8 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -1,6 +1,7 @@ module CrossRealmFluxes using Oceananigans +using Adapt export Radiation, OceanSeaIceSurfaceFluxes From d6e0196f2cf2d20afcc92661c7e911eef80d8a5b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 18:25:20 -0400 Subject: [PATCH 365/716] changing the parameters for TabulatedAlbedo --- .../CrossRealmFluxes/latitude_dependent_albedo.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl index fc4b26a4..de1610bd 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl @@ -7,10 +7,10 @@ using ClimaOcean.OceanSeaIceModels: # Bilinear interpolation of the albedo α in α_table based on a # transmissivity value (𝓉_values) and latitude (φ_values) -struct TabulatedAlbedo{M, A, FT} +struct TabulatedAlbedo{M, P, T, FT} α_table :: M - φ_values :: A - 𝓉_values :: A + φ_values :: P + 𝓉_values :: T S₀ :: FT # Solar constant W / m^2 end From 8327c0bbdab60f155376e6e4fbed50ae674f2ac1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 18:34:17 -0400 Subject: [PATCH 366/716] small bugfix --- .../similarity_theory_turbulent_fluxes.jl | 26 +++++++------------ src/OceanSimulations/OceanSimulations.jl | 7 ++--- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index cf27516a..65e88456 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -397,13 +397,8 @@ end return Δh, Δu, Δv, Δθ, Δq end -@inline momentum_roughness_length(ℓ, Σ★) = ℓ(Σ★) -@inline water_vapor_roughness_length(ℓ, ℓu, Σ★) = ℓ(Σ★) -@inline temperature_roughness_length(ℓ, ℓq, Σ★) = ℓ(Σ★) - -@inline momentum_roughness_length(ℓ::Number, Σ★) = ℓ -@inline water_vapor_roughness_length(ℓ::Number, ℓu, Σ★) = ℓ -@inline temperature_roughness_length(ℓ::Number, ℓq, Σ★) = ℓ +@inline roughness_length(ℓ, Σ★) = ℓ(Σ★) +@inline roughness_length(ℓ::Number, Σ★) = ℓ @inline function refine_characteristic_scales(estimated_characteristic_scales, roughness_lengths, @@ -434,9 +429,9 @@ end h = differences.h ϰ = von_karman_constant - ℓu₀ = momentum_roughness_length(ℓu, Σ★) - ℓq₀ = water_vapor_roughness_length(ℓq, h, Σ★) - ℓθ₀ = temperature_roughness_length(ℓθ, h, Σ★) + ℓu₀ = roughness_length(ℓu, Σ★) + ℓq₀ = roughness_length(ℓq, Σ★) + ℓθ₀ = roughness_length(ℓθ, Σ★) ℂ = thermodynamics_parameters g = gravitational_acceleration @@ -477,7 +472,7 @@ struct GravityScalarRoughnessLength{FT, R} maximum_roughness_length :: FT end -@inline liu_katsaros_businger_scaling_function(Rr :: FT) where FT = ifelse(Rr == 0, FT(0), covert(FT, 5.8e-5 / Rr^0.72)) +@inline liu_katsaros_businger_scaling_function(Rr :: FT) where FT = ifelse(Rr == 0, FT(0), convert(FT, 5.8e-5 / Rr^0.72)) function GravityScalarRoughnessLength(FT=Float64; air_kinematic_viscosity = 1.5e-5, @@ -505,7 +500,7 @@ end # Momentum roughness length should be different from scalar roughness length. # Apparently temperature and water vapor can be considered the same (Edison et al 2013) -@inline function momentum_roughness_length(ℓ::GravityMomentumRoughnessLength{FT}, Σ★) where FT +@inline function roughness_length(ℓ::GravityMomentumRoughnessLength{FT}, Σ★) where FT u★ = Σ★.momentum g = ℓ.gravitational_acceleration ν = ℓ.air_kinematic_viscosity @@ -522,7 +517,7 @@ end end # This, for example is what is implemented in COARE 3.6 -@inline function water_vapor_roughness_length(ℓ::GravityScalarRoughnessLength{FT}, ℓu, Σ★) where FT +@inline function roughness_length(ℓ::GravityScalarRoughnessLength{FT}, Σ★) where FT u★ = Σ★.momentum ν = ℓ.air_kinematic_viscosity ℓm = ℓ.maximum_roughness_length @@ -536,7 +531,4 @@ end ℓq = ifelse(u★ == 0, ℓm, ν / u★ * ℓᴿ) return min(ℓq, ℓm); -end - -@inline temperature_roughness_length(ℓ::GravityScalarRoughnessLength, ℓq, Σ★) = ℓq - +end \ No newline at end of file diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 0d81c407..42ee32a6 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -37,9 +37,6 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), WENO(; order = 7), Centered()) -const c = Center() -const f = Face() - @inline ϕ²(i, j, k, grid, ϕ) = @inbounds ϕ[i, j, k]^2 @inline spᶠᶜᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.u[i, j, k]^2 + ℑxyᶠᶜᵃ(i, j, k, grid, ϕ², Φ.v)) @inline spᶜᶠᶜ(i, j, k, grid, Φ) = @inbounds sqrt(Φ.v[i, j, k]^2 + ℑxyᶜᶠᵃ(i, j, k, grid, ϕ², Φ.u)) @@ -50,8 +47,8 @@ const f = Face() @inline u_immersed_quadratic_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * spᶠᶜᶜ(i, j, k, grid, Φ) @inline v_immersed_quadratic_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) -@inline is_immersed_drag_u(i, j, k, grid) = Int(immersed_peripheral_node(i, j, k-1, grid, f, c, c) & !inactive_node(i, j, k, grid, f, c, c)) -@inline is_immersed_drag_v(i, j, k, grid) = Int(immersed_peripheral_node(i, j, k-1, grid, c, f, c) & !inactive_node(i, j, k, grid, c, f, c)) +@inline is_immersed_drag_u(i, j, k, grid) = Int(immersed_peripheral_node(i, j, k-1, grid, Face(), Center(), Center()) & !inactive_node(i, j, k, grid, Face(), Center(), Center())) +@inline is_immersed_drag_v(i, j, k, grid) = Int(immersed_peripheral_node(i, j, k-1, grid, Center(), Face(), Center()) & !inactive_node(i, j, k, grid, Center(), Face(), Center())) # Keep a constant linear drag parameter independent on vertical level @inline u_immersed_bottom_drag(i, j, k, grid, clock, fields, μ) = @inbounds - μ * fields.u[i, j, k] * is_immersed_drag_u(i, j, k, grid) * spᶠᶜᶜ(i, j, k, grid, fields) / Δzᶠᶜᶜ(i, j, k, grid) From 8b8fa2af07a28d4229fd70d22d85254f5c48edd1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 18:48:32 -0400 Subject: [PATCH 367/716] try like this? --- .../similarity_theory_turbulent_fluxes.jl | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 65e88456..56d87453 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -400,6 +400,9 @@ end @inline roughness_length(ℓ, Σ★) = ℓ(Σ★) @inline roughness_length(ℓ::Number, Σ★) = ℓ +@inline roughness_length(ℓ, ℓu, Σ★) = ℓ(Σ★) +@inline roughness_length(ℓ::Number, ℓu, Σ★) = ℓ + @inline function refine_characteristic_scales(estimated_characteristic_scales, roughness_lengths, similarity_functions, @@ -425,20 +428,21 @@ end ℓθ = roughness_lengths.temperature ℓq = roughness_lengths.water_vapor - # Compute Monin-Obukhov length scale h = differences.h ϰ = von_karman_constant - + + # Compute roughness length scales ℓu₀ = roughness_length(ℓu, Σ★) - ℓq₀ = roughness_length(ℓq, Σ★) - ℓθ₀ = roughness_length(ℓθ, Σ★) + ℓq₀ = roughness_length(ℓq, ℓu₀, Σ★) + ℓθ₀ = roughness_length(ℓθ, ℓu₀, Σ★) + # Compute Monin-Obukhov length scale depending on a `buoyancy flux` ℂ = thermodynamics_parameters g = gravitational_acceleration 𝒬ₒ = surface_state.ts # thermodynamic state b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, ℂ, g) - # Monin-Obhukov characteristic length + # Monin-Obhukov characteristic length scale L★ = ifelse(b★ == 0, zero(b★), - u★^2 / (ϰ * b★)) χu = bulk_factor(ψu, h, ℓu₀, L★) @@ -477,7 +481,7 @@ end function GravityScalarRoughnessLength(FT=Float64; air_kinematic_viscosity = 1.5e-5, reynolds_number_scaling_function = liu_katsaros_businger_scaling_function, - maximum_roughness_length = 1.64e-4) # Values from COARE3.6 + maximum_roughness_length = 1.6e-4) # Values from COARE3.6 return GravityScalarRoughnessLength(convert(FT, air_kinematic_viscosity), reynolds_number_scaling_function, @@ -486,7 +490,7 @@ end function GravityMomentumRoughnessLength(FT=Float64; gravitational_acceleration = default_gravitational_acceleration, - maximum_roughness_length = 1, + maximum_roughness_length = 5e-3, # An estimate? air_kinematic_viscosity = 1.5e-5, gravity_wave_parameter = 0.011, laminar_parameter = 0.11) @@ -517,7 +521,7 @@ end end # This, for example is what is implemented in COARE 3.6 -@inline function roughness_length(ℓ::GravityScalarRoughnessLength{FT}, Σ★) where FT +@inline function roughness_length(ℓ::GravityScalarRoughnessLength{FT}, ℓu, Σ★) where FT u★ = Σ★.momentum ν = ℓ.air_kinematic_viscosity ℓm = ℓ.maximum_roughness_length @@ -530,5 +534,5 @@ end # If u★ is small we cap the scalar roughness length ℓq = ifelse(u★ == 0, ℓm, ν / u★ * ℓᴿ) - return min(ℓq, ℓm); + return min(ℓᴿ, ℓm); end \ No newline at end of file From 4f20c0204213aca146afec702e2bcb02255d089c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 18:56:15 -0400 Subject: [PATCH 368/716] cleanup a bit --- .../similarity_theory_turbulent_fluxes.jl | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 56d87453..2af866eb 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -476,11 +476,14 @@ struct GravityScalarRoughnessLength{FT, R} maximum_roughness_length :: FT end -@inline liu_katsaros_businger_scaling_function(Rr :: FT) where FT = ifelse(Rr == 0, FT(0), convert(FT, 5.8e-5 / Rr^0.72)) +# Empirical fit of the scalar roughness length with the roughness reynolds number `R★ = u★ / ν` +# Found in Edson et al. (2013), equation (28) +@inline empirical_scaling_function(R★ :: FT, args...) where FT = + ifelse(R★ == 0, FT(0), convert(FT, 5.8e-5 / R★ ^ 0.72)) function GravityScalarRoughnessLength(FT=Float64; air_kinematic_viscosity = 1.5e-5, - reynolds_number_scaling_function = liu_katsaros_businger_scaling_function, + reynolds_number_scaling_function = empirical_scaling_function, maximum_roughness_length = 1.6e-4) # Values from COARE3.6 return GravityScalarRoughnessLength(convert(FT, air_kinematic_viscosity), @@ -525,14 +528,14 @@ end u★ = Σ★.momentum ν = ℓ.air_kinematic_viscosity ℓm = ℓ.maximum_roughness_length - R = ℓ.reynolds_number_scaling_function + + scaling_function = ℓ.reynolds_number_scaling_function - # Roughness Reynolds number based - # on momentum roughness length - ℓᴿ = R(ℓu * u★ / ν) + # Roughness Reynolds number + R★ = ℓu * u★ / ν - # If u★ is small we cap the scalar roughness length - ℓq = ifelse(u★ == 0, ℓm, ν / u★ * ℓᴿ) + # implementation of scalar roughness length + ℓq = scaling_function(R★, ℓu, u★, ν) - return min(ℓᴿ, ℓm); + return min(ℓᴿ, ℓm) end \ No newline at end of file From dee662c5ce217dbf88315fac45ac42e6f388edb9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 19:36:00 -0400 Subject: [PATCH 369/716] give it a try --- .../similarity_theory_turbulent_fluxes.jl | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 2af866eb..cd7bbef6 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -476,15 +476,21 @@ struct GravityScalarRoughnessLength{FT, R} maximum_roughness_length :: FT end -# Empirical fit of the scalar roughness length with the roughness reynolds number `R★ = u★ / ν` -# Found in Edson et al. (2013), equation (28) +# Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ / ν` +# Edson et al. (2013), equation (28) @inline empirical_scaling_function(R★ :: FT, args...) where FT = - ifelse(R★ == 0, FT(0), convert(FT, 5.8e-5 / R★ ^ 0.72)) + ifelse(R★ == 0, FT(0), convert(FT, 5.5e-5 / R★ ^ 0.6)) + +# Brusser - Garrat scaling of the scalar roughness length with roughness number +# Edson et al. (2013), equation (29) +@inline brusser_garrat_scaling_function(R★ :: FT, ℓu, args...) where FT = + convert(FT, ℓu * exp(2 - 2.28 * sqrt(sqrt(R★)))) + function GravityScalarRoughnessLength(FT=Float64; air_kinematic_viscosity = 1.5e-5, - reynolds_number_scaling_function = empirical_scaling_function, - maximum_roughness_length = 1.6e-4) # Values from COARE3.6 + reynolds_number_scaling_function = brusser_garrat_scaling_function, + maximum_roughness_length = 1.1e-4) # Values from COARE3.6 return GravityScalarRoughnessLength(convert(FT, air_kinematic_viscosity), reynolds_number_scaling_function, @@ -537,5 +543,5 @@ end # implementation of scalar roughness length ℓq = scaling_function(R★, ℓu, u★, ν) - return min(ℓᴿ, ℓm) + return min(ℓq, ℓm) end \ No newline at end of file From a96df8d94a3dfe87858c493e0eab5936e3c8d594 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 27 Apr 2024 19:41:00 -0400 Subject: [PATCH 370/716] back to previous formulation --- prototype_omip_simulation/comparison_to_coare.jl | 3 ++- .../CrossRealmFluxes/latitude_dependent_albedo.jl | 2 +- .../CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index 2e162ca0..97ab36e2 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -7,6 +7,7 @@ using ClimaOcean.ECCO2 using ClimaOcean.OceanSimulations using Oceananigans.Units using ClimaOcean.JRA55: JRA55_prescribed_atmosphere +using ClimaOcean.OceanSeaIceModels: Radiation # Upload ECCO2 fields T = ECCO2.ecco2_field(:temperature) @@ -28,7 +29,7 @@ ocean_model = ocean.model # setting ecco variables in the model set!(ocean_model, T = T, S = S, u = u, v = v) -coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation = nothing) +coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation = Radiation()) function centered_surface_u_velocity(u) 𝒰ᶜᶜᶜ = KernelFunctionOperation{Center, Center, Center}(ℑxᶜᵃᵃ, grid, u) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl index de1610bd..40c11a49 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl @@ -114,5 +114,5 @@ end ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) - return - (1 - α) * Qs - ε * Qℓ + return - (1 - α) * Qs - ϵ * Qℓ end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index cd7bbef6..bbdb8086 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -479,7 +479,7 @@ end # Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ / ν` # Edson et al. (2013), equation (28) @inline empirical_scaling_function(R★ :: FT, args...) where FT = - ifelse(R★ == 0, FT(0), convert(FT, 5.5e-5 / R★ ^ 0.6)) + ifelse(R★ == 0, FT(0), convert(FT, 5.85e-5 / R★ ^ 0.76)) # Brusser - Garrat scaling of the scalar roughness length with roughness number # Edson et al. (2013), equation (29) @@ -490,7 +490,7 @@ end function GravityScalarRoughnessLength(FT=Float64; air_kinematic_viscosity = 1.5e-5, reynolds_number_scaling_function = brusser_garrat_scaling_function, - maximum_roughness_length = 1.1e-4) # Values from COARE3.6 + maximum_roughness_length = 1.6e-4) # Values from COARE3.6 return GravityScalarRoughnessLength(convert(FT, air_kinematic_viscosity), reynolds_number_scaling_function, From 28ac1cdbf02354a65cab5c37c9b9d09783b72fa7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 14:57:08 -0400 Subject: [PATCH 371/716] this should work now! --- .../PrescribedAtmospheres.jl | 205 -------------- src/DataWrangling/JRA55.jl | 4 +- .../ocean_sea_ice_surface_fluxes.jl | 25 +- .../similarity_theory_turbulent_fluxes.jl | 268 ++++++++++++------ .../PrescribedAtmospheres.jl | 8 +- 5 files changed, 186 insertions(+), 324 deletions(-) delete mode 100644 sandbox/PrescribedAtmospheres/PrescribedAtmospheres.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/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 07f68ac7..b8f3ab6d 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -566,7 +566,7 @@ JRA55_prescribed_atmosphere(arch::Distributed, time_indices=Colon(); kw...) = function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, time_indexing = Cyclical(), - reference_height = 2, # meters + measurement_height = 2, # meters other_kw...) if isnothing(backend) # apply a default @@ -620,7 +620,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); freshwater_flux, tracers, downwelling_radiation, - reference_height, + measurement_height, pressure) return atmosphere diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 010a9dcb..93b49227 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -193,7 +193,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_times, atmosphere_backend, atmosphere_time_indexing, - atmosphere.reference_height, # height at which the state is known + atmosphere.measurement_height, # height at which the state is known atmosphere.thermodynamics_parameters, similarity_theory.roughness_lengths, similarity_theory.similarity_functions) @@ -247,7 +247,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing atmos_times, atmos_backend, atmos_time_indexing, - atmosphere_reference_height, + atmosphere_measurement_height, atmos_thermodynamics_parameters, roughness_lengths, similarity_functions) @@ -294,7 +294,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing ℂₐ = atmos_thermodynamics_parameters 𝒬ₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) - hₐ = atmosphere_reference_height # elevation of atmos variables relative to surface + hₐ = atmosphere_measurement_height # elevation of atmos variables relative to surface Uₐ = SVector(uₐ, vₐ) 𝒰ₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, 𝒬ₐ) @@ -318,23 +318,6 @@ limit_fluxes_over_sea_ice!(args...) = nothing τx = similarity_theory_fields.x_momentum τy = similarity_theory_fields.y_momentum - @inbounds begin - Qcᵢ = Qc[i, j, 1] - Fvᵢ = Fv[i, j, 1] - τxᵢ = τx[i, j, 1] - τyᵢ = τy[i, j, 1] - end - - # Compute initial guess based on previous fluxes - ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) - cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity - - u★ = sqrt(sqrt(τxᵢ^2 + τyᵢ^2)) - u★ = ifelse(u★ == 0, 1e-2, u★) - θ★ = - Qcᵢ / (ρₐ * cₚ * u★) - q★ = - Fvᵢ / (ρₐ * u★) - Σ★ = SimilarityScales(u★, θ★, q★) - g = default_gravitational_acceleration ϰ = 0.4 @@ -342,7 +325,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing similarity_functions, dynamic_ocean_state, dynamic_atmos_state, - ℂₐ, g, ϰ, Σ★) + ℂₐ, g, ϰ) kᴺ = size(grid, 3) # index of the top ocean cell diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index bbdb8086..23c94e25 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -232,26 +232,32 @@ SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature atmos_state, thermodynamics_parameters, gravitational_acceleration, - von_karman_constant, - Σ₀ = SimilarityScales(1e-3, 1e-3, 1e-3)) + 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. - Σ★ = Σ₀ + Σ★ = initial_guess(differences, + roughness_lengths, + similarity_functions, + gravitational_acceleration, + von_karman_constant, + ℂₐ, surface_state.ts) + + uτ = sqrt(Δu^2 + Δv^2 + 0.5^2) for _ in 1:10 - Σ★ = refine_characteristic_scales(Σ★, - roughness_lengths, - similarity_functions, - surface_state, - differences, - thermodynamics_parameters, - gravitational_acceleration, - von_karman_constant) + Σ★, uτ = refine_characteristic_scales(Σ★, uτ, + roughness_lengths, + similarity_functions, + surface_state, + differences, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) end u★ = Σ★.momentum @@ -278,24 +284,90 @@ SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature return fluxes end +@inline function initial_guess(differences, + roughness_lengths, + similarity_functions, + gravitational_acceleration, + von_karman_constant, + ℂₐ, 𝒬ₐ) + + Δu = differences.u + Δv = differences.v + Δθ = differences.θ + Δq = differences.q + h = differences.h + + g = gravitational_acceleration + ϰ = von_karman_constant + + # Extract roughness lengths + ℓu = roughness_lengths.momentum + ℓθ = roughness_lengths.temperature + ℓq = roughness_lengths.water_vapor + + # assuming the initial gustiness is `0.5` ms⁻¹ + uᴳ = 0.5 + uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) + + # u★ at the reference ten meter height, assuming the initial roughness length is `1e-4` m + u10 = uτ / log(h / 1e-4) * 11.5129 # log(10 / 1e-4) == 11.5129 + u★ = 0.035 * u10 + + ℓu₀ = roughness_length(ℓu, u★, 𝒬ₐ, ℂₐ) + + # Initial neutral coefficients at 10 meter height + Cuₙ = (ϰ / log(10 / ℓu₀))^2 + Cθₙ = 0.00115 / sqrt(Cuₙ) + + # Initial thermal roughness length + ℓθ₀ = 10 / exp(ϰ / Cθₙ) + + # Transfer coefficients at height `h` + Cu = (ϰ / log(h / ℓu₀))^2 + Cθ = (ϰ / log(h / ℓθ₀))^2 + + # Similarity functions from Businger et al. (1971) + ψu = similarity_functions.momentum + ψθ = similarity_functions.temperature + ψq = similarity_functions.water_vapor + + # Bulk Flux Richardson number + Ribcu = - h / 600 / 0.004 / 1.2^3 # - zu / zi / 0.004 / β^3 + b★ = buoyancy_scale(Δθ, Δq, 𝒬ₐ, ℂₐ, g) + Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) + ζ = ϰ * Cθ / Cu * Ribcu / (1 + Ri / Ribcu) + + L10 = ifelse(ζ == 0, zero(ζ), h / ζ) + + u★ = uτ * ϰ / (log(h / ℓu₀) - ψu(h / L10) + ψu(ℓu₀ / L10)) + θ★ = Δθ * ϰ / (log(h / ℓθ₀) - ψθ(h / L10) + ψθ(ℓθ₀ / L10)) + q★ = Δq * ϰ / (log(h / ℓθ₀) - ψq(h / L10) + ψq(ℓθ₀ / L10)) + + return SimilarityScales(u★, θ★, q★) +end + struct Momentum end struct Scalar end -struct SimilarityFunction{M, FT, C} +struct SimilarityFunction{M, FT, C, D} a :: FT b :: FT c :: C + d :: D - SimilarityFunction{M}(a::FT, b::FT, c::C) where {M, FT, C} = new{M, FT, C}(a, b, c) + SimilarityFunction{M}(a::FT, b::FT, c::C, d::D) where {M, FT, C, D} = new{M, FT, C, D}(a, b, c, d) end -Adapt.adapt_structure(to, ψ::SimilarityFunction{M}) where M = SimilarityFunction{M}(ψ.a, ψ.b, ψ.c) +Adapt.adapt_structure(to, ψ::SimilarityFunction{M}) where M = SimilarityFunction{M}(ψ.a, ψ.b, ψ.c, ψ.d) function businger_similarity_functions(FT = Float64) # Computed from Businger et al. (1971) - ψu = SimilarityFunction{Momentum}(4.7, 15.0, OneQuarter()) - ψc = SimilarityFunction{Scalar}(6.35, 9.0, OneHalf()) + # ψu = SimilarityFunction{Momentum}(4.7, 15.0, OneQuarter()) + # ψc = SimilarityFunction{Scalar}(6.35, 9.0, OneHalf()) + + ψu = SimilarityFunction{Momentum}(0.7, 0.75, 5.0, 0.35) + ψc = SimilarityFunction{Scalar}(6.35, 2/3, 0.35, 1.0) return SimilarityScales(ψu, ψc, ψc) end @@ -305,29 +377,41 @@ end # Also in that paper momentum and scalar stability functions are different, here they are the same?? # Fairell et al implement a different formulation with a "convective" and "stable" stability function @inline function (ψ::SimilarityFunction{<:Momentum})(ζ) - a = ψ.a - b = ψ.b - c = ψ.c ζ⁻ = min(zero(ζ), ζ) - fₘ = (1 - b * ζ⁻)^c + ζ⁺ = max(zero(ζ), ζ) + dζ = min(50, 0.35 * ζ⁺) - ψ_unstable = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2 - ψ_stable = - a * ζ + ψ_stable = - 0.7 * ζ⁺ - 3 / 4 * (ζ⁺ - 5 / 0.35) * exp(-dζ) - 3 / 4 * 5 / 0.35 + + fₘ = sqrt(sqrt(1 - 15 * ζ⁻)) + ψ_unstable_1 = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2; + + fₘ = cbrt(1 - 10.15 * ζ⁻) + ψ_unstable_2 = 1.5 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3))+ π / sqrt(3) + + f⁻ = ζ⁻^2 / (1 + ζ⁻^2) + ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 return ifelse(ζ < 0, ψ_unstable, ψ_stable) end @inline function (ψ::SimilarityFunction{<:Scalar})(ζ) - a = ψ.a - b = ψ.b - c = ψ.c ζ⁻ = min(zero(ζ), ζ) - fₕ = (1 - b * ζ⁻)^c + ζ⁺ = max(zero(ζ), ζ) + dζ = min(50, 0.35 * ζ⁺) - ψ_unstable = 2 * log((1 + fₕ^2) / 2) - ψ_stable = - a * ζ + ψ_stable = - (4 * ζ⁺ / 3)^(3 / 2) - 2 / 3 * (ζ⁺ - 14.28) * exp(-dζ) - 8.525 + + fₕ = sqrt(1 - 15 * ζ⁻) + ψ_unstable_1 = 2 * log((1 + fₕ) / 2) + + fₕ = cbrt(1 - 34.15 * ζ⁻) + ψ_unstable_2 = 1.5 * log((1 + fₕ + fₕ^2) / 3) - sqrt(3) * atan((1 + 2fₕ) / sqrt(3))+ π / sqrt(3) + + f⁻ = ζ⁻^2 / (1 + ζ⁻^2) + ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 return ifelse(ζ < 0, ψ_unstable, ψ_stable) end @@ -339,19 +423,6 @@ import Base: ^ @inline ^(x, ::OneQuarter) = sqrt(sqrt(x)) @inline ^(x, ::OneHalf) = sqrt(x) -@inline function bulk_factor(ψ, h, ℓ, L★) - - # Non-dimensional height in Obukhov length units - ζ = ifelse(L★ == 0, zero(h), h / L★) - - # Non-dimensional roughness height in Obukhov length units - ζᵣ = ifelse(L★ == 0, zero(h), ℓ / L★) - - χ⁻¹ = log(h / ℓ) - ψ(ζ) + ψ(ζᵣ) - - return ifelse(χ⁻¹ == 0, zero(h), 1 / χ⁻¹) -end - # The M-O characteristic length is calculated as # L★ = - u★² / (κ ⋅ b★) # where b★ is the characteristic buoyancy scale calculated from this function @@ -397,13 +468,14 @@ end return Δh, Δu, Δv, Δθ, Δq end -@inline roughness_length(ℓ, Σ★) = ℓ(Σ★) -@inline roughness_length(ℓ::Number, Σ★) = ℓ +@inline roughness_length(ℓ, Σ★, args...) = ℓ(Σ★, args...) +@inline roughness_length(ℓ::Number, Σ★, args...) = ℓ -@inline roughness_length(ℓ, ℓu, Σ★) = ℓ(Σ★) -@inline roughness_length(ℓ::Number, ℓu, Σ★) = ℓ +@inline roughness_length(ℓ, ℓu, Σ★, args...) = ℓ(Σ★, args...) +@inline roughness_length(ℓ::Number, ℓu, Σ★, args...) = ℓ -@inline function refine_characteristic_scales(estimated_characteristic_scales, +@inline function refine_characteristic_scales(estimated_characteristic_scales, + velocity_scale, roughness_lengths, similarity_functions, surface_state, @@ -416,7 +488,7 @@ end u★ = estimated_characteristic_scales.momentum θ★ = estimated_characteristic_scales.temperature q★ = estimated_characteristic_scales.water_vapor - Σ★ = estimated_characteristic_scales + uτ = velocity_scale # Similarity functions from Businger et al. (1971) ψu = similarity_functions.momentum @@ -428,50 +500,58 @@ end ℓθ = roughness_lengths.temperature ℓq = roughness_lengths.water_vapor - h = differences.h - ϰ = von_karman_constant - - # Compute roughness length scales - ℓu₀ = roughness_length(ℓu, Σ★) - ℓq₀ = roughness_length(ℓq, ℓu₀, Σ★) - ℓθ₀ = roughness_length(ℓθ, ℓu₀, Σ★) + h = differences.h + ϰ = von_karman_constant + ℂ = thermodynamics_parameters + g = gravitational_acceleration + 𝒬ₒ = surface_state.ts # thermodynamic state # Compute Monin-Obukhov length scale depending on a `buoyancy flux` - ℂ = thermodynamics_parameters - g = gravitational_acceleration - 𝒬ₒ = surface_state.ts # thermodynamic state b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, ℂ, g) - # Monin-Obhukov characteristic length scale + # Monin-Obhukov characteristic length scale and non-dimensional height L★ = ifelse(b★ == 0, zero(b★), - u★^2 / (ϰ * b★)) - χu = bulk_factor(ψu, h, ℓu₀, L★) - χθ = bulk_factor(ψθ, h, ℓθ₀, L★) - χq = bulk_factor(ψq, h, ℓq₀, L★) + # Compute roughness length scales + ℓu₀ = roughness_length(ℓu, u★, 𝒬ₒ, ℂ) + ℓq₀ = roughness_length(ℓq, ℓu₀, u★, 𝒬ₒ, ℂ) + ℓθ₀ = roughness_length(ℓθ, ℓu₀, u★, 𝒬ₒ, ℂ) + + # Transfer coefficients at height `h` + Cu = ϰ / (log(h / ℓu₀) - ψu(h / L★) + ψu(ℓu₀ / L★)) + Cθ = ϰ / (log(h / ℓq₀) - ψθ(h / L★) + ψθ(ℓq₀ / L★)) + Cq = ϰ / (log(h / ℓθ₀) - ψq(h / L★) + ψq(ℓθ₀ / L★)) Δu = differences.u Δv = differences.v Δθ = differences.θ Δq = differences.q - # Maybe we should add gustiness here? - u★ = ϰ * χu * sqrt(Δu^2 + Δv^2) - θ★ = ϰ * χθ * Δθ - q★ = ϰ * χq * Δq + # u★ including gustiness + u★ = Cu * uτ + θ★ = Cθ * Δθ + q★ = Cq * Δq - return SimilarityScales(u★, θ★, q★) + # Dissipation characteristic scale for gustiness + ε★ = - u★ * b★ + uᴳ = 1.2 * cbrt(ε★ * 600) + + # New velocity difference accounting for gustiness + uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) + + return SimilarityScales(u★, θ★, q★), uτ end -struct GravityMomentumRoughnessLength{FT} +struct GravityMomentumRoughnessLength{FT, V} gravitational_acceleration :: FT - air_kinematic_viscosity :: FT + air_kinematic_viscosity :: V gravity_wave_parameter :: FT laminar_parameter :: FT maximum_roughness_length :: FT end -struct GravityScalarRoughnessLength{FT, R} - air_kinematic_viscosity :: FT +struct GravityScalarRoughnessLength{FT, V, R} + air_kinematic_viscosity :: V reynolds_number_scaling_function :: R maximum_roughness_length :: FT end @@ -479,33 +559,35 @@ end # Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ / ν` # Edson et al. (2013), equation (28) @inline empirical_scaling_function(R★ :: FT, args...) where FT = - ifelse(R★ == 0, FT(0), convert(FT, 5.85e-5 / R★ ^ 0.76)) - -# Brusser - Garrat scaling of the scalar roughness length with roughness number -# Edson et al. (2013), equation (29) -@inline brusser_garrat_scaling_function(R★ :: FT, ℓu, args...) where FT = - convert(FT, ℓu * exp(2 - 2.28 * sqrt(sqrt(R★)))) + ifelse(R★ == 0, FT(0), convert(FT, 5.85e-5 / R★ ^ 0.72)) +# Assumes that θ comes in in Kelvin +@inline function temperature_dependent_viscosity(θ :: FT) where FT + T = convert(FT, θ - celsius_to_kelvin) + ν = convert(FT, 1.326e-5 * (1 + 6.542e-3 * T + 8.301e-6 * T^2 - 4.84e-9 * T^3)) + + return ν +end function GravityScalarRoughnessLength(FT=Float64; - air_kinematic_viscosity = 1.5e-5, - reynolds_number_scaling_function = brusser_garrat_scaling_function, + air_kinematic_viscosity = temperature_dependent_viscosity, + reynolds_number_scaling_function = empirical_scaling_function, maximum_roughness_length = 1.6e-4) # Values from COARE3.6 - return GravityScalarRoughnessLength(convert(FT, air_kinematic_viscosity), + return GravityScalarRoughnessLength(air_kinematic_viscosity, reynolds_number_scaling_function, convert(FT, maximum_roughness_length)) end function GravityMomentumRoughnessLength(FT=Float64; - gravitational_acceleration = default_gravitational_acceleration, - maximum_roughness_length = 5e-3, # An estimate? - air_kinematic_viscosity = 1.5e-5, - gravity_wave_parameter = 0.011, - laminar_parameter = 0.11) + gravitational_acceleration = default_gravitational_acceleration, + maximum_roughness_length = 5e-3, # An estimate? + air_kinematic_viscosity = temperature_dependent_viscosity, + gravity_wave_parameter = 0.011, + laminar_parameter = 0.11) return GravityMomentumRoughnessLength(convert(FT, gravitational_acceleration), - convert(FT, air_kinematic_viscosity), + air_kinematic_viscosity, convert(FT, gravity_wave_parameter), convert(FT, laminar_parameter), convert(FT, maximum_roughness_length)) @@ -513,14 +595,15 @@ end # Momentum roughness length should be different from scalar roughness length. # Apparently temperature and water vapor can be considered the same (Edison et al 2013) -@inline function roughness_length(ℓ::GravityMomentumRoughnessLength{FT}, Σ★) where FT - u★ = Σ★.momentum +@inline function roughness_length(ℓ::GravityMomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT g = ℓ.gravitational_acceleration - ν = ℓ.air_kinematic_viscosity α = ℓ.gravity_wave_parameter β = ℓ.laminar_parameter ℓm = ℓ.maximum_roughness_length + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) + ν = ℓ.air_kinematic_viscosity(θ₀) + # We need to prevent `Inf` that pops up when `u★ == 0`. # For this reason, if `u★ == 0` we prescribe the roughness length to be # equal to a `maximum` roughness length @@ -530,13 +613,14 @@ end end # This, for example is what is implemented in COARE 3.6 -@inline function roughness_length(ℓ::GravityScalarRoughnessLength{FT}, ℓu, Σ★) where FT - u★ = Σ★.momentum - ν = ℓ.air_kinematic_viscosity +@inline function roughness_length(ℓ::GravityScalarRoughnessLength{FT}, ℓu, u★, 𝒬, ℂ) where FT ℓm = ℓ.maximum_roughness_length scaling_function = ℓ.reynolds_number_scaling_function + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) + ν = ℓ.air_kinematic_viscosity(θ₀) + # Roughness Reynolds number R★ = ℓu * u★ / ν diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 0a845024..e8451881 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -296,7 +296,7 @@ struct PrescribedAtmosphere{G, U, P, C, F, R, TP, TI, FT} downwelling_radiation :: R thermodynamics_parameters :: TP times :: TI - reference_height :: FT + measurement_height :: FT end Base.summary(::PrescribedAtmosphere) = "PrescribedAtmosphere" @@ -304,7 +304,7 @@ Base.show(io::IO, pa::PrescribedAtmosphere) = print(io, summary(pa)) """ PrescribedAtmosphere(times; - reference_height, + measurement_height, velocities = nothing, pressure = nothing, freshwater_flux = nothing, @@ -315,7 +315,7 @@ Return a representation of a prescribed time-evolving atmospheric state with data given at `times`. """ function PrescribedAtmosphere(times, FT=Float64; - reference_height, + measurement_height, velocities = nothing, pressure = nothing, freshwater_flux = nothing, @@ -337,7 +337,7 @@ function PrescribedAtmosphere(times, FT=Float64; downwelling_radiation, thermodynamics_parameters, times, - convert(FT, reference_height)) + convert(FT, measurement_height)) end update_model_field_time_series!(::Nothing, time) = nothing From 756a98702f3954e723b9c0f5f081ce951cf65712 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 15:00:16 -0400 Subject: [PATCH 372/716] some changes --- .../CrossRealmFluxes/latitude_dependent_albedo.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl index 40c11a49..9d18d4f5 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl @@ -100,7 +100,7 @@ end Δ𝓉 = @inbounds α.𝓉_values[2] - 𝓉₁ i⁻, i⁺, ξ = interpolator((𝓉 - 𝓉₁) / Δ𝓉) - # finding the i-index in the table (depending on latitude) + # finding the j-index in the table (depending on latitude) # assuming the transmissivity is tabulated with constant values φ₁ = @inbounds α.φ_values[1] Δφ = @inbounds α.φ_values[2] - φ₁ From b06d3153d96bbb2e4f8afcfbd2463fd9cf4d181b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 15:59:15 -0400 Subject: [PATCH 373/716] updating --- .../ocean_sea_ice_surface_fluxes.jl | 34 +++---- .../similarity_theory_turbulent_fluxes.jl | 93 ++++++++++--------- 2 files changed, 62 insertions(+), 65 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 93b49227..55296151 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -58,6 +58,7 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; radiation = nothing, freshwater_density = 1000, ocean_temperature_units = DegreesCelsius(), + similarity_theory = nothing, ocean_reference_density = reference_density(ocean), ocean_heat_capacity = heat_capacity(ocean)) @@ -72,9 +73,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 - similarity_theory = SimilarityTheoryTurbulentFluxes(grid; gravitational_acceleration) - else - similarity_theory = nothing + if isnothing(similarity_theory) + similarity_theory = SimilarityTheoryTurbulentFluxes(grid; gravitational_acceleration) + end end prescribed_fluxes = nothing @@ -183,7 +184,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) kernel_parameters = KernelParameters(kernel_size, (-1, -1)) launch!(arch, grid, kernel_parameters, _compute_atmosphere_ocean_similarity_theory_fluxes!, - similarity_theory.fields, + similarity_theory, grid, clock, ocean_state, @@ -194,9 +195,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_backend, atmosphere_time_indexing, atmosphere.measurement_height, # height at which the state is known - atmosphere.thermodynamics_parameters, - similarity_theory.roughness_lengths, - similarity_theory.similarity_functions) + atmosphere.thermodynamics_parameters) launch!(arch, grid, kernel_parameters, _assemble_atmosphere_ocean_fluxes!, centered_velocity_fluxes, @@ -237,7 +236,7 @@ end # Fallback! limit_fluxes_over_sea_ice!(args...) = nothing -@kernel function _compute_atmosphere_ocean_similarity_theory_fluxes!(similarity_theory_fields, +@kernel function _compute_atmosphere_ocean_similarity_theory_fluxes!(similarity_theory, grid, clock, ocean_state, @@ -248,9 +247,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing atmos_backend, atmos_time_indexing, atmosphere_measurement_height, - atmos_thermodynamics_parameters, - roughness_lengths, - similarity_functions) + atmos_thermodynamics_parameters) i, j = @index(Global, NTuple) kᴺ = size(grid, 3) @@ -312,17 +309,16 @@ limit_fluxes_over_sea_ice!(args...) = nothing 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 + 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 g = default_gravitational_acceleration - ϰ = 0.4 + ϰ = similarity_theory.von_karman_constant - turbulent_fluxes = compute_similarity_theory_fluxes(roughness_lengths, - similarity_functions, + turbulent_fluxes = compute_similarity_theory_fluxes(similarity_theory, dynamic_ocean_state, dynamic_atmos_state, ℂₐ, g, ϰ) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 23c94e25..6716b5fd 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -32,6 +32,8 @@ import SurfaceFluxes.Parameters: struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, R, F} <: AbstractSurfaceFluxesParameters gravitational_acceleration :: FT von_karman_constant :: FT + planetary_boundary_layer_height :: FT + turbulent_prandtl_number :: FT bulk_velocity_scale :: ΔU similarity_functions :: UF thermodynamics_parameters :: TP @@ -52,6 +54,8 @@ const STTF = SimilarityTheoryTurbulentFluxes Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), adapt(to, fluxes.von_karman_constant), + adapt(to, fluxes.planetary_boundary_layer_height), + adapt(to, fluxes.turbulent_prandtl_number), nothing, # adapt(to, fluxes.bulk_velocity_scale), adapt(to, fluxes.similarity_functions), adapt(to, fluxes.thermodynamics_parameters), @@ -85,13 +89,15 @@ const LYS = LargeYeagerSaturation function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) print(io, summary(fluxes), '\n', - "├── gravitational_acceleration: ", prettysummary(fluxes.gravitational_acceleration), '\n', - "├── von_karman_constant: ", prettysummary(fluxes.von_karman_constant), '\n', - "├── bulk_velocity_scale: ", summary(fluxes.bulk_velocity_scale), '\n', - "├── similarity_function: ", summary(fluxes.similarity_function), '\n', - "├── water_mole_fraction: ", summary(fluxes.water_mole_fraction), '\n', - "├── water_vapor_saturation: ", summary(fluxes.water_vapor_saturation), '\n', - "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) + "├── 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', + "├── planetary_boundary_layer_height: ", prettysummary(fluxes.planetary_boundary_layer_height), '\n', + "├── turbulent_prandtl_number: ", prettysummary(fluxes.turbulent_prandtl_number), '\n', + "├── similarity_function: ", summary(fluxes.similarity_function), '\n', + "├── water_mole_fraction: ", summary(fluxes.water_mole_fraction), '\n', + "├── water_vapor_saturation: ", summary(fluxes.water_vapor_saturation), '\n', + "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) end function default_roughness_lengths(FT=Float64) @@ -107,6 +113,8 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; gravitational_acceleration = default_gravitational_acceleration, bulk_velocity_scale = nothing, von_karman_constant = convert(FT, 0.4), + planetary_boundary_layer_height = convert(FT, 600), + turbulent_prandtl_number = convert(FT, 1), similarity_functions = businger_similarity_functions(FT), thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), @@ -116,6 +124,8 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), convert(FT, von_karman_constant), + convert(FT, planetary_boundary_layer_height), + convert(FT, turbulent_prandtl_number), bulk_velocity_scale, similarity_functions, thermodynamics_parameters, @@ -226,8 +236,7 @@ SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature ##### Fixed-point iteration for roughness length ##### -@inline function compute_similarity_theory_fluxes(roughness_lengths, - similarity_functions, +@inline function compute_similarity_theory_fluxes(similarity_theory, surface_state, atmos_state, thermodynamics_parameters, @@ -239,20 +248,21 @@ SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature Δ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. + # Initial guess for the characteristic scales u★, θ★, q★. Σ★ = initial_guess(differences, - roughness_lengths, - similarity_functions, + similarity_theory, gravitational_acceleration, von_karman_constant, - ℂₐ, surface_state.ts) + ℂₐ, atmos_state.ts) - uτ = sqrt(Δu^2 + Δv^2 + 0.5^2) + # The inital velocity scale assumes that + # the gustiness velocity `uᴳ` is equal to 0.5 ms⁻¹. + # That will be refined later on. + uτ = sqrt(Δu^2 + Δv^2 + 0.25) for _ in 1:10 Σ★, uτ = refine_characteristic_scales(Σ★, uτ, - roughness_lengths, - similarity_functions, + similarity_theory, surface_state, differences, thermodynamics_parameters, @@ -285,12 +295,11 @@ SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature end @inline function initial_guess(differences, - roughness_lengths, - similarity_functions, + similarity_theory, gravitational_acceleration, von_karman_constant, ℂₐ, 𝒬ₐ) - + Δu = differences.u Δv = differences.v Δθ = differences.θ @@ -301,15 +310,14 @@ end ϰ = von_karman_constant # Extract roughness lengths - ℓu = roughness_lengths.momentum - ℓθ = roughness_lengths.temperature - ℓq = roughness_lengths.water_vapor + ℓu = similarity_theory.roughness_lengths.momentum + zᵢ = similarity_theory.planetary_boundary_layer_height # assuming the initial gustiness is `0.5` ms⁻¹ uᴳ = 0.5 uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) - # u★ at the reference ten meter height, assuming the initial roughness length is `1e-4` m + # u10 at the reference ten meter height, assuming the initial roughness length is `1e-4` m u10 = uτ / log(h / 1e-4) * 11.5129 # log(10 / 1e-4) == 11.5129 u★ = 0.035 * u10 @@ -322,17 +330,17 @@ end # Initial thermal roughness length ℓθ₀ = 10 / exp(ϰ / Cθₙ) - # Transfer coefficients at height `h` + # Neutral transfer coefficients at height `h` Cu = (ϰ / log(h / ℓu₀))^2 Cθ = (ϰ / log(h / ℓθ₀))^2 # Similarity functions from Businger et al. (1971) - ψu = similarity_functions.momentum - ψθ = similarity_functions.temperature - ψq = similarity_functions.water_vapor + ψu = similarity_theory.similarity_functions.momentum + ψθ = similarity_theory.similarity_functions.temperature + ψq = similarity_theory.similarity_functions.water_vapor # Bulk Flux Richardson number - Ribcu = - h / 600 / 0.004 / 1.2^3 # - zu / zi / 0.004 / β^3 + Ribcu = - h / zᵢ / 0.004 / 1.2^3 # - h / zi / 0.004 / β^3 b★ = buoyancy_scale(Δθ, Δq, 𝒬ₐ, ℂₐ, g) Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) ζ = ϰ * Cθ / Cu * Ribcu / (1 + Ri / Ribcu) @@ -372,10 +380,6 @@ function businger_similarity_functions(FT = Float64) return SimilarityScales(ψu, ψc, ψc) end -# This seems to come from "SURFACE FLUXES FOR PRACTITIONERS OF GLOBAL OCEAN DATA ASSIMILATION" -# Of William Large, but a couple of coefficients and signs are off. -# Also in that paper momentum and scalar stability functions are different, here they are the same?? -# Fairell et al implement a different formulation with a "convective" and "stable" stability function @inline function (ψ::SimilarityFunction{<:Momentum})(ζ) ζ⁻ = min(zero(ζ), ζ) @@ -468,16 +472,12 @@ end return Δh, Δu, Δv, Δθ, Δq end -@inline roughness_length(ℓ, Σ★, args...) = ℓ(Σ★, args...) -@inline roughness_length(ℓ::Number, Σ★, args...) = ℓ - -@inline roughness_length(ℓ, ℓu, Σ★, args...) = ℓ(Σ★, args...) -@inline roughness_length(ℓ::Number, ℓu, Σ★, args...) = ℓ +@inline roughness_length(ℓ, u★, args...) = ℓ(u★, args...) +@inline roughness_length(ℓ::Number, args...) = ℓ @inline function refine_characteristic_scales(estimated_characteristic_scales, velocity_scale, - roughness_lengths, - similarity_functions, + similarity_theory, surface_state, differences, thermodynamics_parameters, @@ -491,20 +491,21 @@ end uτ = velocity_scale # Similarity functions from Businger et al. (1971) - ψu = similarity_functions.momentum - ψθ = similarity_functions.temperature - ψq = similarity_functions.water_vapor + ψu = similarity_theory.similarity_functions.momentum + ψθ = similarity_theory.similarity_functions.temperature + ψq = similarity_theory.similarity_functions.water_vapor # Extract roughness lengths - ℓu = roughness_lengths.momentum - ℓθ = roughness_lengths.temperature - ℓq = roughness_lengths.water_vapor + ℓu = similarity_theory.roughness_lengths.momentum + ℓθ = similarity_theory.roughness_lengths.temperature + ℓq = similarity_theory.roughness_lengths.water_vapor h = differences.h ϰ = von_karman_constant ℂ = thermodynamics_parameters g = gravitational_acceleration 𝒬ₒ = surface_state.ts # thermodynamic state + zᵢ = similarity_theory.planetary_boundary_layer_height # Compute Monin-Obukhov length scale depending on a `buoyancy flux` b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, ℂ, g) @@ -534,7 +535,7 @@ end # Dissipation characteristic scale for gustiness ε★ = - u★ * b★ - uᴳ = 1.2 * cbrt(ε★ * 600) + uᴳ = 1.2 * cbrt(ε★ * zᵢ) # New velocity difference accounting for gustiness uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) From 0f3da21804f33f1bf35fbf9275ea4fd7629bde38 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 17:12:27 -0400 Subject: [PATCH 374/716] 10 meters --- src/DataWrangling/JRA55.jl | 8 +++++--- .../CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index b8f3ab6d..55fdce9a 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -566,7 +566,7 @@ JRA55_prescribed_atmosphere(arch::Distributed, time_indices=Colon(); kw...) = function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, time_indexing = Cyclical(), - measurement_height = 2, # meters + measurement_height = 10, # meters other_kw...) if isnothing(backend) # apply a default @@ -615,12 +615,14 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qs, longwave=Ql) - atmosphere = PrescribedAtmosphere(times, eltype(ua); + FT = eltype(ua) + + atmosphere = PrescribedAtmosphere(times, FT; velocities, freshwater_flux, tracers, downwelling_radiation, - measurement_height, + convert(FT, measurement_height), pressure) return atmosphere diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 55296151..e6fb88d1 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -437,8 +437,8 @@ end end # Fallback for a `Nothing` radiation scheme -@inline net_upwelling_radiation(i, j, grid, time, ::Nothing, Tₒ) = zero(0) -@inline net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, ::Nothing) = zero(0) +@inline net_upwelling_radiation(i, j, grid, time, ::Nothing, Tₒ) = zero(grid) +@inline net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, ::Nothing) = zero(grid) @inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) α = stateindex(radiation.reflection.ocean, i, j, 1, grid, time) From a5bc9cfea0aa4b8bc0f7e18d7e6f746faa782595 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 17:15:27 -0400 Subject: [PATCH 375/716] bugfix --- 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 55fdce9a..6d2a088a 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -616,13 +616,14 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qs, longwave=Ql) FT = eltype(ua) + measurement_height = convert(FT, measurement_height) atmosphere = PrescribedAtmosphere(times, FT; velocities, freshwater_flux, tracers, downwelling_radiation, - convert(FT, measurement_height), + measurement_height, pressure) return atmosphere From 68ea2ebdf6a67b3ae0e83dd11791d7a4bc70d51d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 17:15:33 -0400 Subject: [PATCH 376/716] correct one --- .../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 6716b5fd..4bad0eb9 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -582,7 +582,7 @@ end function GravityMomentumRoughnessLength(FT=Float64; gravitational_acceleration = default_gravitational_acceleration, - maximum_roughness_length = 5e-3, # An estimate? + maximum_roughness_length = Inf, # An estimate? air_kinematic_viscosity = temperature_dependent_viscosity, gravity_wave_parameter = 0.011, laminar_parameter = 0.11) From 1b74321867a595e81f0c8cebf876bf4355c2646c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 17:45:20 -0400 Subject: [PATCH 377/716] add a maximum --- .../similarity_theory_turbulent_fluxes.jl | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 4bad0eb9..477566a9 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -512,16 +512,20 @@ end # Monin-Obhukov characteristic length scale and non-dimensional height L★ = ifelse(b★ == 0, zero(b★), - u★^2 / (ϰ * b★)) - + # Compute roughness length scales ℓu₀ = roughness_length(ℓu, u★, 𝒬ₒ, ℂ) ℓq₀ = roughness_length(ℓq, ℓu₀, u★, 𝒬ₒ, ℂ) ℓθ₀ = roughness_length(ℓθ, ℓu₀, u★, 𝒬ₒ, ℂ) # Transfer coefficients at height `h` - Cu = ϰ / (log(h / ℓu₀) - ψu(h / L★) + ψu(ℓu₀ / L★)) - Cθ = ϰ / (log(h / ℓq₀) - ψθ(h / L★) + ψθ(ℓq₀ / L★)) - Cq = ϰ / (log(h / ℓθ₀) - ψq(h / L★) + ψq(ℓθ₀ / L★)) + χu = ϰ / (log(h / ℓu₀) - ψu(h / L★) + ψu(ℓu₀ / L★)) + χθ = ϰ / (log(h / ℓq₀) - ψθ(h / L★) + ψθ(ℓq₀ / L★)) + χq = ϰ / (log(h / ℓθ₀) - ψq(h / L★) + ψq(ℓθ₀ / L★)) + + if χu < 0 + @show h, χu, u★, h, ℓu₀, L★ + end Δu = differences.u Δv = differences.v @@ -529,9 +533,9 @@ end Δq = differences.q # u★ including gustiness - u★ = Cu * uτ - θ★ = Cθ * Δθ - q★ = Cq * Δq + u★ = χu * uτ + θ★ = χθ * Δθ + q★ = χq * Δq # Dissipation characteristic scale for gustiness ε★ = - u★ * b★ @@ -582,7 +586,7 @@ end function GravityMomentumRoughnessLength(FT=Float64; gravitational_acceleration = default_gravitational_acceleration, - maximum_roughness_length = Inf, # An estimate? + maximum_roughness_length = 1.0, # An estimate? air_kinematic_viscosity = temperature_dependent_viscosity, gravity_wave_parameter = 0.011, laminar_parameter = 0.11) From f942fec698eca2f66bb438bb179c3c0281f73b28 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 20:24:12 -0400 Subject: [PATCH 378/716] remove show --- .../CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 477566a9..aea0a261 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -523,10 +523,6 @@ end χθ = ϰ / (log(h / ℓq₀) - ψθ(h / L★) + ψθ(ℓq₀ / L★)) χq = ϰ / (log(h / ℓθ₀) - ψq(h / L★) + ψq(ℓθ₀ / L★)) - if χu < 0 - @show h, χu, u★, h, ℓu₀, L★ - end - Δu = differences.u Δv = differences.v Δθ = differences.θ From f5a78fad696dbf5cca5b76b8494ac6825cfdf1f0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Apr 2024 21:59:55 -0400 Subject: [PATCH 379/716] this works --- .../CrossRealmFluxes/CrossRealmFluxes.jl | 1 + .../ocean_sea_ice_surface_fluxes.jl | 3 + .../similarity_theory_turbulent_fluxes.jl | 197 ++++++------------ .../CrossRealmFluxes/stability_functions.jl | 81 +++++++ .../PrescribedAtmospheres.jl | 5 +- 5 files changed, 150 insertions(+), 137 deletions(-) create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index cadd20c8..ae9e2df9 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -63,6 +63,7 @@ end include("three_dimensional_operators.jl") include("radiation.jl") include("latitude_dependent_albedo.jl") +include("stability_functions.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") include("sea_ice_ocean_fluxes.jl") diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index e6fb88d1..4dbb8aa2 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -195,6 +195,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_backend, atmosphere_time_indexing, atmosphere.measurement_height, # height at which the state is known + atmosphere.boundary_layer_height, atmosphere.thermodynamics_parameters) launch!(arch, grid, kernel_parameters, _assemble_atmosphere_ocean_fluxes!, @@ -247,6 +248,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing atmos_backend, atmos_time_indexing, atmosphere_measurement_height, + atmosphere_boundary_layer_height, atmos_thermodynamics_parameters) i, j = @index(Global, NTuple) @@ -321,6 +323,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing turbulent_fluxes = compute_similarity_theory_fluxes(similarity_theory, dynamic_ocean_state, dynamic_atmos_state, + atmosphere_boundary_layer_height, ℂₐ, g, ϰ) kᴺ = size(grid, 3) # index of the top ocean cell diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index aea0a261..390cea6d 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -32,10 +32,9 @@ import SurfaceFluxes.Parameters: struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, R, F} <: AbstractSurfaceFluxesParameters gravitational_acceleration :: FT von_karman_constant :: FT - planetary_boundary_layer_height :: FT turbulent_prandtl_number :: FT bulk_velocity_scale :: ΔU - similarity_functions :: UF + stability_functions :: UF thermodynamics_parameters :: TP water_vapor_saturation :: S water_mole_fraction :: W @@ -45,7 +44,7 @@ end const STTF = SimilarityTheoryTurbulentFluxes @inline thermodynamics_params(fluxes::STTF) = fluxes.thermodynamics_parameters -@inline uf_params(fluxes::STTF) = fluxes.similarity_functions +@inline uf_params(fluxes::STTF) = fluxes.stability_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) @@ -54,10 +53,9 @@ const STTF = SimilarityTheoryTurbulentFluxes Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), adapt(to, fluxes.von_karman_constant), - adapt(to, fluxes.planetary_boundary_layer_height), adapt(to, fluxes.turbulent_prandtl_number), nothing, # adapt(to, fluxes.bulk_velocity_scale), - adapt(to, fluxes.similarity_functions), + adapt(to, fluxes.stability_functions), adapt(to, fluxes.thermodynamics_parameters), nothing, #adapt(to, fluxes.water_vapor_saturation), nothing, #adapt(to, fluxes.water_mole_fraction), @@ -113,9 +111,8 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; gravitational_acceleration = default_gravitational_acceleration, bulk_velocity_scale = nothing, von_karman_constant = convert(FT, 0.4), - planetary_boundary_layer_height = convert(FT, 600), turbulent_prandtl_number = convert(FT, 1), - similarity_functions = businger_similarity_functions(FT), + stability_functions = default_stability_functions(FT), thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), @@ -124,10 +121,9 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), convert(FT, von_karman_constant), - convert(FT, planetary_boundary_layer_height), convert(FT, turbulent_prandtl_number), bulk_velocity_scale, - similarity_functions, + stability_functions, thermodynamics_parameters, water_vapor_saturation, water_mole_fraction, @@ -219,19 +215,6 @@ end return (1 - s) / (1 - s + α * s) end -##### -##### 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) - ##### ##### Fixed-point iteration for roughness length ##### @@ -239,32 +222,40 @@ SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature @inline function compute_similarity_theory_fluxes(similarity_theory, surface_state, atmos_state, + atmos_boundary_layer_height, thermodynamics_parameters, gravitational_acceleration, von_karman_constant) # Prescribed difference between two states ℂₐ = thermodynamics_parameters - Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, surface_state) + Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, surface_state, gravitational_acceleration) differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) # Initial guess for the characteristic scales u★, θ★, q★. - Σ★ = initial_guess(differences, - similarity_theory, - gravitational_acceleration, - von_karman_constant, - ℂₐ, atmos_state.ts) + # also provides the initial stability parameter (or non-dimensional height) `ζ₀`. + Σ★, ζ₀ = initial_guess(differences, + similarity_theory, + atmos_boundary_layer_height, + gravitational_acceleration, + von_karman_constant, + ℂₐ, atmos_state.ts) # The inital velocity scale assumes that # the gustiness velocity `uᴳ` is equal to 0.5 ms⁻¹. # That will be refined later on. uτ = sqrt(Δu^2 + Δv^2 + 0.25) - for _ in 1:10 + # In case ζ₀ > 50 we have a very stable boundary layer with a MO length + # extremely thin with respect to `h`. In this case we use the first iteration + niter = ifelse(ζ₀ > 50, 1, 10) + + for _ in 1:niter Σ★, uτ = refine_characteristic_scales(Σ★, uτ, similarity_theory, surface_state, differences, + atmos_boundary_layer_height, thermodynamics_parameters, gravitational_acceleration, von_karman_constant) @@ -274,9 +265,10 @@ SimilarityScales(momentum, temperature) = SimilarityScales(momentum, temperature θ★ = Σ★.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) + # `u★² ≡ sqrt(τx² + τy²)` + # We remove the gustiness by dividing by `uτ` + τx = - u★^2 * Δu / uτ + τy = - u★^2 * Δv / uτ 𝒬ₐ = atmos_state.ts ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) @@ -296,6 +288,7 @@ end @inline function initial_guess(differences, similarity_theory, + atmos_boundary_layer_height, gravitational_acceleration, von_karman_constant, ℂₐ, 𝒬ₐ) @@ -311,7 +304,7 @@ end # Extract roughness lengths ℓu = similarity_theory.roughness_lengths.momentum - zᵢ = similarity_theory.planetary_boundary_layer_height + zᵢ = atmos_boundary_layer_height # assuming the initial gustiness is `0.5` ms⁻¹ uᴳ = 0.5 @@ -324,127 +317,55 @@ end ℓu₀ = roughness_length(ℓu, u★, 𝒬ₐ, ℂₐ) # Initial neutral coefficients at 10 meter height - Cuₙ = (ϰ / log(10 / ℓu₀))^2 - Cθₙ = 0.00115 / sqrt(Cuₙ) + χuₙ = (ϰ / log(10 / ℓu₀))^2 + χcₙ = 0.00115 / sqrt(χuₙ) - # Initial thermal roughness length - ℓθ₀ = 10 / exp(ϰ / Cθₙ) + # Initial scalar roughness length + ℓθ₀ = 10 / exp(ϰ / χcₙ) # Neutral transfer coefficients at height `h` - Cu = (ϰ / log(h / ℓu₀))^2 - Cθ = (ϰ / log(h / ℓθ₀))^2 - + χu = (ϰ / log(h / ℓu₀))^2 + χq = ϰ / log(h / ℓθ₀) + χc = ϰ * χq / χu + # Similarity functions from Businger et al. (1971) - ψu = similarity_theory.similarity_functions.momentum - ψθ = similarity_theory.similarity_functions.temperature - ψq = similarity_theory.similarity_functions.water_vapor + ψu = InitialMomentumStabilityFunction() + ψθ = similarity_theory.stability_functions.temperature + ψq = similarity_theory.stability_functions.water_vapor # Bulk Flux Richardson number - Ribcu = - h / zᵢ / 0.004 / 1.2^3 # - h / zi / 0.004 / β^3 - b★ = buoyancy_scale(Δθ, Δq, 𝒬ₐ, ℂₐ, g) - Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) - ζ = ϰ * Cθ / Cu * Ribcu / (1 + Ri / Ribcu) + b★ = buoyancy_scale(Δθ, Δq, 𝒬ₐ, ℂₐ, g) + Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) + Riᶜ = - h / zᵢ / 0.004 / 1.2^3 # - h / zi / 0.004 / β^3 - L10 = ifelse(ζ == 0, zero(ζ), h / ζ) + # Calculating the first stability coefficient and the MO length at 10 meters + ζ10 = ifelse(Ri < 0, χc * Ri / (1 + Ri / Riᶜ), χc * Ri * (1 + 27 / 9 * Ri / χc)) + L10 = ifelse(ζ10 == 0, zero(ζ10), h / ζ10) - u★ = uτ * ϰ / (log(h / ℓu₀) - ψu(h / L10) + ψu(ℓu₀ / L10)) - θ★ = Δθ * ϰ / (log(h / ℓθ₀) - ψθ(h / L10) + ψθ(ℓθ₀ / L10)) - q★ = Δq * ϰ / (log(h / ℓθ₀) - ψq(h / L10) + ψq(ℓθ₀ / L10)) + u★ = uτ * ϰ / (log(h / ℓu₀) - ψu(h / L10)) # + ψu(ℓu₀ / L10)) + θ★ = Δθ * ϰ / (log(h / ℓθ₀) - ψθ(h / L10)) # + ψθ(ℓθ₀ / L10)) + q★ = Δq * ϰ / (log(h / ℓθ₀) - ψq(h / L10)) # + ψq(ℓθ₀ / L10)) - return SimilarityScales(u★, θ★, q★) -end - -struct Momentum end -struct Scalar end - -struct SimilarityFunction{M, FT, C, D} - a :: FT - b :: FT - c :: C - d :: D - - SimilarityFunction{M}(a::FT, b::FT, c::C, d::D) where {M, FT, C, D} = new{M, FT, C, D}(a, b, c, d) -end - -Adapt.adapt_structure(to, ψ::SimilarityFunction{M}) where M = SimilarityFunction{M}(ψ.a, ψ.b, ψ.c, ψ.d) - -function businger_similarity_functions(FT = Float64) - - # Computed from Businger et al. (1971) - # ψu = SimilarityFunction{Momentum}(4.7, 15.0, OneQuarter()) - # ψc = SimilarityFunction{Scalar}(6.35, 9.0, OneHalf()) - - ψu = SimilarityFunction{Momentum}(0.7, 0.75, 5.0, 0.35) - ψc = SimilarityFunction{Scalar}(6.35, 2/3, 0.35, 1.0) - - return SimilarityScales(ψu, ψc, ψc) + return SimilarityScales(u★, θ★, q★), ζ10 end -@inline function (ψ::SimilarityFunction{<:Momentum})(ζ) - - ζ⁻ = min(zero(ζ), ζ) - ζ⁺ = max(zero(ζ), ζ) - dζ = min(50, 0.35 * ζ⁺) - - ψ_stable = - 0.7 * ζ⁺ - 3 / 4 * (ζ⁺ - 5 / 0.35) * exp(-dζ) - 3 / 4 * 5 / 0.35 - - fₘ = sqrt(sqrt(1 - 15 * ζ⁻)) - ψ_unstable_1 = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2; - - fₘ = cbrt(1 - 10.15 * ζ⁻) - ψ_unstable_2 = 1.5 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3))+ π / sqrt(3) - - f⁻ = ζ⁻^2 / (1 + ζ⁻^2) - ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 - - return ifelse(ζ < 0, ψ_unstable, ψ_stable) -end - -@inline function (ψ::SimilarityFunction{<:Scalar})(ζ) - - ζ⁻ = min(zero(ζ), ζ) - ζ⁺ = max(zero(ζ), ζ) - dζ = min(50, 0.35 * ζ⁺) - - ψ_stable = - (4 * ζ⁺ / 3)^(3 / 2) - 2 / 3 * (ζ⁺ - 14.28) * exp(-dζ) - 8.525 - - fₕ = sqrt(1 - 15 * ζ⁻) - ψ_unstable_1 = 2 * log((1 + fₕ) / 2) - - fₕ = cbrt(1 - 34.15 * ζ⁻) - ψ_unstable_2 = 1.5 * log((1 + fₕ + fₕ^2) / 3) - sqrt(3) * atan((1 + 2fₕ) / sqrt(3))+ π / sqrt(3) - - f⁻ = ζ⁻^2 / (1 + ζ⁻^2) - ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 - - return ifelse(ζ < 0, ψ_unstable, ψ_stable) -end - -struct OneQuarter end -struct OneHalf end - -import Base: ^ -@inline ^(x, ::OneQuarter) = sqrt(sqrt(x)) -@inline ^(x, ::OneHalf) = sqrt(x) - # The M-O characteristic length is calculated as # L★ = - u★² / (κ ⋅ b★) # where b★ is the characteristic buoyancy scale calculated from this function @inline function buoyancy_scale(θ★, q★, 𝒬, ℂ, g) 𝒯₀ = AtmosphericThermodynamics.virtual_temperature(ℂ, 𝒬) - θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬) ε = AtmosphericThermodynamics.Parameters.molmass_ratio(ℂ) δ = ε - 1 # typically equal to 0.608 # Where does this come from? Probably Fairell et al. 1996, - b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * θ₀ * q★) + b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * 𝒯₀ * q★) / (1 + δ * q₀) return b★ end -@inline function state_differences(ℂ, 𝒰₁, 𝒰₀) +@inline function state_differences(ℂ, 𝒰₁, 𝒰₀, g) z₁ = 𝒰₁.z z₀ = 𝒰₀.z Δh = z₁ - z₀ @@ -463,7 +384,10 @@ end θ₁ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₁) θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₀) - Δθ = θ₁ - θ₀ + cₚ = AtmosphericThermodynamics.cp_m(ℂ, 𝒬₁) # moist heat capacity + + # The temperature difference includes the ``lapse rate'' α = g / h + Δθ = θ₁ - θ₀ + g / cₚ * Δh q₁ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₁) q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₀) @@ -480,6 +404,7 @@ end similarity_theory, surface_state, differences, + atmos_boundary_layer_height, thermodynamics_parameters, gravitational_acceleration, von_karman_constant) @@ -491,9 +416,9 @@ end uτ = velocity_scale # Similarity functions from Businger et al. (1971) - ψu = similarity_theory.similarity_functions.momentum - ψθ = similarity_theory.similarity_functions.temperature - ψq = similarity_theory.similarity_functions.water_vapor + ψu = similarity_theory.stability_functions.momentum + ψθ = similarity_theory.stability_functions.temperature + ψq = similarity_theory.stability_functions.water_vapor # Extract roughness lengths ℓu = similarity_theory.roughness_lengths.momentum @@ -505,7 +430,7 @@ end ℂ = thermodynamics_parameters g = gravitational_acceleration 𝒬ₒ = surface_state.ts # thermodynamic state - zᵢ = similarity_theory.planetary_boundary_layer_height + zᵢ = atmos_boundary_layer_height # Compute Monin-Obukhov length scale depending on a `buoyancy flux` b★ = buoyancy_scale(θ★, q★, 𝒬ₒ, ℂ, g) @@ -519,9 +444,9 @@ end ℓθ₀ = roughness_length(ℓθ, ℓu₀, u★, 𝒬ₒ, ℂ) # Transfer coefficients at height `h` - χu = ϰ / (log(h / ℓu₀) - ψu(h / L★) + ψu(ℓu₀ / L★)) - χθ = ϰ / (log(h / ℓq₀) - ψθ(h / L★) + ψθ(ℓq₀ / L★)) - χq = ϰ / (log(h / ℓθ₀) - ψq(h / L★) + ψq(ℓθ₀ / L★)) + χu = ϰ / (log(h / ℓu₀) - ψu(h / L★)) # + ψu(ℓu₀ / L★)) + χθ = ϰ / (log(h / ℓq₀) - ψθ(h / L★)) # + ψθ(ℓq₀ / L★)) + χq = ϰ / (log(h / ℓθ₀) - ψq(h / L★)) # + ψq(ℓθ₀ / L★)) Δu = differences.u Δv = differences.v diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl new file mode 100644 index 00000000..8faefb3d --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -0,0 +1,81 @@ +##### +##### 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 MomentumStabilityFunction end +struct ScalarStabilityFunction end +struct InitialMomentumStabilityFunction end + +function default_stability_functions(FT = Float64) + + # Computed from Edisen et al. (2013) + ψu = MomentumStabilityFunction() + ψc = ScalarStabilityFunction() + + return SimilarityScales(ψu, ψc, ψc) +end + +@inline function (ψ::InitialMomentumStabilityFunction)(ζ) + ζ⁻ = min(zero(ζ), ζ) + ζ⁺ = max(zero(ζ), ζ) + dζ = min(50, 0.35 * ζ⁺) + + ψ_stable = - ζ⁺ - 3 / 4 * (ζ⁺ - 5 / 0.35) * exp(-dζ) - 3 / 4 * 5 / 0.35 + + fₘ = sqrt(sqrt(1 - 18 * ζ⁻)) + ψ_unstable_1 = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2; + + fₘ = cbrt(1 - 10 * ζ⁻) + ψ_unstable_2 = 1.5 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3))+ π / sqrt(3) + + f⁻ = ζ⁻^2 / (1 + ζ⁻^2) + ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 + + return ifelse(ζ < 0, ψ_unstable, ψ_stable) +end + +@inline function (ψ::MomentumStabilityFunction)(ζ) + + ζ⁻ = min(zero(ζ), ζ) + ζ⁺ = max(zero(ζ), ζ) + dζ = min(50, 0.35 * ζ⁺) + + ψ_stable = - 0.7 * ζ⁺ - 3 / 4 * (ζ⁺ - 5 / 0.35) * exp(-dζ) - 3 / 4 * 5 / 0.35 + + fₘ = sqrt(sqrt(1 - 15 * ζ⁻)) + ψ_unstable_1 = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2; + + fₘ = cbrt(1 - 10.15 * ζ⁻) + ψ_unstable_2 = 1.5 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3))+ π / sqrt(3) + + f⁻ = ζ⁻^2 / (1 + ζ⁻^2) + ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 + + return ifelse(ζ < 0, ψ_unstable, ψ_stable) +end + +@inline function (ψ::ScalarStabilityFunction)(ζ) + + ζ⁻ = min(zero(ζ), ζ) + ζ⁺ = max(zero(ζ), ζ) + dζ = min(50, 0.35 * ζ⁺) + + ψ_stable = - (4 * ζ⁺ / 3)^(3 / 2) - 2 / 3 * (ζ⁺ - 14.28) * exp(-dζ) - 8.525 + + fₕ = sqrt(1 - 15 * ζ⁻) + ψ_unstable_1 = 2 * log((1 + fₕ) / 2) + + fₕ = cbrt(1 - 34.15 * ζ⁻) + ψ_unstable_2 = 1.5 * log((1 + fₕ + fₕ^2) / 3) - sqrt(3) * atan((1 + 2fₕ) / sqrt(3))+ π / sqrt(3) + + f⁻ = ζ⁻^2 / (1 + ζ⁻^2) + ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 + + return ifelse(ζ < 0, ψ_unstable, ψ_stable) +end diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index e8451881..6edffae3 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -297,6 +297,7 @@ struct PrescribedAtmosphere{G, U, P, C, F, R, TP, TI, FT} thermodynamics_parameters :: TP times :: TI measurement_height :: FT + boundary_layer_height :: FT end Base.summary(::PrescribedAtmosphere) = "PrescribedAtmosphere" @@ -317,6 +318,7 @@ state with data given at `times`. function PrescribedAtmosphere(times, FT=Float64; measurement_height, velocities = nothing, + boundary_layer_height = convert(FT, 600), pressure = nothing, freshwater_flux = nothing, downwelling_radiation = nothing, @@ -337,7 +339,8 @@ function PrescribedAtmosphere(times, FT=Float64; downwelling_radiation, thermodynamics_parameters, times, - convert(FT, measurement_height)) + convert(FT, measurement_height), + convert(FT, boundary_layer_height)) end update_model_field_time_series!(::Nothing, time) = nothing From b179f8705b276c68865ffb1a360345a1ea2547d4 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 30 Apr 2024 09:36:41 -0400 Subject: [PATCH 380/716] fix ocean simulations --- src/OceanSimulations/OceanSimulations.jl | 51 ------------------------ 1 file changed, 51 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 4529acf0..42ee32a6 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -1,6 +1,5 @@ module OceanSimulations -<<<<<<< HEAD export load_balanced_regional_grid, ocean_simulation using Oceananigans.Units @@ -8,8 +7,6 @@ using Oceananigans.Advection: TracerAdvection using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.ImmersedBoundaries: immersed_peripheral_node, inactive_node -======= ->>>>>>> origin/main using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity, MixingLength, @@ -19,18 +16,12 @@ using SeawaterPolynomials.TEOS10: TEOS10EquationOfState using Oceananigans.BuoyancyModels: g_Earth using Oceananigans.Coriolis: Ω_Earth -<<<<<<< HEAD using Oceananigans.Operators include("load_balanced_regional_grid.jl") # Some defaults default_free_surface(grid) = SplitExplicitFreeSurface(grid; cfl=0.7) -======= - -# Some defualts -default_free_surface(grid) = SplitExplicitFreeSurface(cfl=0.7; grid) ->>>>>>> origin/main function default_ocean_closure() mixing_length = MixingLength(Cᵇ=0.01) @@ -38,7 +29,6 @@ function default_ocean_closure() return CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) end -<<<<<<< HEAD default_momentum_advection() = VectorInvariant(; vorticity_scheme = WENO(; order = 9), vertical_scheme = Centered(), divergence_scheme = WENO()) @@ -67,24 +57,15 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), # 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; Δt = 5minutes, -======= -# 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; ->>>>>>> origin/main closure = default_ocean_closure(), free_surface = default_free_surface(grid), reference_density = 1020, rotation_rate = Ω_Earth, -<<<<<<< HEAD gravitational_acceleration = g_Earth, drag_coefficient = 0.003, momentum_advection = default_momentum_advection(), tracer_advection = default_tracer_advection(), verbose = false) -======= - gravitational_acceleration = g_Earth) ->>>>>>> origin/main # Set up boundary conditions using Field top_zonal_momentum_flux = Jᵘ = Field{Face, Center, Nothing}(grid) @@ -92,7 +73,6 @@ function ocean_simulation(grid; top_ocean_heat_flux = Jᵀ = Field{Center, Center, Nothing}(grid) top_salt_flux = Jˢ = Field{Center, Center, Nothing}(grid) -<<<<<<< HEAD u_bot_bc = FluxBoundaryCondition(u_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) v_bot_bc = FluxBoundaryCondition(v_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) @@ -105,50 +85,25 @@ function ocean_simulation(grid; Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) forcing = (; u = Fu, v = Fv) -======= - ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵘ)), - v = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵛ)), - T = FieldBoundaryConditions(top=FluxBoundaryCondition(Jᵀ)), - S = FieldBoundaryConditions(top=FluxBoundaryCondition(Jˢ))) ->>>>>>> origin/main # Use the TEOS10 equation of state teos10 = TEOS10EquationOfState(; reference_density) buoyancy = SeawaterBuoyancy(; gravitational_acceleration, equation_of_state=teos10) # Minor simplifications for single column grids -<<<<<<< HEAD Nx, Ny, _ = size(grid) if Nx == Ny == 1 # single column grid tracer_advection = nothing momentum_advection = nothing -======= - 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()) ->>>>>>> origin/main end tracers = (:T, :S) if closure isa CATKEVerticalDiffusivity tracers = tuple(tracers..., :e) -<<<<<<< HEAD tracer_advection = (; T = tracer_advection, S = tracer_advection, e = nothing) end coriolis = HydrostaticSphericalCoriolis(; rotation_rate, scheme = ActiveCellEnstrophyConserving()) -======= - end - - coriolis = HydrostaticSphericalCoriolis(; rotation_rate) ->>>>>>> origin/main ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, @@ -158,16 +113,10 @@ function ocean_simulation(grid; tracers, free_surface, coriolis, -<<<<<<< HEAD forcing, boundary_conditions = ocean_boundary_conditions) ocean = Simulation(ocean_model; Δt, verbose) -======= - boundary_conditions = ocean_boundary_conditions) - - ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) ->>>>>>> origin/main return ocean end From e52a08f19ba69314c9eeb00d01f28a2c7b0fe725 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 30 Apr 2024 19:44:38 -0400 Subject: [PATCH 381/716] change manifests --- Manifest.toml | 63 ------------ docs/Manifest.toml | 242 --------------------------------------------- 2 files changed, 305 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 15c8d96d..09fe750a 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,11 +2,7 @@ julia_version = "1.10.2" manifest_format = "2.0" -<<<<<<< HEAD project_hash = "eef01b615158af2777b0945e4cc529fabc90261f" -======= -project_hash = "b77431445966c6920fb04c6ab1b5a7dbdaa668aa" ->>>>>>> origin/main [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -56,24 +52,15 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] -<<<<<<< HEAD git-tree-sha1 = "133a240faec6e074e07c31ee75619c90544179cf" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" version = "7.10.0" -======= -git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.9.0" ->>>>>>> origin/main [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" ArrayInterfaceCUDAExt = "CUDA" -<<<<<<< HEAD ArrayInterfaceCUDSSExt = "CUDSS" -======= ->>>>>>> origin/main ArrayInterfaceChainRulesExt = "ChainRules" ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" ArrayInterfaceReverseDiffExt = "ReverseDiff" @@ -84,10 +71,7 @@ version = "7.9.0" BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" -<<<<<<< HEAD CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" -======= ->>>>>>> origin/main ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" @@ -181,15 +165,12 @@ git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" version = "0.11.1+0" -<<<<<<< HEAD [[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" -======= ->>>>>>> origin/main [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" @@ -202,7 +183,6 @@ weakdeps = ["SparseArrays"] [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -<<<<<<< HEAD git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" repo-rev = "main" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" @@ -215,12 +195,6 @@ git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" version = "0.1.12" -======= -git-tree-sha1 = "e25e43451edd449c3dcc899bd447983d7b76a59f" -uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.1.0" - ->>>>>>> origin/main [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" @@ -351,17 +325,10 @@ uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" version = "1.5.0" [[deps.DataStructures]] -<<<<<<< HEAD deps = ["Compat", "InteractiveUtils", "OrderedCollections"] git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" version = "0.18.20" -======= -deps = ["InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "88d48e133e6d3dd68183309877eac74393daa7eb" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.17.20" ->>>>>>> origin/main [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -477,15 +444,12 @@ git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.8.4" -<<<<<<< HEAD [[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" -======= ->>>>>>> origin/main [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" @@ -496,7 +460,6 @@ weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] ForwardDiffStaticArraysExt = "StaticArrays" -<<<<<<< HEAD [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" @@ -509,8 +472,6 @@ git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" uuid = "559328eb-81f9-559d-9380-de523a88c83c" version = "1.0.10+0" -======= ->>>>>>> origin/main [[deps.Future]] deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" @@ -560,15 +521,12 @@ deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Nettle_jll", "P11Kit_jl git-tree-sha1 = "383db7d3f900f4c1f47a8a04115b053c095e48d3" uuid = "0951126a-58fd-58f1-b5b3-b08c7c4a876d" version = "3.8.4+0" -<<<<<<< HEAD [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" version = "1.3.14+0" -======= ->>>>>>> origin/main [[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"] @@ -581,7 +539,6 @@ deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapp git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" version = "1.10.5" -<<<<<<< HEAD [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -594,8 +551,6 @@ deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" version = "0.1.16" -======= ->>>>>>> origin/main [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1360,15 +1315,12 @@ weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" -<<<<<<< HEAD [[deps.StackViews]] deps = ["OffsetArrays"] git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" version = "0.1.1" -======= ->>>>>>> origin/main [[deps.Static]] deps = ["IfElse"] git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" @@ -1528,17 +1480,11 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -<<<<<<< HEAD git-tree-sha1 = "ed1a35a4b608024f60b71f92930ca9e64d55068c" repo-rev = "glw/density-example" repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" version = "0.12.4" -======= -git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" -uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.12.6" ->>>>>>> origin/main [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" @@ -1546,7 +1492,6 @@ version = "0.12.6" [deps.Thermodynamics.weakdeps] ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" -<<<<<<< HEAD [[deps.ThreadingUtilities]] deps = ["ManualMemory"] git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" @@ -1559,8 +1504,6 @@ git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" version = "0.5.0" -======= ->>>>>>> origin/main [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" @@ -1625,22 +1568,18 @@ deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" version = "2.12.6+0" -<<<<<<< HEAD [[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" -======= ->>>>>>> origin/main [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" version = "5.4.6+0" -<<<<<<< HEAD [[deps.Xorg_libX11_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] @@ -1689,8 +1628,6 @@ deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" version = "1.5.0+0" -======= ->>>>>>> origin/main [[deps.Zlib_jll]] deps = ["Libdl"] diff --git a/docs/Manifest.toml b/docs/Manifest.toml index b9c70192..efc58ea5 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -2,16 +2,12 @@ julia_version = "1.10.2" manifest_format = "2.0" -<<<<<<< HEAD -project_hash = "043decf5ca2c4bac92a6417c1b87d2bdd66286cb" -======= project_hash = "2b1abab6f384a62f893ca939d86c6775549fc57e" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" version = "0.0.1" ->>>>>>> origin/main [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -91,15 +87,12 @@ deps = ["UnsafeAtomics"] git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" version = "0.1.0" -<<<<<<< HEAD -======= [[deps.Automa]] deps = ["PrecompileTools", "TranscodingStreams"] git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" version = "1.0.3" ->>>>>>> origin/main [[deps.BFloat16s]] deps = ["LinearAlgebra", "Printf", "Random", "Test"] @@ -143,19 +136,6 @@ deps = ["Dates", "Printf"] git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" uuid = "179af706-886a-5703-950a-314cd64e0468" version = "0.1.3" -<<<<<<< HEAD - -[[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.CRC32c]] uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" @@ -206,7 +186,6 @@ deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b" uuid = "159f3aea-2a34-519c-b102-8c37f9878175" version = "1.0.5" ->>>>>>> origin/main [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] @@ -214,19 +193,11 @@ git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" version = "0.7.0+1" -<<<<<<< HEAD -[[deps.CUDA_Runtime_Discovery]] -deps = ["Libdl"] -git-tree-sha1 = "2cb12f6b2209f40a4b8967697689a47c50485490" -uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.2.3" -======= [[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" ->>>>>>> origin/main [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] @@ -244,17 +215,6 @@ weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] ChainRulesCoreSparseArraysExt = "SparseArrays" -<<<<<<< HEAD -[[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" - -======= ->>>>>>> origin/main [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" @@ -330,27 +290,17 @@ version = "2.4.1" deps = ["LinearAlgebra"] git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -<<<<<<< HEAD -version = "1.5.4" -======= version = "1.5.5" weakdeps = ["IntervalSets", "StaticArrays"] ->>>>>>> origin/main [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" ConstructionBaseStaticArraysExt = "StaticArrays" -<<<<<<< HEAD - [deps.ConstructionBase.weakdeps] - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -======= [[deps.Contour]] git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" version = "0.6.3" ->>>>>>> origin/main [[deps.Crayons]] git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" @@ -362,15 +312,6 @@ deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "Taylo git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" version = "0.2.5" -<<<<<<< HEAD - -[[deps.CubicSplines]] -deps = ["Random", "Test"] -git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" -uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" -version = "0.2.1" -======= ->>>>>>> origin/main [[deps.DataAPI]] git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" @@ -443,22 +384,17 @@ git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" version = "0.9.3" -<<<<<<< HEAD -======= [[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" ->>>>>>> origin/main [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" -<<<<<<< HEAD -======= [[deps.DualNumbers]] deps = ["Calculus", "NaNMath", "SpecialFunctions"] git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" @@ -471,13 +407,10 @@ git-tree-sha1 = "e3290f2d49e661fbd94046d7e3726ffcb2d41053" uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" version = "2.2.4+0" ->>>>>>> origin/main [[deps.Elliptic]] git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" uuid = "b305315f-e792-5b7a-8f41-49f472929428" version = "1.0.1" -<<<<<<< HEAD -======= [[deps.EnumX]] git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" @@ -494,7 +427,6 @@ deps = ["IntervalArithmetic", "Random", "StaticArraysCore", "Test"] git-tree-sha1 = "276e83bc8b21589b79303b9985c321024ffdf59c" uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" version = "2.2.5" ->>>>>>> origin/main [[deps.ExceptionUnwrapping]] deps = ["Test"] @@ -502,21 +434,16 @@ git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" version = "0.1.10" -<<<<<<< HEAD -======= [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" version = "2.5.0+0" ->>>>>>> origin/main [[deps.ExprTools]] git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" version = "0.1.10" -<<<<<<< HEAD -======= [[deps.Extents]] git-tree-sha1 = "2140cd04483da90b2da7f99b2add0750504fc39c" @@ -528,7 +455,6 @@ deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", git-tree-sha1 = "ab3f7e1819dba9434a3a5126510c8fda3a4e7000" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" version = "6.1.1+0" ->>>>>>> origin/main [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] @@ -557,8 +483,6 @@ version = "1.16.3" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" -<<<<<<< HEAD -======= [[deps.FillArrays]] deps = ["LinearAlgebra"] git-tree-sha1 = "bfe82a708416cf00b73a3198db0859c82f741558" @@ -587,7 +511,6 @@ version = "2.23.0" BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" ->>>>>>> origin/main [[deps.FixedPointNumbers]] deps = ["Statistics"] git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" @@ -612,8 +535,6 @@ uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" deps = ["Artifacts", "Libdl"] uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" version = "6.2.1+6" -<<<<<<< HEAD -======= [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] @@ -638,7 +559,6 @@ deps = ["Extents"] git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" version = "1.3.3" ->>>>>>> origin/main [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] @@ -663,19 +583,6 @@ git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" version = "1.3.1" -<<<<<<< HEAD -[[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" -uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" -version = "1.14.2+1" -======= [[deps.Git_jll]] deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"] git-tree-sha1 = "d18fb8a1f3609361ebda9bf029b60fd0f120c809" @@ -721,7 +628,6 @@ version = "0.9.2" git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" version = "1.0.2" ->>>>>>> origin/main [[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"] @@ -735,9 +641,6 @@ git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" version = "1.10.5" -<<<<<<< HEAD -[[deps.Hwloc_jll]] -======= [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" @@ -798,18 +701,11 @@ uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" version = "0.9.9" [[deps.Imath_jll]] ->>>>>>> origin/main deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" version = "2.10.0+0" -<<<<<<< HEAD -[[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" @@ -820,7 +716,6 @@ version = "0.2.1" git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" version = "1.0.0" ->>>>>>> origin/main [[deps.IncompleteLU]] deps = ["LinearAlgebra", "SparseArrays"] @@ -833,14 +728,11 @@ deps = ["Parsers"] git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" version = "1.4.0" -<<<<<<< HEAD -======= [[deps.IntegerMathUtils]] git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" version = "0.1.2" ->>>>>>> origin/main [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -858,12 +750,6 @@ git-tree-sha1 = "68772f49f54b479fa88ace904f6127f0a3bb2e46" uuid = "3587e190-3f89-42d0-90ee-14403ec27112" version = "0.1.12" -<<<<<<< HEAD -[[deps.InvertedIndices]] -git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" -uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" -version = "1.3.0" -======= [deps.Interpolations.extensions] InterpolationsUnitfulExt = "Unitful" @@ -886,7 +772,6 @@ weakdeps = ["Random", "RecipesBase", "Statistics"] IntervalSetsRandomExt = "Random" IntervalSetsRecipesBaseExt = "RecipesBase" IntervalSetsStatisticsExt = "Statistics" ->>>>>>> origin/main [[deps.InvertedIndices]] git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" @@ -933,10 +818,6 @@ git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" version = "1.14.0" -<<<<<<< HEAD - [deps.JSON3.extensions] - JSON3ArrowExt = ["ArrowTypes"] -======= [[deps.JSON3]] deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" @@ -954,14 +835,11 @@ deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] git-tree-sha1 = "fa6d0bcff8583bac20f1ffa708c3913ca605c611" uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" version = "0.1.5" ->>>>>>> origin/main [deps.JSON3.weakdeps] ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" [[deps.JuliaNVTXCallbacks_jll]] -<<<<<<< HEAD -======= deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" @@ -986,7 +864,6 @@ uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" version = "0.6.8" [[deps.LAME_jll]] ->>>>>>> origin/main deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" @@ -1060,15 +937,12 @@ weakdeps = ["Serialization"] [deps.LRUCache.extensions] SerializationExt = ["Serialization"] -<<<<<<< HEAD -======= [[deps.LZO_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" version = "2.10.1+0" ->>>>>>> origin/main [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" @@ -1112,8 +986,6 @@ git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" version = "1.17.0+0" -<<<<<<< HEAD -======= [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" @@ -1138,7 +1010,6 @@ git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" version = "7.2.0" ->>>>>>> origin/main [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -1222,8 +1093,6 @@ version = "0.5.13" deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" -<<<<<<< HEAD -======= [[deps.MarkdownAST]] deps = ["AbstractTrees", "Markdown"] git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" @@ -1236,7 +1105,6 @@ git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" version = "0.5.7" ->>>>>>> origin/main [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" @@ -1273,19 +1141,11 @@ git-tree-sha1 = "98ca95cf41116a24e46dc9a06fa22b923e8411b7" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" version = "0.14.2" -<<<<<<< HEAD -[[deps.NVTX]] -deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] -git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" -uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" -version = "0.3.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" ->>>>>>> origin/main [[deps.NVTX_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1317,19 +1177,11 @@ git-tree-sha1 = "a8af1798e4eb9ff768ce7fdefc0e957097793f15" uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" version = "400.902.209+0" -<<<<<<< HEAD -[[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.Netpbm]] deps = ["FileIO", "ImageCore", "ImageMetadata"] git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" version = "1.1.1" ->>>>>>> origin/main [[deps.Nettle_jll]] deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1410,8 +1262,6 @@ git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.5+0" -<<<<<<< HEAD -======= [[deps.Optim]] deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] git-tree-sha1 = "d9b79c4eed437421ac4285148fcadf42e0700e89" @@ -1430,7 +1280,6 @@ git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" uuid = "91d4177d-7536-5919-b921-800302f37372" version = "1.3.2+0" ->>>>>>> origin/main [[deps.OrderedCollections]] git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" @@ -1441,14 +1290,11 @@ deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "2cd396108e178f3ae8dedbd8e938a18726ab2fbf" uuid = "c2071276-7c44-58a7-b746-946036e04d0a" version = "0.24.1+0" -<<<<<<< HEAD -======= [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" version = "10.42.0+1" ->>>>>>> origin/main [[deps.PMIx_jll]] deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] @@ -1456,8 +1302,6 @@ git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" version = "4.2.7+0" -<<<<<<< HEAD -======= [[deps.PMIx_jll]] deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] git-tree-sha1 = "8b3b19351fa24791f94d7ae85faf845ca1362541" @@ -1470,14 +1314,11 @@ git-tree-sha1 = "67186a2bc9a90f9f85ff3cc8277868961fb57cbd" uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" version = "0.4.3" ->>>>>>> origin/main [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" version = "1.0.2" weakdeps = ["Requires", "TOML"] -<<<<<<< HEAD -======= [[deps.Packing]] deps = ["GeometryBasics"] @@ -1502,7 +1343,6 @@ deps = ["OrderedCollections", "UnPack"] git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" version = "0.12.3" ->>>>>>> origin/main [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] @@ -1515,8 +1355,6 @@ deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Ree git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" version = "0.19.3" -<<<<<<< HEAD -======= [deps.PencilArrays.extensions] PencilArraysDiffEqExt = ["DiffEqBase"] @@ -1537,7 +1375,6 @@ deps = ["Combinatorics", "LinearAlgebra", "Random"] git-tree-sha1 = "eb3f9df2457819bf0a9019bd93cc451697a0751e" uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" version = "0.4.20" ->>>>>>> origin/main [deps.PencilArrays.extensions] PencilArraysDiffEqExt = ["DiffEqBase"] @@ -1564,8 +1401,6 @@ git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" version = "0.3.3" -<<<<<<< HEAD -======= [[deps.PlotUtils]] deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] git-tree-sha1 = "7b1a9df27f072ac4c9c7cbe5efb198489258d1f5" @@ -1595,21 +1430,17 @@ version = "4.0.6" MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" ->>>>>>> origin/main [[deps.PooledArrays]] deps = ["DataAPI", "Future"] git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" version = "1.4.3" -<<<<<<< HEAD -======= [[deps.PositiveFactorizations]] deps = ["LinearAlgebra"] git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" version = "0.2.4" ->>>>>>> origin/main [[deps.PrecompileTools]] deps = ["Preferences"] @@ -1645,13 +1476,6 @@ git-tree-sha1 = "b437cdb0385ed38312d91d9c00c20f3798b30256" uuid = "49802e3a-d2f1-5c88-81d8-b72133a6f568" version = "1.5.1" -<<<<<<< HEAD -[[deps.Quaternions]] -deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" -uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.6" -======= [[deps.ProgressMeter]] deps = ["Distributed", "Printf"] git-tree-sha1 = "763a8ceb07833dd51bb9e3bbca372de32c0605ad" @@ -1669,7 +1493,6 @@ deps = ["DataStructures", "LinearAlgebra"] git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" version = "2.9.4" ->>>>>>> origin/main [[deps.Quaternions]] deps = ["LinearAlgebra", "Random", "RealDot"] @@ -1690,8 +1513,6 @@ deps = ["Random", "RandomNumbers"] git-tree-sha1 = "4743b43e5a9c4a2ede372de7061eed81795b12e7" uuid = "74087812-796a-5b5d-8853-05524746bad3" version = "1.7.0" -<<<<<<< HEAD -======= [[deps.RandomNumbers]] deps = ["Random", "Requires"] @@ -1703,7 +1524,6 @@ version = "1.5.3" git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" version = "0.3.2" ->>>>>>> origin/main [[deps.RandomNumbers]] deps = ["Random", "Requires"] @@ -1758,15 +1578,6 @@ version = "2.1.2" RootsSymPyExt = "SymPy" RootsSymPyPythonCallExt = "SymPyPythonCall" -<<<<<<< HEAD - [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" - -======= ->>>>>>> origin/main [[deps.Rotations]] deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" @@ -1776,14 +1587,11 @@ weakdeps = ["RecipesBase"] [deps.Rotations.extensions] RotationsRecipesBaseExt = "RecipesBase" -<<<<<<< HEAD -======= [[deps.RoundingEmulator]] git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" uuid = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705" version = "0.2.1" ->>>>>>> origin/main [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" @@ -1809,8 +1617,6 @@ version = "1.4.1" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -<<<<<<< HEAD -======= [[deps.SetRounding]] git-tree-sha1 = "d7a25e439d07a17b7cdf97eecee504c50fedf5f6" uuid = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" @@ -1844,7 +1650,6 @@ git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" version = "0.4.0" ->>>>>>> origin/main [[deps.SimpleBufferStream]] git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" @@ -1940,19 +1745,11 @@ git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" version = "1.7.0" -<<<<<<< HEAD -[[deps.Strided]] -deps = ["LinearAlgebra", "StridedViews", "TupleTools"] -git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" -uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" -version = "2.0.4" -======= [[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" ->>>>>>> origin/main [[deps.StridedViews]] deps = ["LinearAlgebra", "PackageExtensionCompat"] @@ -2061,24 +1858,16 @@ deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] git-tree-sha1 = "1c7170668366821b0c4c4fe03ee78f8d6cf36e2c" uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" version = "0.16.0" -<<<<<<< HEAD -======= weakdeps = ["IntervalArithmetic"] ->>>>>>> origin/main [deps.TaylorSeries.extensions] TaylorSeriesIAExt = "IntervalArithmetic" -<<<<<<< HEAD - [deps.TaylorSeries.weakdeps] - IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -======= [[deps.TensorCore]] deps = ["LinearAlgebra"] git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" version = "0.1.1" ->>>>>>> origin/main [[deps.Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] @@ -2141,14 +1930,11 @@ git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" version = "0.2.1" -<<<<<<< HEAD -======= [[deps.UnsafeAtomics]] git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" version = "0.2.1" ->>>>>>> origin/main [[deps.UnsafeAtomicsLLVM]] deps = ["LLVM", "UnsafeAtomics"] git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" @@ -2159,15 +1945,12 @@ version = "0.1.3" git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" version = "1.3.0" -<<<<<<< HEAD -======= [[deps.WoodburyMatrices]] deps = ["LinearAlgebra", "SparseArrays"] git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" version = "1.0.0" ->>>>>>> origin/main [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] @@ -2175,9 +1958,6 @@ git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" version = "2.12.6+0" -<<<<<<< HEAD -[[deps.XZ_jll]] -======= [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" @@ -2197,7 +1977,6 @@ uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" version = "1.8.6+0" [[deps.Xorg_libXau_jll]] ->>>>>>> origin/main deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "37195dcb94a5970397ad425b95a9a26d0befce3a" uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" @@ -2210,11 +1989,6 @@ version = "1.2.13+1" [[deps.Zstd_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -<<<<<<< HEAD -git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.5+0" -======= git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b" uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" version = "1.5.6+0" @@ -2224,15 +1998,12 @@ deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" version = "0.2.3+0" ->>>>>>> origin/main [[deps.libaec_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "46bf7be2917b59b761247be3f317ddf75e50e997" uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" version = "1.1.2+0" -<<<<<<< HEAD -======= [[deps.libaom_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -2245,7 +2016,6 @@ deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll" git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" version = "0.15.1+0" ->>>>>>> origin/main [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] @@ -2257,14 +2027,6 @@ deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll"] git-tree-sha1 = "f04ec6d9a186115fb38f858f05c0c4e1b7fc9dcb" uuid = "1080aeaf-3a6a-583e-a51c-c537b09f60ec" version = "2.1.13+1" -<<<<<<< HEAD - -[[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.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -2289,7 +2051,6 @@ deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" version = "1.3.7+1" ->>>>>>> origin/main [[deps.libzip_jll]] deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] @@ -2312,8 +2073,6 @@ deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "PMIx_jll", "libevent_ git-tree-sha1 = "5adb2d7a18a30280feb66cad6f1a1dfdca2dc7b0" uuid = "eb928a42-fffd-568d-ab9c-3f5d54fc65b9" version = "3.0.2+0" -<<<<<<< HEAD -======= [[deps.x264_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -2326,4 +2085,3 @@ deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" version = "3.5.0+0" ->>>>>>> origin/main From 6d064c67a5418fbc7de7e9986e0890744003a18c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 30 Apr 2024 22:33:22 -0400 Subject: [PATCH 382/716] guess this is the closest we get! --- .../CrossRealmFluxes/CrossRealmFluxes.jl | 2 + .../CrossRealmFluxes/roughness_lengths.jl | 98 +++++++ .../similarity_theory_turbulent_fluxes.jl | 276 +++++------------- .../CrossRealmFluxes/water_model_fraction.jl | 49 ++++ 4 files changed, 216 insertions(+), 209 deletions(-) create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/water_model_fraction.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index ae9e2df9..31033db7 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -63,7 +63,9 @@ end include("three_dimensional_operators.jl") include("radiation.jl") include("latitude_dependent_albedo.jl") +include("roughness_lengths.jl") include("stability_functions.jl") +include("water_model_fraction.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") include("sea_ice_ocean_fluxes.jl") diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl new file mode 100644 index 00000000..c79fb699 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -0,0 +1,98 @@ +struct GravityMomentumRoughnessLength{FT, V} + gravitational_acceleration :: FT + air_kinematic_viscosity :: V + gravity_wave_parameter :: FT + laminar_parameter :: FT + maximum_roughness_length :: FT +end + +struct GravityScalarRoughnessLength{FT, V, R} + air_kinematic_viscosity :: V + reynolds_number_scaling_function :: R + maximum_roughness_length :: FT +end + +function default_roughness_lengths(FT=Float64) + momentum = GravityMomentumRoughnessLength(FT) + temperature = GravityScalarRoughnessLength(FT) + water_vapor = GravityScalarRoughnessLength(FT) + return SimilarityScales(momentum, temperature, water_vapor) +end + +# Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ / ν` +# Edson et al. (2013), equation (28) +@inline empirical_scaling_function(R★ :: FT, args...) where FT = + ifelse(R★ == 0, FT(0), convert(FT, 5.85e-5 / R★ ^ 0.72)) + +# Assumes that θ comes in in Kelvin +@inline function temperature_dependent_viscosity(θ :: FT) where FT + T = convert(FT, θ - celsius_to_kelvin) + ν = convert(FT, 1.326e-5 * (1 + 6.542e-3 * T + 8.301e-6 * T^2 - 4.84e-9 * T^3)) + + return ν +end + +# Fallbacks for constant roughness length! +@inline roughness_length(ℓ, u★, args...) = ℓ(u★, args...) +@inline roughness_length(ℓ::Number, args...) = ℓ + +function GravityScalarRoughnessLength(FT=Float64; + air_kinematic_viscosity = temperature_dependent_viscosity, + reynolds_number_scaling_function = empirical_scaling_function, + maximum_roughness_length = 1.6e-4) # Values from COARE3.6 + + return GravityScalarRoughnessLength(air_kinematic_viscosity, + reynolds_number_scaling_function, + convert(FT, maximum_roughness_length)) +end + +function GravityMomentumRoughnessLength(FT=Float64; + gravitational_acceleration = default_gravitational_acceleration, + maximum_roughness_length = 1.0, # An estimate? + air_kinematic_viscosity = temperature_dependent_viscosity, + gravity_wave_parameter = 0.011, + laminar_parameter = 0.11) + + return GravityMomentumRoughnessLength(convert(FT, gravitational_acceleration), + air_kinematic_viscosity, + convert(FT, gravity_wave_parameter), + convert(FT, laminar_parameter), + convert(FT, maximum_roughness_length)) +end + +# Momentum roughness length should be different from scalar roughness length. +# Apparently temperature and water vapor can be considered the same (Edison et al 2013) +@inline function roughness_length(ℓ::GravityMomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT + g = ℓ.gravitational_acceleration + α = ℓ.gravity_wave_parameter + β = ℓ.laminar_parameter + ℓm = ℓ.maximum_roughness_length + + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) + ν = ℓ.air_kinematic_viscosity(θ₀) + + # We need to prevent `Inf` that pops up when `u★ == 0`. + # For this reason, if `u★ == 0` we prescribe the roughness length to be + # equal to a `maximum` roughness length + ℓᴿ = ifelse(u★ == 0, ℓm, β * ν / u★) + + return min(α * u★^2 / g + ℓᴿ, ℓm) +end + +# This, for example is what is implemented in COARE 3.6 +@inline function roughness_length(ℓ::GravityScalarRoughnessLength{FT}, ℓu, u★, 𝒬, ℂ) where FT + ℓm = ℓ.maximum_roughness_length + + scaling_function = ℓ.reynolds_number_scaling_function + + θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) + ν = ℓ.air_kinematic_viscosity(θ₀) + + # Roughness Reynolds number + R★ = ℓu * u★ / ν + + # implementation of scalar roughness length + ℓq = scaling_function(R★, ℓu, u★, ν) + + return min(ℓq, ℓm) +end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 242ae707..9583e7da 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -29,11 +29,11 @@ import SurfaceFluxes.Parameters: ##### Bulk turbulent fluxes based on similarity theory ##### -struct SimilarityTheoryTurbulentFluxes{FT, ΔU, UF, TP, S, W, R, F} <: AbstractSurfaceFluxesParameters +struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, F} <: AbstractSurfaceFluxesParameters gravitational_acceleration :: FT von_karman_constant :: FT turbulent_prandtl_number :: FT - bulk_velocity_scale :: ΔU + gustiness_parameter :: FT stability_functions :: UF thermodynamics_parameters :: TP water_vapor_saturation :: S @@ -54,7 +54,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.turbulent_prandtl_number), - nothing, # adapt(to, fluxes.bulk_velocity_scale), + adapt(to, fluxes.gustiness_parameter), adapt(to, fluxes.stability_functions), adapt(to, fluxes.thermodynamics_parameters), nothing, #adapt(to, fluxes.water_vapor_saturation), @@ -73,23 +73,10 @@ struct ClasiusClapyeronSaturation end return q★ end -struct LargeYeagerSaturation{FT} - c₁ :: FT - c₂ :: FT -end - -function LargeYeagerSaturation(FT=Float64; c₁ = 640380, c₂ = 5107.4) - return LargeYeagerSaturation(convert(FT, c₁), convert(FT, c₂)) -end - -const LYS = LargeYeagerSaturation -@inline water_saturation_specific_humidity(lys::LYS, ℂₐ, ρₛ, Tₛ) = lys.c₁ * exp(-lys.c₂ / Tₛ) / ρₛ - function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) print(io, summary(fluxes), '\n', "├── gravitational_acceleration: ", prettysummary(fluxes.gravitational_acceleration), '\n', "├── von_karman_constant: ", prettysummary(fluxes.von_karman_constant), '\n', - "├── bulk_velocity_scale: ", summary(fluxes.bulk_velocity_scale), '\n', "├── planetary_boundary_layer_height: ", prettysummary(fluxes.planetary_boundary_layer_height), '\n', "├── turbulent_prandtl_number: ", prettysummary(fluxes.turbulent_prandtl_number), '\n', "├── similarity_function: ", summary(fluxes.similarity_function), '\n', @@ -98,20 +85,13 @@ function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) end -function default_roughness_lengths(FT=Float64) - momentum = GravityMomentumRoughnessLength(FT) - temperature = GravityScalarRoughnessLength(FT) - water_vapor = GravityScalarRoughnessLength(FT) - return SimilarityScales(momentum, temperature, water_vapor) -end - const PATP = PrescribedAtmosphereThermodynamicsParameters function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; gravitational_acceleration = default_gravitational_acceleration, - bulk_velocity_scale = nothing, von_karman_constant = convert(FT, 0.4), turbulent_prandtl_number = convert(FT, 1), + gustiness_parameter = convert(FT, 1.2), stability_functions = default_stability_functions(FT), thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), @@ -122,7 +102,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), convert(FT, von_karman_constant), convert(FT, turbulent_prandtl_number), - bulk_velocity_scale, + convert(FT, gustiness_parameter), stability_functions, thermodynamics_parameters, water_vapor_saturation, @@ -165,56 +145,6 @@ end return q★_H₂O * x_H₂O end -struct SalinityConstituent{FT} - molar_mass :: FT - mass_fraction :: FT -end - -struct WaterMoleFraction{FT, C} - water_molar_mass :: FT - salinity_constituents :: C -end - -function WaterMoleFraction(FT=Float64) - water_molar_mass = convert(FT, 18.02) - - # TODO: find reference for these - salinity_constituents = ( - chloride = SalinityConstituent{FT}(35.45, 0.56), - sodium = SalinityConstituent{FT}(22.99, 0.31), - sulfate = SalinityConstituent{FT}(96.06, 0.08), - magnesium = SalinityConstituent{FT}(24.31, 0.05), - ) - - return SeawaterComposition(water_molar_mass, salinity_constituents) -end - -@inline compute_water_mole_fraction(x_H₂O::Number, S) = x_H₂O - -@inline function compute_water_mole_fraction(wmf::WaterMoleFraction, S) - # TODO: express the concept of "ocean_salinity_units"? - s = S / 1000 # convert g/kg to concentration - - # Molecular weights - μ_H₂O = wmf.water_molar_mass - - # Salinity constituents: Cl, Na, SO₄, Mg - μ_Cl = wmf.salinity_constituents.chloride.molar_mass - μ_Na = wmf.salinity_constituents.sodium.molar_mass - μ_SO₄ = wmf.salinity_constituents.sulfate.molar_mass - μ_Mg = wmf.salinity_constituents.magnesium.molar_mass - - # Salinity constituent fractions - ϵ_Cl = wmf.salinity_constituents.chloride.mass_fraction - ϵ_Na = wmf.salinity_constituents.sodium.mass_fraction - ϵ_SO₄ = wmf.salinity_constituents.sulfate.mass_fraction - ϵ_Mg = wmf.salinity_constituents.magnesium.mass_fraction - - α = μ_H₂O * (ϵ_Cl/μ_Cl + ϵ_Na/μ_Na + ϵ_SO₄/μ_SO₄ + ϵ_Mg/μ_Mg) - - return (1 - s) / (1 - s + α * s) -end - ##### ##### Fixed-point iteration for roughness length ##### @@ -233,13 +163,14 @@ end differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) # Initial guess for the characteristic scales u★, θ★, q★. - # also provides the initial stability parameter (or non-dimensional height) `ζ₀`. - Σ★, ζ₀ = initial_guess(differences, - similarity_theory, - atmos_boundary_layer_height, - gravitational_acceleration, - von_karman_constant, - ℂₐ, atmos_state.ts) + Σ★ = initial_guess(differences, + similarity_theory, + atmos_boundary_layer_height, + gravitational_acceleration, + von_karman_constant, + ℂₐ, + atmos_state.ts, + surface_state.ts) # The inital velocity scale assumes that # the gustiness velocity `uᴳ` is equal to 0.5 ms⁻¹. @@ -248,17 +179,21 @@ end # In case ζ₀ > 50 we have a very stable boundary layer with a MO length # extremely thin with respect to `h`. In this case we use the first iteration - niter = ifelse(ζ₀ > 50, 1, 10) - for _ in 1:niter - Σ★, uτ = refine_characteristic_scales(Σ★, uτ, - similarity_theory, - surface_state, - differences, - atmos_boundary_layer_height, - thermodynamics_parameters, - gravitational_acceleration, - von_karman_constant) + lu = 0 + lt = 0 + lq = 0 + + for _ in 1:30 + Σ★, uτ, lu, lt, lq = refine_characteristic_scales(Σ★, uτ, + similarity_theory, + surface_state, + atmos_state, + differences, + atmos_boundary_layer_height, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) end u★ = Σ★.momentum @@ -275,6 +210,16 @@ end cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) + # qₐ = AtmosphericThermodynamics.vapor_specific_humidity(ℂₐ, 𝒬ₐ) + + # fluxes = (; + # sensible_heat = θ★, + # latent_heat = u★, + # water_vapor = q★, + # x_momentum = lu, + # y_momentum = qₐ, + # ) + fluxes = (; sensible_heat = - ρₐ * cₚ * u★ * θ★, latent_heat = - ρₐ * u★ * q★ * ℰv, @@ -291,7 +236,7 @@ end atmos_boundary_layer_height, gravitational_acceleration, von_karman_constant, - ℂₐ, 𝒬ₐ) + ℂₐ, 𝒬ₐ, 𝒬ₒ) Δu = differences.u Δv = differences.v @@ -301,27 +246,30 @@ end g = gravitational_acceleration ϰ = von_karman_constant - # Extract roughness lengths - ℓu = similarity_theory.roughness_lengths.momentum - zᵢ = atmos_boundary_layer_height + ℓu = similarity_theory.roughness_lengths.momentum + β = similarity_theory.gustiness_parameter + zᵢ = atmos_boundary_layer_height + + hᵢ = convert(eltype(h), 10) # Reference height of 10 meters + ℓuᵢ = convert(eltype(h), 1e-4) # Initial roughness length == 1e-4 # assuming the initial gustiness is `0.5` ms⁻¹ uᴳ = 0.5 uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) # u10 at the reference ten meter height, assuming the initial roughness length is `1e-4` m - u10 = uτ / log(h / 1e-4) * 11.5129 # log(10 / 1e-4) == 11.5129 + u10 = uτ / log(h / ℓuᵢ) * 11.5129 # log(10 / 1e-4) == 11.5129 u★ = 0.035 * u10 ℓu₀ = roughness_length(ℓu, u★, 𝒬ₐ, ℂₐ) # Initial neutral coefficients at 10 meter height - χuₙ = (ϰ / log(10 / ℓu₀))^2 + χuₙ = (ϰ / log(hᵢ / ℓu₀))^2 χcₙ = 0.00115 / sqrt(χuₙ) # Initial scalar roughness length - ℓθ₀ = 10 / exp(ϰ / χcₙ) + ℓθ₀ = hᵢ / exp(ϰ / χcₙ) # Neutral transfer coefficients at height `h` χu = (ϰ / log(h / ℓu₀))^2 @@ -334,33 +282,31 @@ end ψq = similarity_theory.stability_functions.water_vapor # Bulk Flux Richardson number - b★ = buoyancy_scale(Δθ, Δq, 𝒬ₐ, ℂₐ, g) + b★ = buoyancy_scale(Δθ, Δq, 𝒬ₒ, ℂₐ, g) Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) - Riᶜ = - h / zᵢ / 0.004 / 1.2^3 # - h / zi / 0.004 / β^3 + Riᶜ = - h / zᵢ / 0.004 / β^3 # - h / zi / 0.004 / β^3 - # Calculating the first stability coefficient and the MO length at 10 meters + # Calculating the first stability coefficient and the MO length ζ10 = ifelse(Ri < 0, χc * Ri / (1 + Ri / Riᶜ), χc * Ri * (1 + 27 / 9 * Ri / χc)) - L10 = ifelse(ζ10 == 0, zero(ζ10), h / ζ10) - u★ = uτ * ϰ / (log(h / ℓu₀) - ψu(h / L10)) # + ψu(ℓu₀ / L10)) - θ★ = Δθ * ϰ / (log(h / ℓθ₀) - ψθ(h / L10)) # + ψθ(ℓθ₀ / L10)) - q★ = Δq * ϰ / (log(h / ℓθ₀) - ψq(h / L10)) # + ψq(ℓθ₀ / L10)) + u★ = uτ * ϰ / (log(h / ℓu₀) - ψu(ζ10)) # + ψu(ℓu₀ / L10)) + θ★ = Δθ * ϰ / (log(h / ℓθ₀) - ψθ(ζ10)) # + ψθ(ℓθ₀ / L10)) + q★ = Δq * ϰ / (log(h / ℓθ₀) - ψq(ζ10)) # + ψq(ℓθ₀ / L10)) - return SimilarityScales(u★, θ★, q★), ζ10 + return SimilarityScales(u★, θ★, q★) end # The M-O characteristic length is calculated as # L★ = - u★² / (κ ⋅ b★) # where b★ is the characteristic buoyancy scale calculated from this function @inline function buoyancy_scale(θ★, q★, 𝒬, ℂ, g) - 𝒯₀ = AtmosphericThermodynamics.virtual_temperature(ℂ, 𝒬) - q₀ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬) - - ε = AtmosphericThermodynamics.Parameters.molmass_ratio(ℂ) - δ = ε - 1 # typically equal to 0.608 + 𝒯ₐ = AtmosphericThermodynamics.virtual_temperature(ℂ, 𝒬) + qₐ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬) + ε = AtmosphericThermodynamics.Parameters.molmass_ratio(ℂ) + δ = ε - 1 # typically equal to 0.608 # Where does this come from? Probably Fairell et al. 1996, - b★ = g / 𝒯₀ * (θ★ * (1 + δ * q₀) + δ * 𝒯₀ * q★) / (1 + δ * q₀) + b★ = g / 𝒯ₐ * (θ★ * (1 + δ * qₐ) + δ * 𝒯ₐ * q★) return b★ end @@ -396,13 +342,11 @@ end return Δh, Δu, Δv, Δθ, Δq end -@inline roughness_length(ℓ, u★, args...) = ℓ(u★, args...) -@inline roughness_length(ℓ::Number, args...) = ℓ - @inline function refine_characteristic_scales(estimated_characteristic_scales, velocity_scale, similarity_theory, surface_state, + atmos_state, differences, atmos_boundary_layer_height, thermodynamics_parameters, @@ -424,12 +368,14 @@ end ℓu = similarity_theory.roughness_lengths.momentum ℓθ = similarity_theory.roughness_lengths.temperature ℓq = similarity_theory.roughness_lengths.water_vapor + β = similarity_theory.gustiness_parameter h = differences.h ϰ = von_karman_constant ℂ = thermodynamics_parameters g = gravitational_acceleration 𝒬ₒ = surface_state.ts # thermodynamic state + 𝒬ₐ = atmos_state.ts # thermodynamic state zᵢ = atmos_boundary_layer_height # Compute Monin-Obukhov length scale depending on a `buoyancy flux` @@ -445,8 +391,8 @@ end # Transfer coefficients at height `h` χu = ϰ / (log(h / ℓu₀) - ψu(h / L★)) # + ψu(ℓu₀ / L★)) - χθ = ϰ / (log(h / ℓq₀) - ψθ(h / L★)) # + ψθ(ℓq₀ / L★)) - χq = ϰ / (log(h / ℓθ₀) - ψq(h / L★)) # + ψq(ℓθ₀ / L★)) + χθ = ϰ / (log(h / ℓθ₀) - ψθ(h / L★)) # + ψθ(ℓq₀ / L★)) + χq = ϰ / (log(h / ℓq₀) - ψq(h / L★)) # + ψq(ℓθ₀ / L★)) Δu = differences.u Δv = differences.v @@ -458,100 +404,12 @@ end θ★ = χθ * Δθ q★ = χq * Δq - # Dissipation characteristic scale for gustiness + # Buoyancy flux characteristic scale for gustiness ε★ = - u★ * b★ - uᴳ = 1.2 * cbrt(ε★ * zᵢ) + uᴳ = β * cbrt(ε★ * zᵢ) # New velocity difference accounting for gustiness uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) - return SimilarityScales(u★, θ★, q★), uτ -end - -struct GravityMomentumRoughnessLength{FT, V} - gravitational_acceleration :: FT - air_kinematic_viscosity :: V - gravity_wave_parameter :: FT - laminar_parameter :: FT - maximum_roughness_length :: FT -end - -struct GravityScalarRoughnessLength{FT, V, R} - air_kinematic_viscosity :: V - reynolds_number_scaling_function :: R - maximum_roughness_length :: FT -end - -# Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ / ν` -# Edson et al. (2013), equation (28) -@inline empirical_scaling_function(R★ :: FT, args...) where FT = - ifelse(R★ == 0, FT(0), convert(FT, 5.85e-5 / R★ ^ 0.72)) - -# Assumes that θ comes in in Kelvin -@inline function temperature_dependent_viscosity(θ :: FT) where FT - T = convert(FT, θ - celsius_to_kelvin) - ν = convert(FT, 1.326e-5 * (1 + 6.542e-3 * T + 8.301e-6 * T^2 - 4.84e-9 * T^3)) - - return ν -end - -function GravityScalarRoughnessLength(FT=Float64; - air_kinematic_viscosity = temperature_dependent_viscosity, - reynolds_number_scaling_function = empirical_scaling_function, - maximum_roughness_length = 1.6e-4) # Values from COARE3.6 - - return GravityScalarRoughnessLength(air_kinematic_viscosity, - reynolds_number_scaling_function, - convert(FT, maximum_roughness_length)) -end - -function GravityMomentumRoughnessLength(FT=Float64; - gravitational_acceleration = default_gravitational_acceleration, - maximum_roughness_length = 1.0, # An estimate? - air_kinematic_viscosity = temperature_dependent_viscosity, - gravity_wave_parameter = 0.011, - laminar_parameter = 0.11) - - return GravityMomentumRoughnessLength(convert(FT, gravitational_acceleration), - air_kinematic_viscosity, - convert(FT, gravity_wave_parameter), - convert(FT, laminar_parameter), - convert(FT, maximum_roughness_length)) -end - -# Momentum roughness length should be different from scalar roughness length. -# Apparently temperature and water vapor can be considered the same (Edison et al 2013) -@inline function roughness_length(ℓ::GravityMomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT - g = ℓ.gravitational_acceleration - α = ℓ.gravity_wave_parameter - β = ℓ.laminar_parameter - ℓm = ℓ.maximum_roughness_length - - θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) - ν = ℓ.air_kinematic_viscosity(θ₀) - - # We need to prevent `Inf` that pops up when `u★ == 0`. - # For this reason, if `u★ == 0` we prescribe the roughness length to be - # equal to a `maximum` roughness length - ℓᴿ = ifelse(u★ == 0, ℓm, β * ν / u★) - - return min(α * u★^2 / g + ℓᴿ, ℓm) -end - -# This, for example is what is implemented in COARE 3.6 -@inline function roughness_length(ℓ::GravityScalarRoughnessLength{FT}, ℓu, u★, 𝒬, ℂ) where FT - ℓm = ℓ.maximum_roughness_length - - scaling_function = ℓ.reynolds_number_scaling_function - - θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬) - ν = ℓ.air_kinematic_viscosity(θ₀) - - # Roughness Reynolds number - R★ = ℓu * u★ / ν - - # implementation of scalar roughness length - ℓq = scaling_function(R★, ℓu, u★, ν) - - return min(ℓq, ℓm) + return SimilarityScales(u★, θ★, q★), uτ, ℓu₀, ℓθ₀, ℓq₀ end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/water_model_fraction.jl b/src/OceanSeaIceModels/CrossRealmFluxes/water_model_fraction.jl new file mode 100644 index 00000000..6e2360f8 --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/water_model_fraction.jl @@ -0,0 +1,49 @@ +struct SalinityConstituent{FT} + molar_mass :: FT + mass_fraction :: FT +end + +struct WaterMoleFraction{FT, C} + water_molar_mass :: FT + salinity_constituents :: C +end + +function WaterMoleFraction(FT=Float64) + water_molar_mass = convert(FT, 18.02) + + # TODO: find reference for these + salinity_constituents = ( + chloride = SalinityConstituent{FT}(35.45, 0.56), + sodium = SalinityConstituent{FT}(22.99, 0.31), + sulfate = SalinityConstituent{FT}(96.06, 0.08), + magnesium = SalinityConstituent{FT}(24.31, 0.05), + ) + + return SeawaterComposition(water_molar_mass, salinity_constituents) +end + +@inline compute_water_mole_fraction(x_H₂O::Number, S) = x_H₂O + +@inline function compute_water_mole_fraction(wmf::WaterMoleFraction, S) + # TODO: express the concept of "ocean_salinity_units"? + s = S / 1000 # convert g/kg to concentration + + # Molecular weights + μ_H₂O = wmf.water_molar_mass + + # Salinity constituents: Cl, Na, SO₄, Mg + μ_Cl = wmf.salinity_constituents.chloride.molar_mass + μ_Na = wmf.salinity_constituents.sodium.molar_mass + μ_SO₄ = wmf.salinity_constituents.sulfate.molar_mass + μ_Mg = wmf.salinity_constituents.magnesium.molar_mass + + # Salinity constituent fractions + ϵ_Cl = wmf.salinity_constituents.chloride.mass_fraction + ϵ_Na = wmf.salinity_constituents.sodium.mass_fraction + ϵ_SO₄ = wmf.salinity_constituents.sulfate.mass_fraction + ϵ_Mg = wmf.salinity_constituents.magnesium.mass_fraction + + α = μ_H₂O * (ϵ_Cl/μ_Cl + ϵ_Na/μ_Na + ϵ_SO₄/μ_SO₄ + ϵ_Mg/μ_Mg) + + return (1 - s) / (1 - s + α * s) +end \ No newline at end of file From 51fc880f5a6fece3f5a26619c8aec7502a5b6e4a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:04:19 -0400 Subject: [PATCH 383/716] Finally I got it! --- .../similarity_theory_turbulent_fluxes.jl | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 9583e7da..ae5875db 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -91,7 +91,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; gravitational_acceleration = default_gravitational_acceleration, von_karman_constant = convert(FT, 0.4), turbulent_prandtl_number = convert(FT, 1), - gustiness_parameter = convert(FT, 1.2), + gustiness_parameter = convert(FT, 6.5), stability_functions = default_stability_functions(FT), thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), @@ -99,6 +99,8 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; roughness_lengths = default_roughness_lengths(FT), fields = nothing) + @show gustiness_parameter + return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), convert(FT, von_karman_constant), convert(FT, turbulent_prandtl_number), @@ -210,16 +212,6 @@ end cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity ℰv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) - # qₐ = AtmosphericThermodynamics.vapor_specific_humidity(ℂₐ, 𝒬ₐ) - - # fluxes = (; - # sensible_heat = θ★, - # latent_heat = u★, - # water_vapor = q★, - # x_momentum = lu, - # y_momentum = qₐ, - # ) - fluxes = (; sensible_heat = - ρₐ * cₚ * u★ * θ★, latent_heat = - ρₐ * u★ * q★ * ℰv, From 9be9fea3ec84aa5b112cd1e67c9afccdb068f421 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 1 May 2024 10:55:48 -0400 Subject: [PATCH 384/716] small fixes --- .../CrossRealmFluxes/radiation.jl | 15 +++++++++++++++ .../CrossRealmFluxes/roughness_lengths.jl | 8 ++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index 77dd9451..8bef3337 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -1,3 +1,5 @@ +using Oceananigans.Coriolis: hack_cosd + struct Radiation{FT, E, R} emission :: E reflection :: R @@ -32,6 +34,19 @@ end Base.summary(r::Radiation) = "Radiation" Base.show(io::IO, r::Radiation) = print(io, summary(r)) +struct LatitudeDependentAlbedo{FT} + direct :: FT + diffuse :: FT +end + +@inline function stateindex(α::LatitudeDependentAlbedo, i, j, 1, grid, time) + φ = φnode(i, j, k, grid, Center(), Center(), Center()) + α_diffuse = α.diffuse + direct_correction = α.direct * hack_cosd(2φ) + + return α_diffuse - direct_correction +end + # To allow the use with KernelFunctionOperation @inline function net_downwelling_radiation(i, j, k, grid, time, atmos_radiation, diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index c79fb699..f7b5ea22 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -19,12 +19,12 @@ function default_roughness_lengths(FT=Float64) return SimilarityScales(momentum, temperature, water_vapor) end -# Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ / ν` +# Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ ℓu / ν` # Edson et al. (2013), equation (28) @inline empirical_scaling_function(R★ :: FT, args...) where FT = ifelse(R★ == 0, FT(0), convert(FT, 5.85e-5 / R★ ^ 0.72)) -# Assumes that θ comes in in Kelvin +# Temeprature-dependent viscosity law: assumes that θ comes in Kelvin @inline function temperature_dependent_viscosity(θ :: FT) where FT T = convert(FT, θ - celsius_to_kelvin) ν = convert(FT, 1.326e-5 * (1 + 6.542e-3 * T + 8.301e-6 * T^2 - 4.84e-9 * T^3)) @@ -61,7 +61,7 @@ function GravityMomentumRoughnessLength(FT=Float64; end # Momentum roughness length should be different from scalar roughness length. -# Apparently temperature and water vapor can be considered the same (Edison et al 2013) +# Temperature and water vapor can be considered the same (Edison et al 2013) @inline function roughness_length(ℓ::GravityMomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT g = ℓ.gravitational_acceleration α = ℓ.gravity_wave_parameter @@ -79,7 +79,7 @@ end return min(α * u★^2 / g + ℓᴿ, ℓm) end -# This, for example is what is implemented in COARE 3.6 +# Edison 2013 formulation of scalar roughness length @inline function roughness_length(ℓ::GravityScalarRoughnessLength{FT}, ℓu, u★, 𝒬, ℂ) where FT ℓm = ℓ.maximum_roughness_length From 084f826732fe7cc262a76dc5e90e8d94fc9281c9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 1 May 2024 11:27:36 -0400 Subject: [PATCH 385/716] try it now --- .../three_dimensional_interpolate_tripolar.jl | 7 +++++-- src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl index f29642f6..6c7adb0a 100644 --- a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl +++ b/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl @@ -24,6 +24,9 @@ using OrthogonalSphericalShellGrids: TRG, WRG const TField = Field{<:Any, <:Any, <:Any, <:Any, <:TRG} const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} +@inline hack_cosd(φ) = cos(π * φ / 180) +@inline hack_sind(φ) = sin(π * φ / 180) + function three_dimensional_interpolate!(a::Union{<:TField, <:WField}, b) interpolate!(a, b) @@ -40,7 +43,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong, conver θ = φ₂ - φ₁ - return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) + return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) end @inline function convert_to_native_grid(i, j, grid::TRG, uₒ, vₒ) @@ -49,5 +52,5 @@ end θ = φ₂ - φ₁ - return uₒ * cosd(θ) + vₒ * sind(θ), uₒ * sind(θ) + vₒ * cosd(θ) + return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index 8bef3337..209b6eda 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -1,4 +1,5 @@ -using Oceananigans.Coriolis: hack_cosd +@inline hack_cosd(φ) = cos(π * φ / 180) +@inline hack_sind(φ) = sin(π * φ / 180) struct Radiation{FT, E, R} emission :: E From eec09a6c58d3f4670a405180158a9b3b24e870eb Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 1 May 2024 11:56:41 -0400 Subject: [PATCH 386/716] bugfix --- src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index 209b6eda..e74a698c 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -40,7 +40,7 @@ struct LatitudeDependentAlbedo{FT} diffuse :: FT end -@inline function stateindex(α::LatitudeDependentAlbedo, i, j, 1, grid, time) +@inline function stateindex(α::LatitudeDependentAlbedo, i, j, k, grid, time) φ = φnode(i, j, k, grid, Center(), Center(), Center()) α_diffuse = α.diffuse direct_correction = α.direct * hack_cosd(2φ) From 8dff60e5e3f3ab2dd6b45eb06878c553ef84af30 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 17:04:48 -0400 Subject: [PATCH 387/716] remove vestigial files --- Manifest.toml | 16 +- Project.toml | 1 + experiments/performance.jl | 125 - .../prototype_omip_simulation/Manifest.toml | 2359 ----------------- .../prototype_omip_simulation/Project.toml | 19 - .../freely_decaying_regional_simulation.jl | 147 - .../omip_components.jl | 205 -- .../plot_freely_decaying_simulation.jl | 40 - .../regional_omip_simulation.jl | 174 -- .../single_column_omip_simulation.jl | 342 --- test/field_time_series_utilities.jl | 0 11 files changed, 6 insertions(+), 3422 deletions(-) delete mode 100644 experiments/performance.jl delete mode 100644 experiments/prototype_omip_simulation/Manifest.toml delete mode 100644 experiments/prototype_omip_simulation/Project.toml delete mode 100644 experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl delete mode 100644 experiments/prototype_omip_simulation/omip_components.jl delete mode 100644 experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl delete mode 100644 experiments/prototype_omip_simulation/regional_omip_simulation.jl delete mode 100644 experiments/prototype_omip_simulation/single_column_omip_simulation.jl delete mode 100644 test/field_time_series_utilities.jl diff --git a/Manifest.toml b/Manifest.toml index 09fe750a..58f5b96f 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.2" +julia_version = "1.10.3" manifest_format = "2.0" -project_hash = "eef01b615158af2777b0945e4cc529fabc90261f" +project_hash = "2a8f25db6ea4e6c9eea1b6a1b3d7fec975bd0d16" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -253,7 +253,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.0+0" +version = "1.1.1+0" [[deps.CompositionsBase]] git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" @@ -642,15 +642,9 @@ version = "1.5.0" [[deps.JSON3]] deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] -git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -version = "1.14.0" - - [deps.JSON3.extensions] - JSON3ArrowExt = ["ArrowTypes"] - - [deps.JSON3.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" +version = "1.13.2" [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] diff --git a/Project.toml b/Project.toml index de6de872..d97e9d8f 100644 --- a/Project.toml +++ b/Project.toml @@ -15,6 +15,7 @@ Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" FFMPEG = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" ImageMorphology = "787d08f9-d448-5407-9aad-5290dd7ab264" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" diff --git a/experiments/performance.jl b/experiments/performance.jl deleted file mode 100644 index 453c109d..00000000 --- a/experiments/performance.jl +++ /dev/null @@ -1,125 +0,0 @@ -using Preferences -const iscray = parse(Bool, load_preference(Base.UUID("3da0fdf6-3ccc-4f1b-acd9-58baa6c99267"), "iscray", "false")) -@debug "Preloading GTL library" iscray -if iscray - import Libdl - Libdl.dlopen_e("libmpi_gtl_cuda", Libdl.RTLD_LAZY | Libdl.RTLD_GLOBAL) -end - -using MPI -MPI.Init() - -using Oceananigans -using Oceananigans: architecture -using ClimaOcean -using ClimaOcean.ECCO2 -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity -using Oceananigans.Coriolis: ActiveCellEnstrophyConserving -using Oceananigans.Units -using ClimaOcean.OceanSimulations -using ClimaOcean.OceanSeaIceModels -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation -using ClimaOcean.VerticalGrids: exponential_z_faces -using ClimaOcean.JRA55 -using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere -using Printf -using JLD2 - -##### -##### Global Ocean at 1/12th of a degree -##### - -include("correct_oceananigans.jl") -bathymetry_file = "bathymetry12.jld2" - -# 100 vertical levels -z_faces = exponential_z_faces(Nz=100, depth=6000) - -Nx = 4320 -Ny = 1800 -Nz = length(z_faces) - 1 - -bottom = zeros(Nx, Ny, 1) - -arch = Distributed(GPU(), partition = Partition(8)) - -grid = load_balanced_regional_grid(arch; - size = (Nx, Ny, Nz), - z = z_faces, - latitude = (-75, 75), - longitude = (0, 360), - halo = (7, 7, 7), - interpolation_passes = 20, - maximum_size = 650, - minimum_depth = 10, - connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea - bathymetry_file) - -@show grid - -##### -##### The Ocean component -##### - -free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt=270) - -ocean = ocean_simulation(grid; Δt = 10, free_surface, closure = RiBasedVerticalDiffusivity()) -model = ocean.model - -# Initializing the model -set!(model, - T = ECCO2Metadata(:temperature), - S = ECCO2Metadata(:salinity)) - -##### -##### The atmosphere -##### - -backend = JRA55NetCDFBackend(5) -atmosphere = JRA55_prescribed_atmosphere(arch; backend) -radiation = Radiation() - -coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) - -function profiled_time_steps!(model, Δt; gc_steps = 100, profiled_steps = 10) - # initial time steps - for step in 1:10 - time_step!(model, Δt) - end - - nranks = MPI.Comm_size(MPI.COMM_WORLD) - rank = MPI.Comm_rank(MPI.COMM_WORLD) - - if rank == 0 - @info "start profiling" - end - elapsed_time = Float64[0] - # Perform profiling - for step in 1:gc_steps - for nogc in 1:profiled_steps - elapsed_time[1] += @elapsed begin - NVTX.@range "one time step" begin - time_step!(model, Δt) - end - end - end - GC.gc() - end - - elapsed_time[1] = elapsed_time[1] / nranks / gc_steps / profiled_steps - MPI.Allreduce!(elapsed_time, +, MPI.COMM_WORLD) - - if rank == 0 - file = "time_twelth.jld2" - while isfile(file) - file = "new_" * file - end - jldsave(file, elapsed_time=elapsed_time[1]) - end - - MPI.Barrier(MPI.COMM_WORLD) - - return nothing -end - -profiled_time_steps!(coupled_model, 0.1) \ No newline at end of file diff --git a/experiments/prototype_omip_simulation/Manifest.toml b/experiments/prototype_omip_simulation/Manifest.toml deleted file mode 100644 index 230b6f71..00000000 --- a/experiments/prototype_omip_simulation/Manifest.toml +++ /dev/null @@ -1,2359 +0,0 @@ -# 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 deleted file mode 100644 index 7744d52a..00000000 --- a/experiments/prototype_omip_simulation/Project.toml +++ /dev/null @@ -1,19 +0,0 @@ -[deps] -CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" -ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" -Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" -JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" -Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" - -[compat] -GLMakie = "0.9" -Oceananigans = "0.90.10" -SeawaterPolynomials = "0.3.4" -Thermodynamics = "0.12.6" diff --git a/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl b/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl deleted file mode 100644 index 23585c82..00000000 --- a/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl +++ /dev/null @@ -1,147 +0,0 @@ -using Oceananigans -using Oceananigans.Architectures: arch_array -using Oceananigans.Units -using Oceananigans.BuoyancyModels: buoyancy_frequency -using Oceananigans.Units: Time - -using ClimaOcean -using ClimaOcean.OceanSeaIceModels: Radiation -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere -using ClimaOcean.DataWrangling.ECCO2: ecco2_field - -# using GLMakie -using Printf -using Dates - -start_time = time_ns() - -include("omip_components.jl") - -arch = CPU() -epoch = Date(1992, 1, 1) -date = Date(1992, 10, 1) -start_seconds = Second(date - epoch).value -Te = ecco2_field(:temperature, date) -Se = ecco2_field(:salinity, date) -# ℋe = ecco2_field(:sea_ice_thickness, date) - -land = interior(Te) .< -10 -interior(Te)[land] .= NaN -interior(Se)[land] .= NaN - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### - -latitude = (-80, -20) -longitude = (0, 360) - -i₁ = 4 * first(longitude) + 1 -i₂ = 1440 - 4 * (360 - last(longitude)) -Nx = i₂ - i₁ + 1 - -j₁ = 4 * (90 + first(latitude)) + 1 -j₂ = 720 - 4 * (90 - last(latitude)) -Ny = j₂ - j₁ + 1 - -zc = znodes(Te) -zf = znodes(Te.grid, Face()) -Δz = first(zspacings(Te.grid, Center())) - -Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) -Sᵢ = interior(Se, i₁:i₂, j₁:j₂, :) -# ℋᵢ = interior(ℋe, i₁:i₂, j₁:j₂, :) - -# Construct bottom_height depth by analyzing T -Nx, Ny, Nz = size(Tᵢ) -bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) - -for i = 1:Nx, j = 1:Ny - @inbounds for k = Nz:-1:1 - if isnan(Tᵢ[i, j, k]) - bottom_height[i, j] = zf[k+1] - break - end - end -end - -Tᵢ = arch_array(arch, Tᵢ) -Sᵢ = arch_array(arch, Sᵢ) -# ℋᵢ = arch_array(arch, ℋᵢ) - -if longitude[2] - longitude[1] == 360 - TX = Periodic -else - TX = Bounded -end - -grid = LatitudeLongitudeGrid(arch; latitude, longitude, - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = zf, - topology = (Periodic, Bounded, Bounded)) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - -#= -ocean = omip_ocean_component(grid) -sea_ice = omip_sea_ice_component(ocean.model) - -coupled_model = OceanSeaIceModel(ocean, sea_ice) -stop_time = 4 * 360days -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=stop_time) - -set!(sea_ice.model, h=ℋᵢ) -#set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) -set!(ocean.model, T=Tᵢ, S=Sᵢ) - -wall_clock = Ref(time_ns()) - -function progress(sim) - msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg *= string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", maximum(T), minimum(T)) - msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) - - # e = sim.model.ocean.model.tracers.e - # msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) - - @info msg -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -N² = buoyancy_frequency(ocean.model) -κᶜ = ocean.model.diffusivity_fields.κᶜ -auxiliary_fields = (; N², κᶜ) -fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) - -filename = "free_decay_heat_only_cold_ice_surface" - -coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; - filename = filename * "_fields", - indices = (:, :, Nz), - schedule = TimeInterval(10days), - overwrite_existing = true) - -coupled_simulation.output_writers[:seaice] = JLD2OutputWriter(sea_ice.model, (; h = sea_ice.model.ice_thickness); - filename = filename * "_sea_ice_thickness", - schedule = TimeInterval(10days), - overwrite_existing = true) - -run!(coupled_simulation) -=# diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl deleted file mode 100644 index 9f354bcb..00000000 --- a/experiments/prototype_omip_simulation/omip_components.jl +++ /dev/null @@ -1,205 +0,0 @@ - using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: - CATKEVerticalDiffusivity, - MixingLength, - TurbulentKineticEnergyEquation - -using Oceananigans.Architectures: architecture -using Oceananigans.Grids: halo_size, topology, φnodes, λnodes, znode -using Oceananigans.Fields: ConstantField, ZeroField, interpolate! -using Oceananigans.Utils: launch! - -using ClimaSeaIce -using ClimaSeaIce.HeatBoundaryConditions: IceWaterThermalEquilibrium - -using KernelAbstractions: @kernel, @index - -using SeawaterPolynomials.TEOS10: TEOS10EquationOfState - -function regional_omip_grid(arch, ecco_2_temperature_field; - latitude, - longitude = (0, 360), - z = znodes(ecco_2_temperature_field.grid, Face()), - resolution = 1/4, # degree - halo = (7, 7, 7)) - - start_time = time_ns() - - Te = ecco_2_temperature_field - launch!(architecture(Te), Te.grid, :xyz, nan_land!, Te) - - ΔΛ = last(longitude) - first(longitude) - ΔΦ = last(latitude) - first(latitude) - Nx = Int(ΔΛ / resolution) - Ny = Int(ΔΦ / resolution) - - Nz = length(z) - 1 - grid = LatitudeLongitudeGrid(arch; latitude, longitude, halo, - size = (Nx, Ny, Nz), - z = z) - - Tᵢ = CenterField(grid) - interpolate!(Tᵢ, Te) - - bottom_height = Field{Center, Center, Nothing}(grid) - set!(bottom_height, -Inf) - - # Construct bottom_height depth by analyzing T - launch!(arch, grid, :xy, infer_bottom_height!, bottom_height, Tᵢ, grid) - - grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - - elapsed = 1e-9 * (time_ns() - start_time) - @info string("Grid for regional omip simulation generated in ", prettytime(elapsed), ".") - @show grid - - return grid, Tᵢ -end - -function omip_ocean_component(grid; - closure = :default, - passive_tracers = tuple()) - - start_time = time_ns() - - top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) - top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) - top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) - top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(grid) - - ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), - v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), - T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), - S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) - - # Model construction - teos10 = TEOS10EquationOfState() - buoyancy = SeawaterBuoyancy(equation_of_state=teos10) - - Nx, Ny, Nz = size(grid) - - if Nx == Ny == 1 - tracer_advection = nothing - momentum_advection = nothing - else - tracer_advection = WENO() - momentum_advection = VectorInvariant(vorticity_scheme = WENO(), - divergence_scheme = WENO(), - vertical_scheme = WENO()) - end - - tracers = tuple(:T, :S, passive_tracers...) - - if closure == :default - - turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) - mixing_length = MixingLength(Cᵇ=0.01) - - closure = CATKEVerticalDiffusivity(; mixing_length, - turbulent_kinetic_energy_equation, - maximum_tracer_diffusivity = 1e-1, - maximum_tke_diffusivity = 1e-1, - maximum_viscosity = 1e-1, - negative_turbulent_kinetic_energy_damping_time_scale = 30, - minimum_turbulent_kinetic_energy = 1e-6, - minimum_convective_buoyancy_flux = 1e-11) - - tracers = tuple(:e, tracers...) - end - - ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, tracers, - tracer_advection, momentum_advection, - free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), - boundary_conditions = ocean_boundary_conditions, - coriolis = HydrostaticSphericalCoriolis()) - - ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) - - elapsed = time_ns() - start_time - msg = string("Finished building ocean component (" * prettytime(elapsed * 1e-9), ").") - @info msg - - return ocean -end - -function omip_sea_ice_component(ocean_model) - start_time = time_ns() - - ocean_grid = ocean_model.grid - Nx, Ny, Nz = size(ocean_grid) - Hx, Hy, Hz = halo_size(ocean_grid) - TX, TY, TZ = topology(ocean_grid) - - λ = λnodes(ocean_grid, Face()) - φ = φnodes(ocean_grid, Face()) - longitude = (λ[1], λ[end]) - latitude = (φ[1], φ[end]) - - sea_ice_grid = LatitudeLongitudeGrid(arch; longitude, latitude, - size = (Nx, Ny), - halo = (Hx, Hy), - topology = (TX, TY, Flat)) - - if ocean_grid isa ImmersedBoundaryGrid - h = ocean_grid.immersed_boundary.bottom_height - land = interior(h) .>= 0 - sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBoundary(land)) - end - - sea_ice_ocean_heat_flux = Field{Center, Center, Nothing}(ocean_grid) - - Nz = size(ocean_grid, 3) - So = ocean_model.tracers.S - ocean_surface_salinity = view(So, :, :, Nz) - bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) - - u, v, w = ocean_model.velocities - ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), - v = view(v, :, :, Nz), #interior(v, :, :, Nz), - w = ZeroField()) - - sea_ice_model = SlabSeaIceModel(sea_ice_grid; - velocities = ocean_surface_velocities, - advection = WENO(), - ice_consolidation_thickness = 0.05, - ice_salinity = 4, - internal_heat_flux = ConductiveFlux(conductivity=2), - top_heat_flux = ConstantField(0), # W m⁻² - top_heat_boundary_condition = PrescribedTemperature(-10), - bottom_heat_boundary_condition = bottom_bc, - bottom_heat_flux = sea_ice_ocean_heat_flux) - - sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) - - elapsed = time_ns() - start_time - msg = string("Finished building sea ice component (" * prettytime(elapsed * 1e-9), ").") - @info msg - - return sea_ice -end - -const c = Center() -const f = Face() - -@kernel function infer_bottom_height!(bottom_height, T, grid) - i, j = @index(Global, NTuple) - - Nz = size(grid, 3) - - @inbounds for k = Nz:-1:1 - if isnan(T[i, j, k]) - bottom_height[i, j] = znode(i, j, k+1, grid, c, c, f) - break - end - end -end - -@kernel function nan_land!(T) - i, j, k = @index(Global, NTuple) - - @inbounds begin - Tᵢ = T[i, j, k] - land = Tᵢ < -10 - T[i, j, k] = ifelse(land, NaN, Tᵢ) - end -end - diff --git a/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl b/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl deleted file mode 100644 index 9238a70f..00000000 --- a/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index bf9bce40..00000000 --- a/experiments/prototype_omip_simulation/regional_omip_simulation.jl +++ /dev/null @@ -1,174 +0,0 @@ -using Oceananigans -using Oceananigans.Architectures: arch_array -using Oceananigans.Units -using Oceananigans.BuoyancyModels: buoyancy_frequency -using Oceananigans.Units: Time - -using ClimaOcean -using ClimaOcean.OceanSeaIceModels: Radiation, FreezingLimitedOceanTemperature -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend -using ClimaOcean.DataWrangling.ECCO2: ecco2_field - -using ClimaSeaIce: LinearLiquidus - -# using GLMakie -using Printf -using Dates - -start_time = time_ns() - -include("omip_components.jl") - -arch = CPU() - -##### -##### Construct initial conditions + grid -##### - -epoch = Date(1992, 1, 1) -date = Date(1992, 1, 2) -start_seconds = Second(date - epoch).value -Te = ecco2_field(:temperature, date, architecture=arch) - -latitude = (-75, -70) -grid, Tᵢ = regional_omip_grid(arch, Te; latitude) - -backend = JRA55NetCDFBackend(8) # InMemory(8) -atmosphere = JRA55_prescribed_atmosphere(arch, 1:56; backend) -radiation = Radiation() - -#closure = RiBasedVerticalDiffusivity(maximum_diffusivity=1e2, maximum_viscosity=1e2) -#closure = RiBasedVerticalDiffusivity() -closure = :default -ocean = omip_ocean_component(grid; closure) -@show size(Tᵢ) ocean.model.grid -set!(ocean.model, T=Tᵢ) #, S=Sᵢ) - -Se = ecco2_field(:salinity, date, architecture=arch) -interpolate!(ocean.model.tracers.S, Se) - -if :e ∈ keys(ocean.model.tracers) - set!(ocean.model, e=1e-6) -end - -sea_ice = FreezingLimitedOceanTemperature(LinearLiquidus(eltype(grid))) - -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_model.clock.time = start_seconds -stop_time = start_seconds + 30days -coupled_simulation = Simulation(coupled_model, Δt=5minutes, stop_time=stop_time) - -elapsed = 1e-9 * (time_ns() - start_time) -@info string("Coupled simulation built ", prettytime(elapsed), ".") -start_time = time_ns() - -wall_clock = Ref(time_ns()) - -# Hm... - -function clip_diffusivity(coupled_simulation) - ocean_model = coupled_simulation.model.ocean.model - κᶜ = parent(ocean_model.diffusivity_fields.κᶜ) - κᵘ = parent(ocean_model.diffusivity_fields.κᵘ) - @. κᶜ = min(κᶜ, 100) - @. κᵘ = min(κᵘ, 100) - return nothing -end - -coupled_simulation.callbacks[:clip] = Callback(clip_diffusivity) - -##### -##### Progress -##### - -Jᵘ = coupled_model.fluxes.total.ocean.momentum.u -Jᵛ = coupled_model.fluxes.total.ocean.momentum.v -Jᵀ = coupled_model.fluxes.total.ocean.tracers.T -Jˢ = coupled_model.fluxes.total.ocean.tracers.S -Fv = coupled_model.fluxes.turbulent.fields.water_vapor -Qc = coupled_model.fluxes.turbulent.fields.sensible_heat -Qv = coupled_model.fluxes.turbulent.fields.latent_heat -ρₒ = coupled_model.fluxes.ocean_reference_density -cₚ = coupled_model.fluxes.ocean_heat_capacity - -import Oceananigans.Fields: reduced_dimensions -reduced_dimensions(::Oceananigans.AbstractOperations.BinaryOperation) = tuple(3) - -ΣQ = ρₒ * cₚ * Jᵀ -τˣ = ρₒ * Jᵘ -τʸ = ρₒ * Jᵛ -N² = buoyancy_frequency(ocean.model) -κᶜ = ocean.model.diffusivity_fields.κᶜ - -function progress(sim) - msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg *= string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) - msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) - msg *= @sprintf(", max|τ|: (%.2e, %.2e) N m⁻²", maximum(τˣ), maximum(τʸ)) - msg *= @sprintf(", max|Qv|: %.2e W m⁻²", maximum(Qv)) - msg *= @sprintf(", max|Qc|: %.2e W m⁻²", maximum(Qc)) - msg *= @sprintf(", extrema(ΣQ): (%.2e, %.2e) W m⁻²", minimum(ΣQ), maximum(ΣQ)) - msg *= @sprintf(", extrema(Fv): (%.2e, %.2e) kg s⁻¹ m⁻²", minimum(Fv), maximum(Fv)) - msg *= @sprintf(", extrema(κᶜ): (%.2e, %.2e) m² s⁻¹", minimum(κᶜ), maximum(κᶜ)) - - #e = sim.model.ocean.model.tracers.e - #msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) - - @info msg -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -run!(coupled_simulation) - -#= -# Build flux outputs -Jᵘ = coupled_model.fluxes.total.ocean.momentum.u -Jᵛ = coupled_model.fluxes.total.ocean.momentum.v -Jᵀ = coupled_model.fluxes.total.ocean.tracers.T -Jˢ = coupled_model.fluxes.total.ocean.tracers.S -Fv = coupled_model.fluxes.turbulent.fields.freshwater -Qc = coupled_model.fluxes.turbulent.fields.sensible_heat -Qv = coupled_model.fluxes.turbulent.fields.latent_heat -ρₒ = coupled_model.fluxes.ocean_reference_density -cₚ = coupled_model.fluxes.ocean_heat_capacity - -ΣQ = ρₒ * cₚ * Jᵀ -τˣ = ρₒ * Jᵘ -τʸ = ρₒ * Jᵛ -N² = buoyancy_frequency(ocean.model) -κᶜ = ocean.model.diffusivity_fields.κᶜ - -fluxes = (; τˣ, τʸ, Fv, Jˢ, ΣQ, Qc, Qv) - -auxiliary_fields = (; N², κᶜ) -fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) - -# Slice fields at the surface -outputs = merge(fields, fluxes) - -filename = "regional_omip_simulation" - -coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(ocean.model, fluxes; - filename = filename * "_fluxes", - schedule = TimeInterval(1days), - overwrite_existing = true) - -coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; - filename = filename * "_fields", - indices = (:, :, Nz), - schedule = TimeInterval(1days), - overwrite_existing = true) - -=# diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl deleted file mode 100644 index 093b9415..00000000 --- a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl +++ /dev/null @@ -1,342 +0,0 @@ -using Oceananigans -using Oceananigans.Units -using Oceananigans.BuoyancyModels: buoyancy_frequency -using Oceananigans.Units: Time - -using ClimaOcean -using ClimaOcean.DataWrangling.ECCO2: ecco2_column - -using GLMakie -using Printf -using Dates - -include("omip_components.jl") - -locations = ( - eastern_mediterranean = (λ = 30, φ = 32), - ocean_station_papa = (λ = 215, φ = 50), - north_atlantic = (λ = 325, φ = 50), - drake_passage = (λ = 300, φ = -60), - weddell_sea = (λ = 325, φ = -70), - tasman_southern_ocean = (λ = 145, φ = -55), -) - -location = :ocean_station_papa - -start_time = time_ns() - -epoch = Date(1992, 1, 1) -date = Date(1992, 10, 1) -start_seconds = Second(date - epoch).value -Tᵢ = ecco2_field(:temperature, date) -Sᵢ = ecco2_field(:salinity, date) - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -##### -##### Construct the grid -##### - -Nz = 80 -H = 400 -arch = CPU() -λ★, φ★ = locations[location] -i★, j★, longitude, latitude = ecco2_column(λ★, φ★) - -grid = LatitudeLongitudeGrid(arch; longitude, latitude, - size = (1, 1, Nz), - z = (-H, 0), - topology = (Periodic, Periodic, Bounded)) - -ocean = omip_ocean_component(grid) - -backend = JRA55NetCDFBackend(8 * 60) -atmosphere = JRA55_prescribed_atmosphere(:; longitude, latitude, backend) - -ocean.model.clock.time = start_seconds -ocean.model.clock.iteration = 0 -interpolate!(ocean.model.tracers.T, Tᵢ) -interpolate!(ocean.model.tracers.S, Sᵢ) -set!(ocean.model, e=1e-6) - -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -times = ua.times - -fig = Figure(size=(1200, 1800)) -axu = Axis(fig[1, 1]) -axT = Axis(fig[2, 1]) -axq = Axis(fig[3, 1]) - -lines!(axu, times ./ days, interior(ua, 1, 1, 1, :)) -lines!(axu, times ./ days, interior(va, 1, 1, 1, :)) -lines!(axT, times ./ days, interior(Ta, 1, 1, 1, :)) -lines!(axq, times ./ days, interior(qa, 1, 1, 1, :)) - -display(fig) - -sea_ice = nothing -radiation = Radiation() -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 30days) - -elapsed = time_ns() - start_time -@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - -wall_clock = Ref(time_ns()) - -function progress(sim) - msg = string("(", location, ")") - msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg *= string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - e = sim.model.ocean.model.tracers.e - - τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) - τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) - u★ = sqrt(sqrt(τˣ^2 + τʸ^2)) - Q = first(sim.model.fluxes.total.ocean.heat) - - Nz = size(T, 3) - msg *= @sprintf(", u★: %.2f m s⁻¹", u★) - msg *= @sprintf(", Q: %.2f W m⁻²", Q) - msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) - msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) - msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) - - @info msg -end - -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) - -# Build flux outputs -Ju = coupled_model.fluxes.total.ocean.momentum.u -Jv = coupled_model.fluxes.total.ocean.momentum.v -JT = coupled_model.fluxes.total.ocean.tracers.T -Js = coupled_model.fluxes.total.ocean.tracers.S -E = coupled_model.fluxes.turbulent.fields.water_vapor -Qc = coupled_model.fluxes.turbulent.fields.sensible_heat -Qv = coupled_model.fluxes.turbulent.fields.latent_heat -ρₒ = coupled_model.fluxes.ocean_reference_density -cₚ = coupled_model.fluxes.ocean_heat_capacity - -Q = ρₒ * cₚ * Jᵀ -τx = ρₒ * Jᵘ -τy = ρₒ * Jᵛ -N² = buoyancy_frequency(ocean.model) -κc = ocean.model.diffusivity_fields.κᶜ - -fluxes = (; τx, τy, E, Js, Q, Qc, Qc) - -auxiliary_fields = (; N², κc) -fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) - -# Slice fields at the surface -outputs = merge(fields, fluxes) - -output_attributes = Dict{String, Any}( - "κc" => Dict("long_name" => "Tracer diffusivity", "units" => "m^2 / s"), - "Q" => Dict("long_name" => "Net heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "Qv" => Dict("long_name" => "Latent heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "Qc" => Dict("long_name" => "Sensible heat flux", "units" => "W / m^2", "convention" => "positive upwards"), - "Js" => Dict("long_name" => "Salt flux", "units" => "g kg⁻¹ m s⁻¹", "convention" => "positive upwards"), - "E" => Dict("long_name" => "Freshwater evaporation flux", "units" => "m s⁻¹", "convention" => "positive upwards"), - "e" => Dict("long_name" => "Turbulent kinetic energy", "units" => "m^2 / s^2"), - "τx" => Dict("long_name" => "Zonal momentum flux", "units" => "m^2 / s^2"), - "τx" => Dict("long_name" => "Meridional momentum flux", "units" => "m^2 / s^2"), -) - -filename = "single_column_omip_$location" - -coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, - schedule = TimeInterval(3hours), - overwrite_existing = true) - -#= -coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, - schedule = AveragedTimeInterval(1days), - output_attributes, - overwrite_existing = true) -=# - -run!(coupled_simulation) - -#= -filename *= ".jld2" - -ut = FieldTimeSeries(filename, "u") -vt = FieldTimeSeries(filename, "v") -Tt = FieldTimeSeries(filename, "T") -St = FieldTimeSeries(filename, "S") -et = FieldTimeSeries(filename, "e") -N²t = FieldTimeSeries(filename, "N²") -κt = FieldTimeSeries(filename, "κᶜ") - -Qt = FieldTimeSeries(filename, "Q") -Qset = FieldTimeSeries(filename, "Qse") -Qlat = FieldTimeSeries(filename, "Qla") -Jˢt = FieldTimeSeries(filename, "Jˢ") -Et = FieldTimeSeries(filename, "E") -τˣt = FieldTimeSeries(filename, "τˣ") -τʸt = FieldTimeSeries(filename, "τʸ") - -Nz = size(Tt, 3) -times = Qt.times - -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q -Qlw = atmosphere.downwelling_radiation.longwave -Qsw = atmosphere.downwelling_radiation.shortwave -Pr = atmosphere.freshwater_flux.rain -Ps = atmosphere.freshwater_flux.snow - -Nt = length(times) -uat = zeros(Nt) -vat = zeros(Nt) -Tat = zeros(Nt) -qat = zeros(Nt) -Qswt = zeros(Nt) -Qlwt = zeros(Nt) -Pt = zeros(Nt) - -for n = 1:Nt - t = times[n] - uat[n] = ua[1, 1, 1, Time(t)] - vat[n] = va[1, 1, 1, Time(t)] - Tat[n] = Ta[1, 1, 1, Time(t)] - qat[n] = qa[1, 1, 1, Time(t)] - Qswt[n] = Qsw[1, 1, 1, Time(t)] - Qlwt[n] = Qlw[1, 1, 1, Time(t)] - Pt[n] = Pr[1, 1, 1, Time(t)] + Ps[1, 1, 1, Time(t)] -end - -set_theme!(Theme(linewidth=3)) - -fig = Figure(size=(2400, 1800)) - -axτ = Axis(fig[1, 1:2], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") -axu = Axis(fig[2, 1:2], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") -axQ = Axis(fig[1, 3:4], xlabel="Days since Oct 1 1992", ylabel="Heat flux (W m⁻²)") -axT = Axis(fig[2, 3:4], xlabel="Days since Oct 1 1992", ylabel="Surface temperature (ᵒC)") -axF = Axis(fig[1, 5:6], xlabel="Days since Oct 1 1992", ylabel="Freshwater volume flux (m s⁻¹)") -axS = Axis(fig[2, 5:6], xlabel="Days since Oct 1 1992", ylabel="Surface salinity (g kg⁻¹)") - -axuz = Axis(fig[3, 1], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") -axTz = Axis(fig[3, 2], xlabel="Temperature (ᵒC)", ylabel="z (m)") -axSz = Axis(fig[3, 3], xlabel="Salinity (g kg⁻¹)", ylabel="z (m)") -axNz = Axis(fig[3, 4], xlabel="Buoyancy frequency (s⁻²)", ylabel="z (m)") -axκz = Axis(fig[3, 5], xlabel="Eddy diffusivity (m² s⁻¹)", ylabel="z (m)", xscale=log10) -axez = Axis(fig[3, 6], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)", xscale=log10) - -title = @sprintf("Single column simulation at %.2f, %.2f", φ★, λ★) -Label(fig[0, 1:6], title) - -slider = Slider(fig[4, 1:6], range=1:Nt, startvalue=1) -n = slider.value - -times = (times .- times[1]) ./days -tn = @lift times[$n] - -colors = Makie.wong_colors() - -#lines!(axu, times, uat, color=colors[1]) -#lines!(axu, times, vat, color=colors[2]) - -ρₒ = coupled_model.fluxes.ocean_reference_density -Jᵘt = interior(τˣt, 1, 1, 1, :) ./ ρₒ -Jᵛt = interior(τʸt, 1, 1, 1, :) ./ ρₒ -u★ = @. (Jᵘt^2 + Jᵛt^2)^(1/4) - -lines!(axu, times, interior(ut, 1, 1, Nz, :), color=colors[1], label="Zonal") -lines!(axu, times, interior(vt, 1, 1, Nz, :), color=colors[2], label="Meridional") -lines!(axu, times, u★, color=colors[3], label="Ocean-side u★") -vlines!(axu, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axu) - -lines!(axτ, times, interior(τˣt, 1, 1, 1, :), label="Zonal") -lines!(axτ, times, interior(τʸt, 1, 1, 1, :), label="Meridional") -vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axτ) - -lines!(axT, times, Tat .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") -lines!(axT, times, interior(Tt, 1, 1, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") -vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axT) - -lines!(axQ, times, interior(Qt, 1, 1, 1, :), color=colors[1], label="Total", linewidth=6) -lines!(axQ, times, interior(Qset, 1, 1, 1, :), color=colors[2], label="Sensible", linewidth=2) -lines!(axQ, times, interior(Qlat, 1, 1, 1, :), color=colors[3], label="Latent", linewidth=2) -lines!(axQ, times, - Qswt, color=colors[4], label="Shortwave", linewidth=2) -lines!(axQ, times, - Qlwt, color=colors[5], label="Longwave", linewidth=2) -vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axQ) - -#lines!(axF, times, interior(Jˢt, 1, 1, 1, :), label="Net freshwater flux") -lines!(axF, times, Pt, label="Prescribed freshwater flux") -lines!(axF, times, - interior(Et, 1, 1, 1, :), label="Evaporation") -vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axF) - -lines!(axS, times, interior(St, 1, 1, Nz, :)) -vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) - -zc = znodes(Tt) -zf = znodes(κt) -un = @lift interior(ut[$n], 1, 1, :) -vn = @lift interior(vt[$n], 1, 1, :) -Tn = @lift interior(Tt[$n], 1, 1, :) -Sn = @lift interior(St[$n], 1, 1, :) -κn = @lift interior(κt[$n], 1, 1, :) -en = @lift max.(1e-6, interior(et[$n], 1, 1, :)) -N²n = @lift interior(N²t[$n], 1, 1, :) - -scatterlines!(axuz, un, zc, label="u") -scatterlines!(axuz, vn, zc, label="v") -scatterlines!(axTz, Tn, zc) -scatterlines!(axSz, Sn, zc) -scatterlines!(axez, en, zc) -scatterlines!(axNz, N²n, zf) -scatterlines!(axκz, κn, zf) - -axislegend(axuz) - -Tmax = maximum(interior(Tt)) -Tmin = minimum(interior(Tt)) -xlims!(axTz, Tmin - 0.1, Tmax + 0.1) - -Nmax = maximum(interior(N²t)) -Nmin = minimum(interior(N²t)) -xlims!(axNz, Nmin / 2, Nmin * 1.1) - -emax = maximum(interior(et)) -xlims!(axez, 8e-7, emax * 1.1) -xlims!(axκz, 1e-7, 10) - -Smax = maximum(interior(St)) -Smin = minimum(interior(St)) -xlims!(axSz, Smin - 0.2, Smax + 0.2) - -display(fig) - -record(fig, "$(location)_single_column_simulation.mp4", 1:Nt, framerate=24) do nn - @info "Drawing frame $nn of $Nt..." - n[] = nn -# end -end -=# diff --git a/test/field_time_series_utilities.jl b/test/field_time_series_utilities.jl deleted file mode 100644 index e69de29b..00000000 From 7e2a900f4ed714d9d3002b37338d803682fd53b3 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 17:07:20 -0400 Subject: [PATCH 388/716] remove some vestigial files --- experiments/twelth_degree_latlong.jl | 148 --------------------------- 1 file changed, 148 deletions(-) delete mode 100644 experiments/twelth_degree_latlong.jl diff --git a/experiments/twelth_degree_latlong.jl b/experiments/twelth_degree_latlong.jl deleted file mode 100644 index 088a3d15..00000000 --- a/experiments/twelth_degree_latlong.jl +++ /dev/null @@ -1,148 +0,0 @@ -using Oceananigans -using Oceananigans: architecture -using ClimaOcean -using ClimaOcean.ECCO2 -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity -using Oceananigans.Coriolis: ActiveCellEnstrophyConserving -using Oceananigans.Units -using ClimaOcean.OceanSimulations -using ClimaOcean.OceanSeaIceModels -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation -using ClimaOcean.VerticalGrids: exponential_z_faces -using ClimaOcean.JRA55 -using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere -using Printf -using CUDA -using CairoMakie -using SixelTerm -CUDA.device!(1) - -include("correct_oceananigans.jl") - -##### -##### Global Ocean at 1/12th of a degree -##### - -bathymetry_file = nothing # "bathymetry_tmp.jld2" - -# 100 vertical levels -z_faces = exponential_z_faces(Nz=60, depth=6500) - -Nx = 720 -Ny = 300 -Nz = length(z_faces) - 1 - -arch = GPU() #Distributed(GPU(), partition = Partition(2)) - -grid = load_balanced_regional_grid(arch; - size = (Nx, Ny, Nz), - z = z_faces, - latitude = (-75, 75), - longitude = (0, 360), - halo = (7, 7, 7), - interpolation_passes = 20, - minimum_depth = 10, - connected_regions_allowed = 3, # We allow the oceans, the med, the bering sea - bathymetry_file) - -@show grid - -##### -##### The Ocean component -##### - -const Lz = grid.Lz -const h = Nz / 4.5 - -@inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) -@inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) - -free_surface = SplitExplicitFreeSurface(; grid, cfl=0.7, fixed_Δt = 20minutes) -vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = 5e-3) - -closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) - -ocean = ocean_simulation(grid; free_surface, closure) -model = ocean.model - -# Initializing the model -set!(model, - T = ECCOMetadata(:temperature), - S = ECCOMetadata(:salinity)) - -##### -##### The atmosphere -##### - -backend = JRA55NetCDFBackend(10) -atmosphere = JRA55_prescribed_atmosphere(arch; backend) -radiation = Radiation() - -sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() - -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) - -wall_time = [time_ns()] - -function progress(sim) - u, v, w = sim.model.velocities - T, S = sim.model.tracers - - Tmax = maximum(abs, T) - Tmin = minimum(T) - umax = maximum(abs, u), maximum(abs, v), maximum(abs, w) - step_time = 1e-9 * (time_ns() - wall_time[1]) - - @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", - prettytime(sim.model.clock.time), - sim.model.clock.iteration, - prettytime(sim.Δt), - umax..., Tmax, Tmin, prettytime(step_time)) - - wall_time[1] = time_ns() -end - -ocean.callbacks[:progress] = Callback(progress, IterationInterval(100)) - -ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(30days), - overwrite_existing = true, - array_type = Array{Float32}, - filename = "snapshots") - -ocean.output_writers[:checkpoint] = Checkpointer(model, - schedule = TimeInterval(60days), - overwrite_existing = true, - prefix = "checkpoint") - -# Simulation warm up! -ocean.Δt = 10 -ocean.stop_iteration = 1 -wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) - -# stop_time = 10days - -# coupled_simulation = Simulation(coupled_model, Δt=1, stop_time=stop_time) - -# try -# run!(coupled_simulation) -# catch - -# end - -# wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 15minutes, max_change = 1.1) -# ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) - -# # Let's reset the maximum number of iterations -# coupled_model.ocean.stop_time = 7200days -# coupled_simulation.stop_time = 7200days -# coupled_model.ocean.stop_iteration = Inf -# coupled_simulation.stop_iteration = Inf - -# try -# run!(coupled_simulation) -# catch - -# end - From f59977df453b061d4accf726d6e2d9fad9604435 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 17:36:23 -0400 Subject: [PATCH 389/716] some small changes --- .../CrossRealmFluxes/CrossRealmFluxes.jl | 2 +- .../CrossRealmFluxes/roughness_lengths.jl | 30 +-- ... seawater_saturation_specific_humidity.jl} | 22 ++ .../similarity_theory_turbulent_fluxes.jl | 131 +++++----- .../CrossRealmFluxes/stability_functions.jl | 9 + src/OceanSimulations/OceanSimulations.jl | 2 - .../load_balanced_regional_grid.jl | 226 ------------------ 7 files changed, 111 insertions(+), 311 deletions(-) rename src/OceanSeaIceModels/CrossRealmFluxes/{water_model_fraction.jl => seawater_saturation_specific_humidity.jl} (61%) delete mode 100644 src/OceanSimulations/load_balanced_regional_grid.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 31033db7..3205e741 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -65,7 +65,7 @@ include("radiation.jl") include("latitude_dependent_albedo.jl") include("roughness_lengths.jl") include("stability_functions.jl") -include("water_model_fraction.jl") +include("seawater_saturation_specific_humidity.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") include("sea_ice_ocean_fluxes.jl") diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index f7b5ea22..0c99fbb6 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -1,21 +1,21 @@ -struct GravityMomentumRoughnessLength{FT, V} +struct MomentumRoughnessLength{FT, V} gravitational_acceleration :: FT air_kinematic_viscosity :: V - gravity_wave_parameter :: FT + _wave_parameter :: FT laminar_parameter :: FT maximum_roughness_length :: FT end -struct GravityScalarRoughnessLength{FT, V, R} +struct ScalarRoughnessLength{FT, V, R} air_kinematic_viscosity :: V reynolds_number_scaling_function :: R maximum_roughness_length :: FT end function default_roughness_lengths(FT=Float64) - momentum = GravityMomentumRoughnessLength(FT) - temperature = GravityScalarRoughnessLength(FT) - water_vapor = GravityScalarRoughnessLength(FT) + momentum = MomentumRoughnessLength(FT) + temperature = ScalarRoughnessLength(FT) + water_vapor = ScalarRoughnessLength(FT) return SimilarityScales(momentum, temperature, water_vapor) end @@ -36,35 +36,35 @@ end @inline roughness_length(ℓ, u★, args...) = ℓ(u★, args...) @inline roughness_length(ℓ::Number, args...) = ℓ -function GravityScalarRoughnessLength(FT=Float64; +function ScalarRoughnessLength(FT=Float64; air_kinematic_viscosity = temperature_dependent_viscosity, reynolds_number_scaling_function = empirical_scaling_function, maximum_roughness_length = 1.6e-4) # Values from COARE3.6 - return GravityScalarRoughnessLength(air_kinematic_viscosity, + return ScalarRoughnessLength(air_kinematic_viscosity, reynolds_number_scaling_function, convert(FT, maximum_roughness_length)) end -function GravityMomentumRoughnessLength(FT=Float64; +function MomentumRoughnessLength(FT=Float64; gravitational_acceleration = default_gravitational_acceleration, maximum_roughness_length = 1.0, # An estimate? air_kinematic_viscosity = temperature_dependent_viscosity, - gravity_wave_parameter = 0.011, + _wave_parameter = 0.011, laminar_parameter = 0.11) - return GravityMomentumRoughnessLength(convert(FT, gravitational_acceleration), + return MomentumRoughnessLength(convert(FT, gravitational_acceleration), air_kinematic_viscosity, - convert(FT, gravity_wave_parameter), + convert(FT, _wave_parameter), convert(FT, laminar_parameter), convert(FT, maximum_roughness_length)) end # Momentum roughness length should be different from scalar roughness length. # Temperature and water vapor can be considered the same (Edison et al 2013) -@inline function roughness_length(ℓ::GravityMomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT +@inline function roughness_length(ℓ::MomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT g = ℓ.gravitational_acceleration - α = ℓ.gravity_wave_parameter + α = ℓ._wave_parameter β = ℓ.laminar_parameter ℓm = ℓ.maximum_roughness_length @@ -80,7 +80,7 @@ end end # Edison 2013 formulation of scalar roughness length -@inline function roughness_length(ℓ::GravityScalarRoughnessLength{FT}, ℓu, u★, 𝒬, ℂ) where FT +@inline function roughness_length(ℓ::ScalarRoughnessLength{FT}, ℓu, u★, 𝒬, ℂ) where FT ℓm = ℓ.maximum_roughness_length scaling_function = ℓ.reynolds_number_scaling_function diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/water_model_fraction.jl b/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl similarity index 61% rename from src/OceanSeaIceModels/CrossRealmFluxes/water_model_fraction.jl rename to src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl index 6e2360f8..0fd865c2 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/water_model_fraction.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl @@ -46,4 +46,26 @@ end α = μ_H₂O * (ϵ_Cl/μ_Cl + ϵ_Na/μ_Na + ϵ_SO₄/μ_SO₄ + ϵ_Mg/μ_Mg) return (1 - s) / (1 - s + α * s) +end + +@inline function seawater_saturation_specific_humidity(atmosphere_thermodynamics_parameters, + surface_temperature, + surface_salinity, + atmos_state, + water_mole_fraction, + water_vapor_saturation, + ::Liquid) + + ℂₐ = atmosphere_thermodynamics_parameters + FT = eltype(ℂₐ) + Tₛ = surface_temperature + Sₛ = surface_salinity + ρₛ = atmos_state.ρ # surface density -- should we extrapolate to obtain this? + ρₛ = convert(FT, ρₛ) + + q★_H₂O = water_saturation_specific_humidity(water_vapor_saturation, ℂₐ, ρₛ, Tₛ) + x_H₂O = compute_water_mole_fraction(water_mole_fraction, Sₛ) + + # Return saturation specific humidity for salty seawater + return q★_H₂O * x_H₂O end \ No newline at end of file diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index ae5875db..78b1eb27 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -39,6 +39,9 @@ struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, F} <: AbstractSurfac water_vapor_saturation :: S water_mole_fraction :: W roughness_lengths :: R + tolerance :: FT + maxiter :: Int + iteration :: Int fields :: F end @@ -57,9 +60,12 @@ Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt( adapt(to, fluxes.gustiness_parameter), adapt(to, fluxes.stability_functions), adapt(to, fluxes.thermodynamics_parameters), - nothing, #adapt(to, fluxes.water_vapor_saturation), - nothing, #adapt(to, fluxes.water_mole_fraction), + adapt(to, fluxes.water_vapor_saturation), + adapt(to, fluxes.water_mole_fraction), adapt(to, fluxes.roughness_lengths), + fluxes.iteration, + fluxes.tolerance, + fluxes.maxiter, adapt(to, fluxes.fields)) Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" @@ -77,11 +83,12 @@ 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', - "├── planetary_boundary_layer_height: ", prettysummary(fluxes.planetary_boundary_layer_height), '\n', "├── turbulent_prandtl_number: ", prettysummary(fluxes.turbulent_prandtl_number), '\n', - "├── similarity_function: ", summary(fluxes.similarity_function), '\n', + "├── gustiness_parameter: ", prettysummary(fluxes.gustiness_parameter), '\n', + "├── stability_functions: ", summary(fluxes.stability_functions), '\n', "├── water_mole_fraction: ", summary(fluxes.water_mole_fraction), '\n', "├── water_vapor_saturation: ", summary(fluxes.water_vapor_saturation), '\n', + "├── roughness_lengths: ", summary(fluxes.roughness_lengths), '\n', "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) end @@ -97,10 +104,10 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), roughness_lengths = default_roughness_lengths(FT), + tolerance = 1e-8, + maxiter = Inf, fields = nothing) - @show gustiness_parameter - return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), convert(FT, von_karman_constant), convert(FT, turbulent_prandtl_number), @@ -110,6 +117,9 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; water_vapor_saturation, water_mole_fraction, roughness_lengths, + tolerance, + maxiter, + 0, fields) end @@ -125,28 +135,6 @@ function SimilarityTheoryTurbulentFluxes(grid::AbstractGrid; kw...) return SimilarityTheoryTurbulentFluxes(eltype(grid); kw..., fields) end -@inline function seawater_saturation_specific_humidity(atmosphere_thermodynamics_parameters, - surface_temperature, - surface_salinity, - atmos_state, - water_mole_fraction, - water_vapor_saturation, - ::Liquid) - - ℂₐ = atmosphere_thermodynamics_parameters - FT = eltype(ℂₐ) - Tₛ = surface_temperature - Sₛ = surface_salinity - ρₛ = atmos_state.ρ # surface density -- should we extrapolate to obtain this? - ρₛ = convert(FT, ρₛ) - - q★_H₂O = water_saturation_specific_humidity(water_vapor_saturation, ℂₐ, ρₛ, Tₛ) - x_H₂O = compute_water_mole_fraction(water_mole_fraction, Sₛ) - - # Return saturation specific humidity for salty seawater - return q★_H₂O * x_H₂O -end - ##### ##### Fixed-point iteration for roughness length ##### @@ -164,6 +152,8 @@ end Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, surface_state, gravitational_acceleration) differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) + Σ₀ = SimilarityScales(0, 0, 0) + # Initial guess for the characteristic scales u★, θ★, q★. Σ★ = initial_guess(differences, similarity_theory, @@ -177,25 +167,19 @@ end # The inital velocity scale assumes that # the gustiness velocity `uᴳ` is equal to 0.5 ms⁻¹. # That will be refined later on. - uτ = sqrt(Δu^2 + Δv^2 + 0.25) - - # In case ζ₀ > 50 we have a very stable boundary layer with a MO length - # extremely thin with respect to `h`. In this case we use the first iteration - - lu = 0 - lt = 0 - lq = 0 - - for _ in 1:30 - Σ★, uτ, lu, lt, lq = refine_characteristic_scales(Σ★, uτ, - similarity_theory, - surface_state, - atmos_state, - differences, - atmos_boundary_layer_height, - thermodynamics_parameters, - gravitational_acceleration, - von_karman_constant) + uτ = sqrt(Δu^2 + Δv^2 + convert(FT, 0.25)) + + while iterating(Σ★ - Σ₀, similarity_theory) + Σ₀ = Σ★ + similarity_theory.iteration += 1 + Σ★, uτ, = refine_characteristic_scales(Σ★, uτ, + similarity_theory, + surface_state, + differences, + atmos_boundary_layer_height, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) end u★ = Σ★.momentum @@ -223,6 +207,17 @@ end return fluxes end +# Iterating condition for the characteristic scales solvers +@inline function iterating(Σ★, solver) + solver.iteration >= solver.maxiter && return false + norm(Σ★) <= solver.tolerance && return false + return true +end + +# The complete bulk coefficient should include also `ψ(ℓ / L)`, but the +# JRA55 atmosphere is adjusted to formulae without this last term so we exclude it +@inline bulk_coefficient(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) # + ψ(ℓ / L) + @inline function initial_guess(differences, similarity_theory, atmos_boundary_layer_height, @@ -238,27 +233,27 @@ end g = gravitational_acceleration ϰ = von_karman_constant + # Extract roughness lengths ℓu = similarity_theory.roughness_lengths.momentum β = similarity_theory.gustiness_parameter zᵢ = atmos_boundary_layer_height - hᵢ = convert(eltype(h), 10) # Reference height of 10 meters - ℓuᵢ = convert(eltype(h), 1e-4) # Initial roughness length == 1e-4 + hᵢ = convert(eltype(h), 10) # Reference Initial height == 10 meters + ℓuᵢ = convert(eltype(h), 1e-4) # Initial roughness length == 1e-4 meters # assuming the initial gustiness is `0.5` ms⁻¹ - uᴳ = 0.5 - uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) + uτ = sqrt(Δu^2 + Δv^2 + convert(FT, 0.25)) # u10 at the reference ten meter height, assuming the initial roughness length is `1e-4` m u10 = uτ / log(h / ℓuᵢ) * 11.5129 # log(10 / 1e-4) == 11.5129 - u★ = 0.035 * u10 + u★ = convert(FT, 0.035) * u10 ℓu₀ = roughness_length(ℓu, u★, 𝒬ₐ, ℂₐ) # Initial neutral coefficients at 10 meter height χuₙ = (ϰ / log(hᵢ / ℓu₀))^2 - χcₙ = 0.00115 / sqrt(χuₙ) + χcₙ = convert(FT, 0.00115) / sqrt(χuₙ) # Initial scalar roughness length ℓθ₀ = hᵢ / exp(ϰ / χcₙ) @@ -274,30 +269,34 @@ end ψq = similarity_theory.stability_functions.water_vapor # Bulk Flux Richardson number + # TODO: find out what 0.004 refers to b★ = buoyancy_scale(Δθ, Δq, 𝒬ₒ, ℂₐ, g) Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) - Riᶜ = - h / zᵢ / 0.004 / β^3 # - h / zi / 0.004 / β^3 + Riᶜ = - h / zᵢ / convert(FT, 0.004) / β^3 # - h / zi / 0.004 / β^3 # Calculating the first stability coefficient and the MO length + # TODO: explain this formulation of the stability function. Is it empirical? + # Found in COARE3.6 ζ10 = ifelse(Ri < 0, χc * Ri / (1 + Ri / Riᶜ), χc * Ri * (1 + 27 / 9 * Ri / χc)) + L10 = h / ζ10 - u★ = uτ * ϰ / (log(h / ℓu₀) - ψu(ζ10)) # + ψu(ℓu₀ / L10)) - θ★ = Δθ * ϰ / (log(h / ℓθ₀) - ψθ(ζ10)) # + ψθ(ℓθ₀ / L10)) - q★ = Δq * ϰ / (log(h / ℓθ₀) - ψq(ζ10)) # + ψq(ℓθ₀ / L10)) + u★ = uτ * ϰ / bulk_coefficient(ψu, h, ℓu₀, L10) + θ★ = Δθ * ϰ / bulk_coefficient(ψθ, h, ℓθ₀, L10) + q★ = Δq * ϰ / bulk_coefficient(ψq, h, ℓθ₀, L10) return SimilarityScales(u★, θ★, q★) end # The M-O characteristic length is calculated as # L★ = - u★² / (κ ⋅ b★) -# where b★ is the characteristic buoyancy scale calculated from this function +# where b★ is the characteristic buoyancy scale calculated from: @inline function buoyancy_scale(θ★, q★, 𝒬, ℂ, g) 𝒯ₐ = AtmosphericThermodynamics.virtual_temperature(ℂ, 𝒬) qₐ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬) ε = AtmosphericThermodynamics.Parameters.molmass_ratio(ℂ) δ = ε - 1 # typically equal to 0.608 - # Where does this come from? Probably Fairell et al. 1996, + # Fairell et al. 1996, b★ = g / 𝒯ₐ * (θ★ * (1 + δ * qₐ) + δ * 𝒯ₐ * q★) return b★ @@ -338,7 +337,6 @@ end velocity_scale, similarity_theory, surface_state, - atmos_state, differences, atmos_boundary_layer_height, thermodynamics_parameters, @@ -351,7 +349,7 @@ end q★ = estimated_characteristic_scales.water_vapor uτ = velocity_scale - # Similarity functions from Businger et al. (1971) + # Similarity functions from Edison et al. (2013) ψu = similarity_theory.stability_functions.momentum ψθ = similarity_theory.stability_functions.temperature ψq = similarity_theory.stability_functions.water_vapor @@ -367,7 +365,6 @@ end ℂ = thermodynamics_parameters g = gravitational_acceleration 𝒬ₒ = surface_state.ts # thermodynamic state - 𝒬ₐ = atmos_state.ts # thermodynamic state zᵢ = atmos_boundary_layer_height # Compute Monin-Obukhov length scale depending on a `buoyancy flux` @@ -382,9 +379,9 @@ end ℓθ₀ = roughness_length(ℓθ, ℓu₀, u★, 𝒬ₒ, ℂ) # Transfer coefficients at height `h` - χu = ϰ / (log(h / ℓu₀) - ψu(h / L★)) # + ψu(ℓu₀ / L★)) - χθ = ϰ / (log(h / ℓθ₀) - ψθ(h / L★)) # + ψθ(ℓq₀ / L★)) - χq = ϰ / (log(h / ℓq₀) - ψq(h / L★)) # + ψq(ℓθ₀ / L★)) + χu = ϰ / bulk_coefficient(ψu, h, ℓu₀, L★) + χθ = ϰ / bulk_coefficient(ψθ, h, ℓθ₀, L★) + χq = ϰ / bulk_coefficient(ψq, h, ℓq₀, L★) Δu = differences.u Δv = differences.v @@ -396,12 +393,12 @@ end θ★ = χθ * Δθ q★ = χq * Δq - # Buoyancy flux characteristic scale for gustiness + # Buoyancy flux characteristic scale for gustiness (Edison 2013) ε★ = - u★ * b★ uᴳ = β * cbrt(ε★ * zᵢ) # New velocity difference accounting for gustiness uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) - return SimilarityScales(u★, θ★, q★), uτ, ℓu₀, ℓθ₀, ℓq₀ + return SimilarityScales(u★, θ★, q★), uτ end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index 8faefb3d..babfb48f 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -1,3 +1,6 @@ +import Base +import Statistics + ##### ##### Struct that represents a 3-tuple of momentum, heat, and water vapor ##### @@ -8,6 +11,12 @@ struct SimilarityScales{U, T, Q} water_vapor :: Q end +Base.(-)(a::SimilarityScales, b::SimilarityScales) = SimilarityScales(a.momentum - b.momentum, + a.temperature - b.temperature, + a.water_vapor - b.water_vapor) + +Statistic.norm(a::SimilarityScales) = norm(a.momentum) + norm(a.temperature) + norm(a.water_vapor) + struct MomentumStabilityFunction end struct ScalarStabilityFunction end struct InitialMomentumStabilityFunction end diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 42ee32a6..3352bc44 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -18,8 +18,6 @@ using Oceananigans.BuoyancyModels: g_Earth using Oceananigans.Coriolis: Ω_Earth using Oceananigans.Operators -include("load_balanced_regional_grid.jl") - # Some defaults default_free_surface(grid) = SplitExplicitFreeSurface(grid; cfl=0.7) diff --git a/src/OceanSimulations/load_balanced_regional_grid.jl b/src/OceanSimulations/load_balanced_regional_grid.jl deleted file mode 100644 index 73c9ab02..00000000 --- a/src/OceanSimulations/load_balanced_regional_grid.jl +++ /dev/null @@ -1,226 +0,0 @@ -using ClimaOcean.Bathymetry -using Oceananigans -using Oceananigans.Architectures: arch_array, device, architecture -using Oceananigans.DistributedComputations -using Oceananigans.DistributedComputations: Sizes, child_architecture, barrier!, all_reduce, partition_global_array -using Oceananigans.ImmersedBoundaries: immersed_cell -using KernelAbstractions: @index, @kernel -using JLD2 - -""" - load_balanced_regional_grid(arch; size, - latitude, - longitude, - z, - halo, - maximum_size, - height_above_water, - minimum_depth, - interpolation_passes) - -Construct a LatitudeLongitudeGrid with an ocean bathymetry interpolated from ETOPO1. -If the architecture is `Distributed` and the partition is only in one direction, the partition will be -calculated to maintain an equal number of active cells across different workers. - -# Positional Arguments -====================== -- `arch`: The architecture of the ocean grid. - -# Keyword Arguments -=================== -- `size`: The size of the grid. -- `latitude`: The latitude of the grid. -- `longitude`: The longitude of the grid. -- `z`: The z-faces of the grid. -- `halo`: The halo size of the grid. Default is `(3, 3, 3)`. -- `maximum_size`: The maximum size in the partitioned direction. In `nothing` the load balanced direction - is not reduced. Default is `nothing`. -- `height_above_water`: The height above water level. Default is `1`. -- `minimum_depth`: The minimum depth of the bathymetry. Default is `10`. -- `interpolation_passes`: The number of interpolation passes. Default is `1`. -- `connected_regions_allowed`: The number of connected regions allowed in the bathymetry - -# Returns -- `grid`: The load-balanced ocean grid. -""" -function load_balanced_regional_grid(arch; - size, - latitude, - longitude, - z, - halo = (3, 3, 3), - maximum_size = nothing, - height_above_water = nothing, - minimum_depth = 10, - connected_regions_allowed = 3, - interpolation_passes = 1, - bathymetry_file = nothing) - - grid = LatitudeLongitudeGrid(arch; - size, - longitude, - latitude, - z, - halo) - - bottom_height = retrieve_bathymetry(grid, bathymetry_file; - height_above_water, - minimum_depth, - interpolation_passes, - connected_regions_allowed) - - return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) -end - -const SlabPartition = Union{Partition{<:Any, <:Nothing, <:Nothing}, - Partition{<:Nothing, <:Any, <:Nothing}} - -const SlabDistributed = Distributed{<:Any, <:Any, <:SlabPartition} - -# Load balancing works only for 1D partitions! -function load_balanced_regional_grid(arch::SlabDistributed; - size, - latitude, - longitude, - z, - halo = (3, 3, 3), - maximum_size = nothing, - height_above_water = 1, - minimum_depth = 10, - interpolation_passes = 1, - connected_regions_allowed = 3, - bathymetry_file = nothing) - - child_arch = child_architecture(arch) - - # index of the partitioned direction - idx = arch.ranks[1] == 1 ? 2 : 1 - - # Calculate the load balancing on the CPU - grid = LatitudeLongitudeGrid(child_arch; - size, - longitude, - latitude, - z, - halo) - - # Calculating the global bottom on the global grid on rank 0 - # so that we can write to file the bathymetry in case `!isnothing(bathymetry_file)` - bottom_height = retrieve_bathymetry(grid, bathymetry_file; - height_above_water, - minimum_depth, - interpolation_passes, - connected_regions_allowed) - - grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - - # Cannot have two dimensional vectors - # set! a field on `Distributed`. - # TODO: fix in Oceananigans - if ndims(bottom_height) == 2 - bottom_height = reshape(bottom_height, Base.size(bottom_height)..., 1) - end - - # Calculate the load for each i-slab if the partition is in x, - # calculate the load for eahc j-slab if the partition is in y. - load_per_slab = arch_array(child_arch, zeros(Int, size[idx])) - - loop! = assess_load!(device(child_arch), 512, size[idx]) - loop!(load_per_slab, grid, idx) - load_per_slab = arch_array(CPU(), load_per_slab) - - # Redistribute the load to have the same number of - # immersed cells in each core - local_N = calculate_local_size(load_per_slab, size[idx], arch.ranks[idx]) - - redistribute_size_to_fulfill_memory_limitation!(local_N, maximum_size) - - # Partition either x or y depending on the original partition direction - partition = idx == 1 ? Partition(x = Sizes(local_N...)) : Partition(y = Sizes(local_N...)) - - arch = Distributed(child_arch; partition) - zonal_rank = arch.local_index[idx] - - @info "slab decomposition with " zonal_rank local_N - - grid = LatitudeLongitudeGrid(arch; - size, - longitude, - latitude, - z, - halo) - - return ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) -end - -@kernel function assess_load!(load_per_slab, grid, idx) - i1 = @index(Global, Linear) - sz = ifelse(idx == 1, size(grid, 2), size(grid, 1)) - - for i2 in 1:sz - for k in 1:size(grid, 3) - i = ifelse(idx == 1, (i1, i2), (i2, i1)) - @inbounds load_per_slab[i1] += ifelse(immersed_cell(i..., k, grid), 0, 1) - end - end -end - -function calculate_local_size(load_per_slab, N, ranks) - active_cells = sum(load_per_slab) - active_load = active_cells / ranks - local_N = zeros(Int, ranks) # fill the local N with the active load - idx = 1 - for r in 1:ranks-1 - local_load = 0 - while local_load <= active_load - local_load += load_per_slab[idx] - local_N[r] += 1 - idx += 1 - end - end - - local_N[end] = N - sum(local_N[1:end-1]) - - return local_N -end - -redistribute_size_to_fulfill_memory_limitation!(l, ::Nothing) = nothing - -function redistribute_size_to_fulfill_memory_limitation!(l, m) - - n = length(l) - - # Reduce large sizes - while any(l .> m) - x⁺, i⁺ = findmax(l) - x⁻, i⁻ = findmin(l) - if x⁺ == m + 1 - l[i⁺] -= 1 - l[i⁻] += 1 - else - Δ = l[i⁺] - m - q = Δ ÷ n - l .+= q - l[i⁺] -= Δ - l[i⁻] += mod(Δ, n) - end - end - - # Increase small sizes - while any(l .< 20) - x⁺, i⁺ = findmax(l) - x⁻, i⁻ = findmin(l) - if x⁻ == 19 - l[i⁻] += 1 - l[i⁺] -= 1 - else - Δ = 20 - l[i⁻] - q = Δ ÷ n - l .-= q - l[i⁺] -= mod(Δ, n) - l[i⁻] += Δ - end - end - - return nothing -end From 522a182c10a5a939451d904314eda8af20c3204f Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 17:37:42 -0400 Subject: [PATCH 390/716] some small bugfixes --- .../CrossRealmFluxes/stability_functions.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index babfb48f..dbc8f775 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -1,4 +1,4 @@ -import Base +import Base: - import Statistics ##### @@ -11,11 +11,11 @@ struct SimilarityScales{U, T, Q} water_vapor :: Q end -Base.(-)(a::SimilarityScales, b::SimilarityScales) = SimilarityScales(a.momentum - b.momentum, +-(a::SimilarityScales, b::SimilarityScales) = SimilarityScales(a.momentum - b.momentum, a.temperature - b.temperature, a.water_vapor - b.water_vapor) -Statistic.norm(a::SimilarityScales) = norm(a.momentum) + norm(a.temperature) + norm(a.water_vapor) +Statistics.norm(a::SimilarityScales) = norm(a.momentum) + norm(a.temperature) + norm(a.water_vapor) struct MomentumStabilityFunction end struct ScalarStabilityFunction end From 90b2f5aa3ba79d9fd7d69e066867fba172fd706f Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 17:38:26 -0400 Subject: [PATCH 391/716] more bugfixes --- .../CrossRealmFluxes/seawater_saturation_specific_humidity.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl b/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl index 0fd865c2..ee780bd9 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl @@ -1,3 +1,5 @@ +using Thermodynamics: Liquid + struct SalinityConstituent{FT} molar_mass :: FT mass_fraction :: FT From 1a1d25ec8c69efd1fd13595f47b1d16c36497405 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 17:40:23 -0400 Subject: [PATCH 392/716] removing useless interpolation --- .../ocean_sea_ice_surface_fluxes.jl | 4 ++-- .../three_dimensional_operators.jl | 17 ----------------- 2 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 4dbb8aa2..a468d3a5 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -434,8 +434,8 @@ end i, j = @index(Global, NTuple) @inbounds begin - J.u[i, j, 1] = ℑxᶠᶜᶜ(i, j, 1, grid, Jᶜᶜᶜ.u) - J.v[i, j, 1] = ℑyᶜᶠᶜ(i, j, 1, grid, Jᶜᶜᶜ.v) + J.u[i, j, 1] = ℑxᶠᵃᵃ(i, j, 1, grid, Jᶜᶜᶜ.u) + J.v[i, j, 1] = ℑyᵃᶠᵃ(i, j, 1, grid, Jᶜᶜᶜ.v) end end diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl b/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl deleted file mode 100644 index 9688ba25..00000000 --- a/src/OceanSeaIceModels/CrossRealmFluxes/three_dimensional_operators.jl +++ /dev/null @@ -1,17 +0,0 @@ -using Oceananigans.Operators -using Oceananigans.Grids: peripheral_node - -@inline ı(i, j, k, grid, f::Function, args...) = f(i, j, k, grid, args...) -@inline ı(i, j, k, grid, ϕ) = ϕ[i, j, k] - -# Defining Interpolation operators for the immersed boundaries -@inline conditional_ℑx_f(LY, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, Center(), LY, LZ), ı(i-1, j, k, grid, t), ifelse(peripheral_node(i-1, j, k, grid, Center(), LY, LZ), ı(i, j, k, grid, t), ℑxᶠᵃᵃ(i, j, k, grid, t))) -@inline conditional_ℑy_f(LX, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, LX, Center(), LZ), ı(i, j-1, k, grid, t), ifelse(peripheral_node(i, j-1, k, grid, LX, Center(), LZ), ı(i, j, k, grid, t), ℑyᵃᶠᵃ(i, j, k, grid, t))) -@inline conditional_ℑx_c(LY, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, Face(), LY, LZ), ı(i+1, j, k, grid, t), ifelse(peripheral_node(i+1, j, k, grid, Face(), LY, LZ), ı(i, j, k, grid, t), ℑxᶜᵃᵃ(i, j, k, grid, t))) -@inline conditional_ℑy_c(LX, LZ, i, j, k, grid, t) = ifelse(peripheral_node(i, j, k, grid, LX, Face(), LZ), ı(i, j+1, k, grid, t), ifelse(peripheral_node(i, j+1, k, grid, LX, Face(), LZ), ı(i, j, k, grid, t), ℑyᵃᶜᵃ(i, j, k, grid, t))) - -ℑxᶠᶜᶜ(i, j, k, grid, t) = conditional_ℑx_f(Center(), Center(), i, j, k, grid, t) -ℑyᶜᶠᶜ(i, j, k, grid, t) = conditional_ℑy_f(Center(), Center(), i, j, k, grid, t) - -ℑxᶜᶜᶜ(i, j, k, grid, t) = conditional_ℑx_c(Center(), Center(), i, j, k, grid, t) -ℑyᶜᶜᶜ(i, j, k, grid, t) = conditional_ℑy_c(Center(), Center(), i, j, k, grid, t) \ No newline at end of file From a3766b85fe02e5f6f507d295424522b6253f526f Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 17:48:06 -0400 Subject: [PATCH 393/716] some correcting --- .../freely_decaying_regional_simulation.jl | 147 ++++++++ .../omip_components.jl | 205 +++++++++++ .../plot_freely_decaying_simulation.jl | 40 ++ .../single_column_omip_simulation.jl | 342 ++++++++++++++++++ .../correct_oceananigans.jl | 61 ---- .../CrossRealmFluxes/CrossRealmFluxes.jl | 1 - 6 files changed, 734 insertions(+), 62 deletions(-) create mode 100644 experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl create mode 100644 experiments/prototype_omip_simulation/omip_components.jl create mode 100644 experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl create mode 100644 experiments/prototype_omip_simulation/single_column_omip_simulation.jl delete mode 100644 prototype_omip_simulation/correct_oceananigans.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..23585c82 --- /dev/null +++ b/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl @@ -0,0 +1,147 @@ +using Oceananigans +using Oceananigans.Architectures: arch_array +using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time + +using ClimaOcean +using ClimaOcean.OceanSeaIceModels: Radiation +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO2: ecco2_field + +# using GLMakie +using Printf +using Dates + +start_time = time_ns() + +include("omip_components.jl") + +arch = CPU() +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 1) +start_seconds = Second(date - epoch).value +Te = ecco2_field(:temperature, date) +Se = ecco2_field(:salinity, date) +# ℋe = ecco2_field(:sea_ice_thickness, date) + +land = interior(Te) .< -10 +interior(Te)[land] .= NaN +interior(Se)[land] .= NaN + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +latitude = (-80, -20) +longitude = (0, 360) + +i₁ = 4 * first(longitude) + 1 +i₂ = 1440 - 4 * (360 - last(longitude)) +Nx = i₂ - i₁ + 1 + +j₁ = 4 * (90 + first(latitude)) + 1 +j₂ = 720 - 4 * (90 - last(latitude)) +Ny = j₂ - j₁ + 1 + +zc = znodes(Te) +zf = znodes(Te.grid, Face()) +Δz = first(zspacings(Te.grid, Center())) + +Tᵢ = interior(Te, i₁:i₂, j₁:j₂, :) +Sᵢ = interior(Se, i₁:i₂, j₁:j₂, :) +# ℋᵢ = interior(ℋe, i₁:i₂, j₁:j₂, :) + +# Construct bottom_height depth by analyzing T +Nx, Ny, Nz = size(Tᵢ) +bottom_height = ones(Nx, Ny) .* (zf[1] - Δz) + +for i = 1:Nx, j = 1:Ny + @inbounds for k = Nz:-1:1 + if isnan(Tᵢ[i, j, k]) + bottom_height[i, j] = zf[k+1] + break + end + end +end + +Tᵢ = arch_array(arch, Tᵢ) +Sᵢ = arch_array(arch, Sᵢ) +# ℋᵢ = arch_array(arch, ℋᵢ) + +if longitude[2] - longitude[1] == 360 + TX = Periodic +else + TX = Bounded +end + +grid = LatitudeLongitudeGrid(arch; latitude, longitude, + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = zf, + topology = (Periodic, Bounded, Bounded)) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + +#= +ocean = omip_ocean_component(grid) +sea_ice = omip_sea_ice_component(ocean.model) + +coupled_model = OceanSeaIceModel(ocean, sea_ice) +stop_time = 4 * 360days +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=stop_time) + +set!(sea_ice.model, h=ℋᵢ) +#set!(ocean.model, T=Tᵢ, S=Sᵢ, e=1e-6) +set!(ocean.model, T=Tᵢ, S=Sᵢ) + +wall_clock = Ref(time_ns()) + +function progress(sim) + msg = string("Iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", maximum(T), minimum(T)) + msg *= @sprintf(", extrema(S): (%.2f, %.2f) g kg⁻¹", minimum(S), maximum(S)) + + # e = sim.model.ocean.model.tracers.e + # msg *= @sprintf(", extrema(e): (%.2f, %.2f) m² s⁻²", minimum(e), maximum(e)) + + @info msg +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +N² = buoyancy_frequency(ocean.model) +κᶜ = ocean.model.diffusivity_fields.κᶜ +auxiliary_fields = (; N², κᶜ) +fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + +filename = "free_decay_heat_only_cold_ice_surface" + +coupled_simulation.output_writers[:fields] = JLD2OutputWriter(ocean.model, fields; + filename = filename * "_fields", + indices = (:, :, Nz), + schedule = TimeInterval(10days), + overwrite_existing = true) + +coupled_simulation.output_writers[:seaice] = JLD2OutputWriter(sea_ice.model, (; h = sea_ice.model.ice_thickness); + filename = filename * "_sea_ice_thickness", + schedule = TimeInterval(10days), + overwrite_existing = true) + +run!(coupled_simulation) +=# diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/prototype_omip_simulation/omip_components.jl new file mode 100644 index 00000000..9f354bcb --- /dev/null +++ b/experiments/prototype_omip_simulation/omip_components.jl @@ -0,0 +1,205 @@ + using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: + CATKEVerticalDiffusivity, + MixingLength, + TurbulentKineticEnergyEquation + +using Oceananigans.Architectures: architecture +using Oceananigans.Grids: halo_size, topology, φnodes, λnodes, znode +using Oceananigans.Fields: ConstantField, ZeroField, interpolate! +using Oceananigans.Utils: launch! + +using ClimaSeaIce +using ClimaSeaIce.HeatBoundaryConditions: IceWaterThermalEquilibrium + +using KernelAbstractions: @kernel, @index + +using SeawaterPolynomials.TEOS10: TEOS10EquationOfState + +function regional_omip_grid(arch, ecco_2_temperature_field; + latitude, + longitude = (0, 360), + z = znodes(ecco_2_temperature_field.grid, Face()), + resolution = 1/4, # degree + halo = (7, 7, 7)) + + start_time = time_ns() + + Te = ecco_2_temperature_field + launch!(architecture(Te), Te.grid, :xyz, nan_land!, Te) + + ΔΛ = last(longitude) - first(longitude) + ΔΦ = last(latitude) - first(latitude) + Nx = Int(ΔΛ / resolution) + Ny = Int(ΔΦ / resolution) + + Nz = length(z) - 1 + grid = LatitudeLongitudeGrid(arch; latitude, longitude, halo, + size = (Nx, Ny, Nz), + z = z) + + Tᵢ = CenterField(grid) + interpolate!(Tᵢ, Te) + + bottom_height = Field{Center, Center, Nothing}(grid) + set!(bottom_height, -Inf) + + # Construct bottom_height depth by analyzing T + launch!(arch, grid, :xy, infer_bottom_height!, bottom_height, Tᵢ, grid) + + grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) + + elapsed = 1e-9 * (time_ns() - start_time) + @info string("Grid for regional omip simulation generated in ", prettytime(elapsed), ".") + @show grid + + return grid, Tᵢ +end + +function omip_ocean_component(grid; + closure = :default, + passive_tracers = tuple()) + + start_time = time_ns() + + top_ocean_heat_flux = Qᵀ = Field{Center, Center, Nothing}(grid) + top_salt_flux = Fˢ = Field{Center, Center, Nothing}(grid) + top_zonal_momentum_flux = τˣ = Field{Face, Center, Nothing}(grid) + top_meridional_momentum_flux = τʸ = Field{Center, Face, Nothing}(grid) + + ocean_boundary_conditions = (u = FieldBoundaryConditions(top=FluxBoundaryCondition(τˣ)), + v = FieldBoundaryConditions(top=FluxBoundaryCondition(τʸ)), + T = FieldBoundaryConditions(top=FluxBoundaryCondition(Qᵀ)), + S = FieldBoundaryConditions(top=FluxBoundaryCondition(Fˢ))) + + # Model construction + teos10 = TEOS10EquationOfState() + buoyancy = SeawaterBuoyancy(equation_of_state=teos10) + + Nx, Ny, Nz = size(grid) + + if Nx == Ny == 1 + tracer_advection = nothing + momentum_advection = nothing + else + tracer_advection = WENO() + momentum_advection = VectorInvariant(vorticity_scheme = WENO(), + divergence_scheme = WENO(), + vertical_scheme = WENO()) + end + + tracers = tuple(:T, :S, passive_tracers...) + + if closure == :default + + turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + mixing_length = MixingLength(Cᵇ=0.01) + + closure = CATKEVerticalDiffusivity(; mixing_length, + turbulent_kinetic_energy_equation, + maximum_tracer_diffusivity = 1e-1, + maximum_tke_diffusivity = 1e-1, + maximum_viscosity = 1e-1, + negative_turbulent_kinetic_energy_damping_time_scale = 30, + minimum_turbulent_kinetic_energy = 1e-6, + minimum_convective_buoyancy_flux = 1e-11) + + tracers = tuple(:e, tracers...) + end + + ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, tracers, + tracer_advection, momentum_advection, + free_surface = SplitExplicitFreeSurface(cfl=0.7; grid), + boundary_conditions = ocean_boundary_conditions, + coriolis = HydrostaticSphericalCoriolis()) + + ocean = Simulation(ocean_model; Δt=5minutes, verbose=false) + + elapsed = time_ns() - start_time + msg = string("Finished building ocean component (" * prettytime(elapsed * 1e-9), ").") + @info msg + + return ocean +end + +function omip_sea_ice_component(ocean_model) + start_time = time_ns() + + ocean_grid = ocean_model.grid + Nx, Ny, Nz = size(ocean_grid) + Hx, Hy, Hz = halo_size(ocean_grid) + TX, TY, TZ = topology(ocean_grid) + + λ = λnodes(ocean_grid, Face()) + φ = φnodes(ocean_grid, Face()) + longitude = (λ[1], λ[end]) + latitude = (φ[1], φ[end]) + + sea_ice_grid = LatitudeLongitudeGrid(arch; longitude, latitude, + size = (Nx, Ny), + halo = (Hx, Hy), + topology = (TX, TY, Flat)) + + if ocean_grid isa ImmersedBoundaryGrid + h = ocean_grid.immersed_boundary.bottom_height + land = interior(h) .>= 0 + sea_ice_grid = ImmersedBoundaryGrid(sea_ice_grid, GridFittedBoundary(land)) + end + + sea_ice_ocean_heat_flux = Field{Center, Center, Nothing}(ocean_grid) + + Nz = size(ocean_grid, 3) + So = ocean_model.tracers.S + ocean_surface_salinity = view(So, :, :, Nz) + bottom_bc = IceWaterThermalEquilibrium(ocean_surface_salinity) + + u, v, w = ocean_model.velocities + ocean_surface_velocities = (u = view(u, :, :, Nz), #interior(u, :, :, Nz), + v = view(v, :, :, Nz), #interior(v, :, :, Nz), + w = ZeroField()) + + sea_ice_model = SlabSeaIceModel(sea_ice_grid; + velocities = ocean_surface_velocities, + advection = WENO(), + ice_consolidation_thickness = 0.05, + ice_salinity = 4, + internal_heat_flux = ConductiveFlux(conductivity=2), + top_heat_flux = ConstantField(0), # W m⁻² + top_heat_boundary_condition = PrescribedTemperature(-10), + bottom_heat_boundary_condition = bottom_bc, + bottom_heat_flux = sea_ice_ocean_heat_flux) + + sea_ice = Simulation(sea_ice_model, Δt=5minutes, verbose=false) + + elapsed = time_ns() - start_time + msg = string("Finished building sea ice component (" * prettytime(elapsed * 1e-9), ").") + @info msg + + return sea_ice +end + +const c = Center() +const f = Face() + +@kernel function infer_bottom_height!(bottom_height, T, grid) + i, j = @index(Global, NTuple) + + Nz = size(grid, 3) + + @inbounds for k = Nz:-1:1 + if isnan(T[i, j, k]) + bottom_height[i, j] = znode(i, j, k+1, grid, c, c, f) + break + end + end +end + +@kernel function nan_land!(T) + i, j, k = @index(Global, NTuple) + + @inbounds begin + Tᵢ = T[i, j, k] + land = Tᵢ < -10 + T[i, j, k] = ifelse(land, NaN, Tᵢ) + end +end + diff --git a/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl b/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl new file mode 100644 index 00000000..9238a70f --- /dev/null +++ b/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl @@ -0,0 +1,40 @@ +using GLMakie +using Oceananigans +using JLD2 + +sea_ice_filename = "freely_decaying_regional_simulation_heat_only_sea_ice_thickness.jld2" +fields_filename = "freely_decaying_regional_simulation_heat_only_fields.jld2" + +ht = FieldTimeSeries(sea_ice_filename, "h") +Tt = FieldTimeSeries(fields_filename, "T") +times = ht.times +Nt = length(times) + +for n = 1:Nt + Tn = interior(Tt[n]) + hn = interior(ht[n]) + land = Tn .== 0 + Tn[land] .= NaN + hn[land] .= NaN +end + +fig = Figure(resolution=(1200, 600)) +axT = Axis(fig[1, 1], xlabel="Longitude", ylabel="Latitude") +axh = Axis(fig[2, 1], xlabel="Longitude", ylabel="Latitude") + +n = Observable(1) +Tn = @lift interior(Tt[$n], :, :, 1) +hn = @lift interior(ht[$n], :, :, 1) + +λ, φ, z = nodes(Tt) + +hmT = heatmap!(axT, λ, φ, Tn, nan_color=:lightyellow, colormap=:thermal, colorrange=(-2, 22)) +hmh = heatmap!(axh, λ, φ, hn, nan_color=:lightyellow, colormap=:grays, colorrange=(0, 1)) + +Colorbar(fig[1, 2], hmT, label="Temperature (ᵒC)") +Colorbar(fig[2, 2], hmh, label="Sea ice thickness (m)") + +record(fig, "free_decay_southern_ocean.mp4", 1:Nt, framerate=12) do nn + @info "Plotting frame $nn of $Nt..." + n[] = nn +end diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl new file mode 100644 index 00000000..093b9415 --- /dev/null +++ b/experiments/prototype_omip_simulation/single_column_omip_simulation.jl @@ -0,0 +1,342 @@ +using Oceananigans +using Oceananigans.Units +using Oceananigans.BuoyancyModels: buoyancy_frequency +using Oceananigans.Units: Time + +using ClimaOcean +using ClimaOcean.DataWrangling.ECCO2: ecco2_column + +using GLMakie +using Printf +using Dates + +include("omip_components.jl") + +locations = ( + eastern_mediterranean = (λ = 30, φ = 32), + ocean_station_papa = (λ = 215, φ = 50), + north_atlantic = (λ = 325, φ = 50), + drake_passage = (λ = 300, φ = -60), + weddell_sea = (λ = 325, φ = -70), + tasman_southern_ocean = (λ = 145, φ = -55), +) + +location = :ocean_station_papa + +start_time = time_ns() + +epoch = Date(1992, 1, 1) +date = Date(1992, 10, 1) +start_seconds = Second(date - epoch).value +Tᵢ = ecco2_field(:temperature, date) +Sᵢ = ecco2_field(:salinity, date) + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +##### +##### Construct the grid +##### + +Nz = 80 +H = 400 +arch = CPU() +λ★, φ★ = locations[location] +i★, j★, longitude, latitude = ecco2_column(λ★, φ★) + +grid = LatitudeLongitudeGrid(arch; longitude, latitude, + size = (1, 1, Nz), + z = (-H, 0), + topology = (Periodic, Periodic, Bounded)) + +ocean = omip_ocean_component(grid) + +backend = JRA55NetCDFBackend(8 * 60) +atmosphere = JRA55_prescribed_atmosphere(:; longitude, latitude, backend) + +ocean.model.clock.time = start_seconds +ocean.model.clock.iteration = 0 +interpolate!(ocean.model.tracers.T, Tᵢ) +interpolate!(ocean.model.tracers.S, Sᵢ) +set!(ocean.model, e=1e-6) + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +times = ua.times + +fig = Figure(size=(1200, 1800)) +axu = Axis(fig[1, 1]) +axT = Axis(fig[2, 1]) +axq = Axis(fig[3, 1]) + +lines!(axu, times ./ days, interior(ua, 1, 1, 1, :)) +lines!(axu, times ./ days, interior(va, 1, 1, 1, :)) +lines!(axT, times ./ days, interior(Ta, 1, 1, 1, :)) +lines!(axq, times ./ days, interior(qa, 1, 1, 1, :)) + +display(fig) + +sea_ice = nothing +radiation = Radiation() +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=start_seconds + 30days) + +elapsed = time_ns() - start_time +@info "Coupled simulation built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +wall_clock = Ref(time_ns()) + +function progress(sim) + msg = string("(", location, ")") + msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + e = sim.model.ocean.model.tracers.e + + τˣ = first(sim.model.fluxes.total.ocean.momentum.τˣ) + τʸ = first(sim.model.fluxes.total.ocean.momentum.τʸ) + u★ = sqrt(sqrt(τˣ^2 + τʸ^2)) + Q = first(sim.model.fluxes.total.ocean.heat) + + Nz = size(T, 3) + msg *= @sprintf(", u★: %.2f m s⁻¹", u★) + msg *= @sprintf(", Q: %.2f W m⁻²", Q) + msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) + msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) + msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) + + @info msg +end + +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) + +# Build flux outputs +Ju = coupled_model.fluxes.total.ocean.momentum.u +Jv = coupled_model.fluxes.total.ocean.momentum.v +JT = coupled_model.fluxes.total.ocean.tracers.T +Js = coupled_model.fluxes.total.ocean.tracers.S +E = coupled_model.fluxes.turbulent.fields.water_vapor +Qc = coupled_model.fluxes.turbulent.fields.sensible_heat +Qv = coupled_model.fluxes.turbulent.fields.latent_heat +ρₒ = coupled_model.fluxes.ocean_reference_density +cₚ = coupled_model.fluxes.ocean_heat_capacity + +Q = ρₒ * cₚ * Jᵀ +τx = ρₒ * Jᵘ +τy = ρₒ * Jᵛ +N² = buoyancy_frequency(ocean.model) +κc = ocean.model.diffusivity_fields.κᶜ + +fluxes = (; τx, τy, E, Js, Q, Qc, Qc) + +auxiliary_fields = (; N², κc) +fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + +# Slice fields at the surface +outputs = merge(fields, fluxes) + +output_attributes = Dict{String, Any}( + "κc" => Dict("long_name" => "Tracer diffusivity", "units" => "m^2 / s"), + "Q" => Dict("long_name" => "Net heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Qv" => Dict("long_name" => "Latent heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Qc" => Dict("long_name" => "Sensible heat flux", "units" => "W / m^2", "convention" => "positive upwards"), + "Js" => Dict("long_name" => "Salt flux", "units" => "g kg⁻¹ m s⁻¹", "convention" => "positive upwards"), + "E" => Dict("long_name" => "Freshwater evaporation flux", "units" => "m s⁻¹", "convention" => "positive upwards"), + "e" => Dict("long_name" => "Turbulent kinetic energy", "units" => "m^2 / s^2"), + "τx" => Dict("long_name" => "Zonal momentum flux", "units" => "m^2 / s^2"), + "τx" => Dict("long_name" => "Meridional momentum flux", "units" => "m^2 / s^2"), +) + +filename = "single_column_omip_$location" + +coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs; filename, + schedule = TimeInterval(3hours), + overwrite_existing = true) + +#= +coupled_simulation.output_writers[:nc] = NetCDFOutputWriter(ocean.model, outputs; filename, + schedule = AveragedTimeInterval(1days), + output_attributes, + overwrite_existing = true) +=# + +run!(coupled_simulation) + +#= +filename *= ".jld2" + +ut = FieldTimeSeries(filename, "u") +vt = FieldTimeSeries(filename, "v") +Tt = FieldTimeSeries(filename, "T") +St = FieldTimeSeries(filename, "S") +et = FieldTimeSeries(filename, "e") +N²t = FieldTimeSeries(filename, "N²") +κt = FieldTimeSeries(filename, "κᶜ") + +Qt = FieldTimeSeries(filename, "Q") +Qset = FieldTimeSeries(filename, "Qse") +Qlat = FieldTimeSeries(filename, "Qla") +Jˢt = FieldTimeSeries(filename, "Jˢ") +Et = FieldTimeSeries(filename, "E") +τˣt = FieldTimeSeries(filename, "τˣ") +τʸt = FieldTimeSeries(filename, "τʸ") + +Nz = size(Tt, 3) +times = Qt.times + +ua = atmosphere.velocities.u +va = atmosphere.velocities.v +Ta = atmosphere.tracers.T +qa = atmosphere.tracers.q +Qlw = atmosphere.downwelling_radiation.longwave +Qsw = atmosphere.downwelling_radiation.shortwave +Pr = atmosphere.freshwater_flux.rain +Ps = atmosphere.freshwater_flux.snow + +Nt = length(times) +uat = zeros(Nt) +vat = zeros(Nt) +Tat = zeros(Nt) +qat = zeros(Nt) +Qswt = zeros(Nt) +Qlwt = zeros(Nt) +Pt = zeros(Nt) + +for n = 1:Nt + t = times[n] + uat[n] = ua[1, 1, 1, Time(t)] + vat[n] = va[1, 1, 1, Time(t)] + Tat[n] = Ta[1, 1, 1, Time(t)] + qat[n] = qa[1, 1, 1, Time(t)] + Qswt[n] = Qsw[1, 1, 1, Time(t)] + Qlwt[n] = Qlw[1, 1, 1, Time(t)] + Pt[n] = Pr[1, 1, 1, Time(t)] + Ps[1, 1, 1, Time(t)] +end + +set_theme!(Theme(linewidth=3)) + +fig = Figure(size=(2400, 1800)) + +axτ = Axis(fig[1, 1:2], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") +axu = Axis(fig[2, 1:2], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") +axQ = Axis(fig[1, 3:4], xlabel="Days since Oct 1 1992", ylabel="Heat flux (W m⁻²)") +axT = Axis(fig[2, 3:4], xlabel="Days since Oct 1 1992", ylabel="Surface temperature (ᵒC)") +axF = Axis(fig[1, 5:6], xlabel="Days since Oct 1 1992", ylabel="Freshwater volume flux (m s⁻¹)") +axS = Axis(fig[2, 5:6], xlabel="Days since Oct 1 1992", ylabel="Surface salinity (g kg⁻¹)") + +axuz = Axis(fig[3, 1], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") +axTz = Axis(fig[3, 2], xlabel="Temperature (ᵒC)", ylabel="z (m)") +axSz = Axis(fig[3, 3], xlabel="Salinity (g kg⁻¹)", ylabel="z (m)") +axNz = Axis(fig[3, 4], xlabel="Buoyancy frequency (s⁻²)", ylabel="z (m)") +axκz = Axis(fig[3, 5], xlabel="Eddy diffusivity (m² s⁻¹)", ylabel="z (m)", xscale=log10) +axez = Axis(fig[3, 6], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)", xscale=log10) + +title = @sprintf("Single column simulation at %.2f, %.2f", φ★, λ★) +Label(fig[0, 1:6], title) + +slider = Slider(fig[4, 1:6], range=1:Nt, startvalue=1) +n = slider.value + +times = (times .- times[1]) ./days +tn = @lift times[$n] + +colors = Makie.wong_colors() + +#lines!(axu, times, uat, color=colors[1]) +#lines!(axu, times, vat, color=colors[2]) + +ρₒ = coupled_model.fluxes.ocean_reference_density +Jᵘt = interior(τˣt, 1, 1, 1, :) ./ ρₒ +Jᵛt = interior(τʸt, 1, 1, 1, :) ./ ρₒ +u★ = @. (Jᵘt^2 + Jᵛt^2)^(1/4) + +lines!(axu, times, interior(ut, 1, 1, Nz, :), color=colors[1], label="Zonal") +lines!(axu, times, interior(vt, 1, 1, Nz, :), color=colors[2], label="Meridional") +lines!(axu, times, u★, color=colors[3], label="Ocean-side u★") +vlines!(axu, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axu) + +lines!(axτ, times, interior(τˣt, 1, 1, 1, :), label="Zonal") +lines!(axτ, times, interior(τʸt, 1, 1, 1, :), label="Meridional") +vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axτ) + +lines!(axT, times, Tat .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") +lines!(axT, times, interior(Tt, 1, 1, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") +vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axT) + +lines!(axQ, times, interior(Qt, 1, 1, 1, :), color=colors[1], label="Total", linewidth=6) +lines!(axQ, times, interior(Qset, 1, 1, 1, :), color=colors[2], label="Sensible", linewidth=2) +lines!(axQ, times, interior(Qlat, 1, 1, 1, :), color=colors[3], label="Latent", linewidth=2) +lines!(axQ, times, - Qswt, color=colors[4], label="Shortwave", linewidth=2) +lines!(axQ, times, - Qlwt, color=colors[5], label="Longwave", linewidth=2) +vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axQ) + +#lines!(axF, times, interior(Jˢt, 1, 1, 1, :), label="Net freshwater flux") +lines!(axF, times, Pt, label="Prescribed freshwater flux") +lines!(axF, times, - interior(Et, 1, 1, 1, :), label="Evaporation") +vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axF) + +lines!(axS, times, interior(St, 1, 1, Nz, :)) +vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) + +zc = znodes(Tt) +zf = znodes(κt) +un = @lift interior(ut[$n], 1, 1, :) +vn = @lift interior(vt[$n], 1, 1, :) +Tn = @lift interior(Tt[$n], 1, 1, :) +Sn = @lift interior(St[$n], 1, 1, :) +κn = @lift interior(κt[$n], 1, 1, :) +en = @lift max.(1e-6, interior(et[$n], 1, 1, :)) +N²n = @lift interior(N²t[$n], 1, 1, :) + +scatterlines!(axuz, un, zc, label="u") +scatterlines!(axuz, vn, zc, label="v") +scatterlines!(axTz, Tn, zc) +scatterlines!(axSz, Sn, zc) +scatterlines!(axez, en, zc) +scatterlines!(axNz, N²n, zf) +scatterlines!(axκz, κn, zf) + +axislegend(axuz) + +Tmax = maximum(interior(Tt)) +Tmin = minimum(interior(Tt)) +xlims!(axTz, Tmin - 0.1, Tmax + 0.1) + +Nmax = maximum(interior(N²t)) +Nmin = minimum(interior(N²t)) +xlims!(axNz, Nmin / 2, Nmin * 1.1) + +emax = maximum(interior(et)) +xlims!(axez, 8e-7, emax * 1.1) +xlims!(axκz, 1e-7, 10) + +Smax = maximum(interior(St)) +Smin = minimum(interior(St)) +xlims!(axSz, Smin - 0.2, Smax + 0.2) + +display(fig) + +record(fig, "$(location)_single_column_simulation.mp4", 1:Nt, framerate=24) do nn + @info "Drawing frame $nn of $Nt..." + n[] = nn +# end +end +=# diff --git a/prototype_omip_simulation/correct_oceananigans.jl b/prototype_omip_simulation/correct_oceananigans.jl deleted file mode 100644 index 3c3dab76..00000000 --- a/prototype_omip_simulation/correct_oceananigans.jl +++ /dev/null @@ -1,61 +0,0 @@ -#### -#### This file contains all the bug-fixes that still didn't get merged in Oceananigans.jl -#### - -using Oceananigans.BuoyancyModels: ∂z_b -using Oceananigans.Operators -using Oceananigans.Grids: peripheral_node, inactive_node -using Oceananigans.TurbulenceClosures: top_buoyancy_flux, getclosure, taper - -import Oceananigans.TurbulenceClosures: _compute_ri_based_diffusivities! - -@inline function _compute_ri_based_diffusivities!(i, j, k, diffusivities, grid, closure, - velocities, tracers, buoyancy, tracer_bcs, clock) - - # Ensure this works with "ensembles" of closures, in addition to ordinary single closures - closure_ij = getclosure(i, j, closure) - - ν₀ = closure_ij.ν₀ - κ₀ = closure_ij.κ₀ - κᶜᵃ = closure_ij.κᶜᵃ - Cᵃᵛ = closure_ij.Cᵃᵛ - Ri₀ = closure_ij.Ri₀ - Riᵟ = closure_ij.Riᵟ - tapering = closure_ij.Ri_dependent_tapering - - # Convection and entrainment - N² = ∂z_b(i, j, k, grid, buoyancy, tracers) - - # Conditions - convecting = N² < 0 # applies regardless of Qᵇ - - # Convective adjustment diffusivity - κᶜᵃ = ifelse(convecting, κᶜᵃ, zero(grid)) - - # Shear mixing diffusivity and viscosity - Ri = ℑxyᶜᶜᵃ(i, j, k, grid, ℑxyᶠᶠᵃ, diffusivities.Ri) - τ = taper(tapering, Ri, Ri₀, Riᵟ) - - κᶜ★ = κ₀ * τ - κᵘ★ = ν₀ * τ - - # Previous diffusivities - κᶜ = diffusivities.κᶜ - κᵘ = diffusivities.κᵘ - - # New diffusivities - κᶜ⁺ = κᶜ★ + κᶜᵃ - κᵘ⁺ = κᵘ★ - - # Set to zero on periphery and NaN within inactive region - on_periphery = peripheral_node(i, j, k, grid, Center(), Center(), Face()) - within_inactive = inactive_node(i, j, k, grid, Center(), Center(), Face()) - κᶜ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᶜ⁺)) - κᵘ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᵘ⁺)) - - # Update by averaging in time - @inbounds κᶜ[i, j, k] = (Cᵃᵛ * κᶜ[i, j, k] + κᶜ⁺) / (1 + Cᵃᵛ) - @inbounds κᵘ[i, j, k] = (Cᵃᵛ * κᵘ[i, j, k] + κᵘ⁺) / (1 + Cᵃᵛ) - - return nothing -end \ No newline at end of file diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 3205e741..6d611451 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -60,7 +60,6 @@ function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) return sfc_tracers end -include("three_dimensional_operators.jl") include("radiation.jl") include("latitude_dependent_albedo.jl") include("roughness_lengths.jl") From 91bc4b06c9149bb455c7c9c4b8790cf83deabc13 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:01:31 -0400 Subject: [PATCH 394/716] some changes --- .../ocean_sea_ice_surface_fluxes.jl | 4 +- .../CrossRealmFluxes/roughness_lengths.jl | 48 +++++++++---------- .../similarity_theory_turbulent_fluxes.jl | 3 +- .../CrossRealmFluxes/stability_functions.jl | 39 +++++++++++---- 4 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index a468d3a5..3b4ef57b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -259,8 +259,8 @@ limit_fluxes_over_sea_ice!(args...) = nothing # 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ₒ = ℑxᶜᵃᵃ(i, j, 1, grid, ocean_state.u) + vₒ = ℑyᵃᶜᵃ(i, j, 1, grid, ocean_state.v) Tₒ = ocean_state.T[i, j, 1] Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) Sₒ = ocean_state.S[i, j, 1] diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index 0c99fbb6..28152c56 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -12,30 +12,6 @@ struct ScalarRoughnessLength{FT, V, R} maximum_roughness_length :: FT end -function default_roughness_lengths(FT=Float64) - momentum = MomentumRoughnessLength(FT) - temperature = ScalarRoughnessLength(FT) - water_vapor = ScalarRoughnessLength(FT) - return SimilarityScales(momentum, temperature, water_vapor) -end - -# Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ ℓu / ν` -# Edson et al. (2013), equation (28) -@inline empirical_scaling_function(R★ :: FT, args...) where FT = - ifelse(R★ == 0, FT(0), convert(FT, 5.85e-5 / R★ ^ 0.72)) - -# Temeprature-dependent viscosity law: assumes that θ comes in Kelvin -@inline function temperature_dependent_viscosity(θ :: FT) where FT - T = convert(FT, θ - celsius_to_kelvin) - ν = convert(FT, 1.326e-5 * (1 + 6.542e-3 * T + 8.301e-6 * T^2 - 4.84e-9 * T^3)) - - return ν -end - -# Fallbacks for constant roughness length! -@inline roughness_length(ℓ, u★, args...) = ℓ(u★, args...) -@inline roughness_length(ℓ::Number, args...) = ℓ - function ScalarRoughnessLength(FT=Float64; air_kinematic_viscosity = temperature_dependent_viscosity, reynolds_number_scaling_function = empirical_scaling_function, @@ -60,6 +36,30 @@ function MomentumRoughnessLength(FT=Float64; convert(FT, maximum_roughness_length)) end +function default_roughness_lengths(FT=Float64) + momentum = MomentumRoughnessLength(FT) + temperature = ScalarRoughnessLength(FT) + water_vapor = ScalarRoughnessLength(FT) + return SimilarityScales(momentum, temperature, water_vapor) +end + +# Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ ℓu / ν` +# Edson et al. (2013), equation (28) +@inline empirical_scaling_function(R★ :: FT, args...) where FT = + ifelse(R★ == 0, FT(0), convert(FT, 5.85e-5 / R★ ^ 0.72)) + +# Temeprature-dependent viscosity law: assumes that θ comes in Kelvin +@inline function temperature_dependent_viscosity(θ :: FT) where FT + T = convert(FT, θ - celsius_to_kelvin) + ν = convert(FT, 1.326e-5 * (1 + 6.542e-3 * T + 8.301e-6 * T^2 - 4.84e-9 * T^3)) + + return ν +end + +# Fallbacks for constant roughness length! +@inline roughness_length(ℓ, u★, args...) = ℓ(u★, args...) +@inline roughness_length(ℓ::Number, args...) = ℓ + # Momentum roughness length should be different from scalar roughness length. # Temperature and water vapor can be considered the same (Edison et al 2013) @inline function roughness_length(ℓ::MomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 78b1eb27..9b0d16ef 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -161,7 +161,6 @@ end gravitational_acceleration, von_karman_constant, ℂₐ, - atmos_state.ts, surface_state.ts) # The inital velocity scale assumes that @@ -223,7 +222,7 @@ end atmos_boundary_layer_height, gravitational_acceleration, von_karman_constant, - ℂₐ, 𝒬ₐ, 𝒬ₒ) + ℂₐ, 𝒬ₒ) Δu = differences.u Δv = differences.v diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index dbc8f775..e1a77b1b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -18,12 +18,13 @@ end Statistics.norm(a::SimilarityScales) = norm(a.momentum) + norm(a.temperature) + norm(a.water_vapor) struct MomentumStabilityFunction end + struct ScalarStabilityFunction end struct InitialMomentumStabilityFunction end function default_stability_functions(FT = Float64) - # Computed from Edisen et al. (2013) + # Edison et al. (2013) ψu = MomentumStabilityFunction() ψc = ScalarStabilityFunction() @@ -31,17 +32,22 @@ function default_stability_functions(FT = Float64) end @inline function (ψ::InitialMomentumStabilityFunction)(ζ) + FT = elype(ζ) + + # Parameters + p₁ = convert(FT, 0.35) + ζ⁻ = min(zero(ζ), ζ) ζ⁺ = max(zero(ζ), ζ) - dζ = min(50, 0.35 * ζ⁺) + dζ = min(50, p₁ * ζ⁺) - ψ_stable = - ζ⁺ - 3 / 4 * (ζ⁺ - 5 / 0.35) * exp(-dζ) - 3 / 4 * 5 / 0.35 + ψ_stable = - ζ⁺ - 3 / 4 * (ζ⁺ - 5 / p₁) * exp(-dζ) - 3 / 4 * 5 / p₁ fₘ = sqrt(sqrt(1 - 18 * ζ⁻)) ψ_unstable_1 = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2; fₘ = cbrt(1 - 10 * ζ⁻) - ψ_unstable_2 = 1.5 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3))+ π / sqrt(3) + ψ_unstable_2 = 3 / 2 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3)) + π / sqrt(3) f⁻ = ζ⁻^2 / (1 + ζ⁻^2) ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 @@ -50,17 +56,23 @@ end end @inline function (ψ::MomentumStabilityFunction)(ζ) + FT = elype(ζ) + + # Parameters + p₁ = convert(FT, 0.35) + p₂ = convert(FT, 0.7) + p₃ = convert(FT, 10.15) ζ⁻ = min(zero(ζ), ζ) ζ⁺ = max(zero(ζ), ζ) - dζ = min(50, 0.35 * ζ⁺) + dζ = min(50, p₁ * ζ⁺) - ψ_stable = - 0.7 * ζ⁺ - 3 / 4 * (ζ⁺ - 5 / 0.35) * exp(-dζ) - 3 / 4 * 5 / 0.35 + ψ_stable = - p₂ * ζ⁺ - 3 / 4 * (ζ⁺ - 5 / p₁) * exp(-dζ) - 3 / 4 * 5 / p₁ fₘ = sqrt(sqrt(1 - 15 * ζ⁻)) ψ_unstable_1 = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2; - fₘ = cbrt(1 - 10.15 * ζ⁻) + fₘ = cbrt(1 - p₃ * ζ⁻) ψ_unstable_2 = 1.5 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3))+ π / sqrt(3) f⁻ = ζ⁻^2 / (1 + ζ⁻^2) @@ -70,17 +82,24 @@ end end @inline function (ψ::ScalarStabilityFunction)(ζ) + FT = elype(ζ) + + # Parameters + p₁ = convert(FT, 0.35) + p₂ = convert(FT, 14.28) + p₃ = convert(FT, 8.525) + p₄ = convert(FT, 34.15) ζ⁻ = min(zero(ζ), ζ) ζ⁺ = max(zero(ζ), ζ) - dζ = min(50, 0.35 * ζ⁺) + dζ = min(50, p₁ * ζ⁺) - ψ_stable = - (4 * ζ⁺ / 3)^(3 / 2) - 2 / 3 * (ζ⁺ - 14.28) * exp(-dζ) - 8.525 + ψ_stable = - (4 * ζ⁺ / 3)^(3 / 2) - 2 / 3 * (ζ⁺ - p₂) * exp(-dζ) - p₃ fₕ = sqrt(1 - 15 * ζ⁻) ψ_unstable_1 = 2 * log((1 + fₕ) / 2) - fₕ = cbrt(1 - 34.15 * ζ⁻) + fₕ = cbrt(1 - p₄ * ζ⁻) ψ_unstable_2 = 1.5 * log((1 + fₕ + fₕ^2) / 3) - sqrt(3) * atan((1 + 2fₕ) / sqrt(3))+ π / sqrt(3) f⁻ = ζ⁻^2 / (1 + ζ⁻^2) From a0a58ec598d76bb6987c69e7c1029421e416016c Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:03:06 -0400 Subject: [PATCH 395/716] a comment --- .../CrossRealmFluxes/stability_functions.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index e1a77b1b..ba45e25b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -17,8 +17,9 @@ end Statistics.norm(a::SimilarityScales) = norm(a.momentum) + norm(a.temperature) + norm(a.water_vapor) +# Implementation of stability functions that follow Edison et al (2013) +# We can swap them out easily if we define new types `NewStability` with a method `(f::NewStability)(ζ)` struct MomentumStabilityFunction end - struct ScalarStabilityFunction end struct InitialMomentumStabilityFunction end @@ -36,7 +37,7 @@ end # Parameters p₁ = convert(FT, 0.35) - + ζ⁻ = min(zero(ζ), ζ) ζ⁺ = max(zero(ζ), ζ) dζ = min(50, p₁ * ζ⁺) From 1f8ecb08c635378eabd1de97200d71f7c20446f3 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:05:21 -0400 Subject: [PATCH 396/716] more comments --- .../similarity_theory_turbulent_fluxes.jl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 9b0d16ef..b7f54a4e 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -29,7 +29,7 @@ import SurfaceFluxes.Parameters: ##### Bulk turbulent fluxes based on similarity theory ##### -struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, F} <: AbstractSurfaceFluxesParameters +struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, F} <: AbstractSurfaceFluxesParameters gravitational_acceleration :: FT von_karman_constant :: FT turbulent_prandtl_number :: FT @@ -39,6 +39,7 @@ struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, F} <: AbstractSurfac water_vapor_saturation :: S water_mole_fraction :: W roughness_lengths :: R + bulk_coefficients :: B tolerance :: FT maxiter :: Int iteration :: Int @@ -63,6 +64,7 @@ Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt( adapt(to, fluxes.water_vapor_saturation), adapt(to, fluxes.water_mole_fraction), adapt(to, fluxes.roughness_lengths), + adapt(to, fluxes.bulk_coefficients), fluxes.iteration, fluxes.tolerance, fluxes.maxiter, @@ -104,6 +106,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), roughness_lengths = default_roughness_lengths(FT), + bulk_coefficients = simplified_bulk_coefficients, tolerance = 1e-8, maxiter = Inf, fields = nothing) @@ -117,6 +120,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; water_vapor_saturation, water_mole_fraction, roughness_lengths, + bulk_coefficients, tolerance, maxiter, 0, @@ -135,6 +139,10 @@ function SimilarityTheoryTurbulentFluxes(grid::AbstractGrid; kw...) return SimilarityTheoryTurbulentFluxes(eltype(grid); kw..., fields) end +# The complete bulk coefficient should include also `ψ(ℓ / L)`, but the +# JRA55 atmosphere is adjusted to formulae without this last term so we exclude it +@inline simplified_bulk_coefficient(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) # + ψ(ℓ / L) + ##### ##### Fixed-point iteration for roughness length ##### @@ -213,10 +221,6 @@ end return true end -# The complete bulk coefficient should include also `ψ(ℓ / L)`, but the -# JRA55 atmosphere is adjusted to formulae without this last term so we exclude it -@inline bulk_coefficient(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) # + ψ(ℓ / L) - @inline function initial_guess(differences, similarity_theory, atmos_boundary_layer_height, @@ -322,7 +326,7 @@ end θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬₀) cₚ = AtmosphericThermodynamics.cp_m(ℂ, 𝒬₁) # moist heat capacity - # The temperature difference includes the ``lapse rate'' α = g / h + # Temperature difference including the ``lapse rate'' `α = g / cₚ` Δθ = θ₁ - θ₀ + g / cₚ * Δh q₁ = AtmosphericThermodynamics.vapor_specific_humidity(ℂ, 𝒬₁) From aa852a2e0857353b00938b3daa00cbb7bb1faf29 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:06:05 -0400 Subject: [PATCH 397/716] changing folder --- .../freely_decaying_regional_simulation.jl | 0 experiments/{prototype_omip_simulation => }/omip_components.jl | 0 .../plot_freely_decaying_simulation.jl | 0 .../single_column_omip_simulation.jl | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename experiments/{prototype_omip_simulation => }/freely_decaying_regional_simulation.jl (100%) rename experiments/{prototype_omip_simulation => }/omip_components.jl (100%) rename experiments/{prototype_omip_simulation => }/plot_freely_decaying_simulation.jl (100%) rename experiments/{prototype_omip_simulation => }/single_column_omip_simulation.jl (100%) diff --git a/experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl b/experiments/freely_decaying_regional_simulation.jl similarity index 100% rename from experiments/prototype_omip_simulation/freely_decaying_regional_simulation.jl rename to experiments/freely_decaying_regional_simulation.jl diff --git a/experiments/prototype_omip_simulation/omip_components.jl b/experiments/omip_components.jl similarity index 100% rename from experiments/prototype_omip_simulation/omip_components.jl rename to experiments/omip_components.jl diff --git a/experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl b/experiments/plot_freely_decaying_simulation.jl similarity index 100% rename from experiments/prototype_omip_simulation/plot_freely_decaying_simulation.jl rename to experiments/plot_freely_decaying_simulation.jl diff --git a/experiments/prototype_omip_simulation/single_column_omip_simulation.jl b/experiments/single_column_omip_simulation.jl similarity index 100% rename from experiments/prototype_omip_simulation/single_column_omip_simulation.jl rename to experiments/single_column_omip_simulation.jl From 9954202298f0a0c836b74b066d333e707f70b19e Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:07:27 -0400 Subject: [PATCH 398/716] arch in radiation --- prototype_omip_simulation/prototype_omip_simulation.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 791de761..67b8227d 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -18,7 +18,6 @@ using ClimaOcean.JRA55 using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using ClimaOcean.Bathymetry -include("correct_oceananigans.jl") include("three_dimensional_interpolate_tripolar.jl") ##### @@ -74,7 +73,7 @@ set!(model, backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) -radiation = Radiation() +radiation = Radiation(arch) sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() From 8528f321a7eb0dff86bcde24a2cd11031f04558c Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:08:30 -0400 Subject: [PATCH 399/716] better default --- src/Bathymetry.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 2d7c6ac6..1cc6205d 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -76,7 +76,7 @@ function regrid_bathymetry(target_grid; url = "https://www.ngdc.noaa.gov/thredds/fileServer/global/ETOPO2022/60s/60s_surface_elev_netcdf", filename = "ETOPO_2022_v1_60s_N90W180_surface.nc", interpolation_passes = 1, - connected_regions_allowed = 3) # Allow an `Inf` number of ``lakes'' + connected_regions_allowed = Inf) # Allow an `Inf` number of ``lakes'' filepath = joinpath(dir, filename) From 7509dbaed847b1853e6958c645e5f7499638a756 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:16:21 -0400 Subject: [PATCH 400/716] some changes --- .../prototype_omip_simulation.jl | 4 +- ...ipolar.jl => tripolar_specific_methods.jl} | 13 ++----- src/DataWrangling/ECCO2.jl | 6 +-- src/InitialConditions/InitialConditions.jl | 37 ------------------- 4 files changed, 8 insertions(+), 52 deletions(-) rename prototype_omip_simulation/{three_dimensional_interpolate_tripolar.jl => tripolar_specific_methods.jl} (83%) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 67b8227d..7dad4d01 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -18,10 +18,10 @@ using ClimaOcean.JRA55 using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using ClimaOcean.Bathymetry -include("three_dimensional_interpolate_tripolar.jl") +include("tripolar_specific_methods.jl") ##### -##### Global Ocean at 1/4th of a degree +##### Global Ocean at 1/6th of a degree ##### bathymetry_file = nothing # "bathymetry_tmp.jld2" diff --git a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl b/prototype_omip_simulation/tripolar_specific_methods.jl similarity index 83% rename from prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl rename to prototype_omip_simulation/tripolar_specific_methods.jl index 6c7adb0a..ff9665fe 100644 --- a/prototype_omip_simulation/three_dimensional_interpolate_tripolar.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -1,5 +1,5 @@ using ClimaOcean -import ClimaOcean.InitialConditions: three_dimensional_interpolate! +import ClimaOcean.InitialConditions: interpolate! using Oceananigans using Oceananigans.BoundaryConditions @@ -27,17 +27,10 @@ const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) -function three_dimensional_interpolate!(a::Union{<:TField, <:WField}, b) - - interpolate!(a, b) - - return a -end - import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong, convert_to_native_grid # Here we assume that the tripolar grid is locally orthogonal -@inline function convert_to_latlong(i, j, grid::TRG, uₒ, vₒ) +@inline function convert_to_latlong(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) @@ -46,7 +39,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong, conver return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) end -@inline function convert_to_native_grid(i, j, grid::TRG, uₒ, vₒ) +@inline function convert_to_native_grid(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i, j+1, 1, grid, Face(), Center(), Center()) diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 04c6d209..5c828e2e 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -3,7 +3,7 @@ module ECCO2 export ECCO2Metadata, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.DataWrangling: inpaint_mask! -using ClimaOcean.InitialConditions: three_dimensional_regrid!, three_dimensional_interpolate! +using ClimaOcean.InitialConditions: three_dimensional_regrid!, interpolate! using Oceananigans using Oceananigans.Architectures: architecture, child_architecture @@ -353,7 +353,7 @@ function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename=" parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) f_grid = Field(ecco2_location[name], grid) - three_dimensional_interpolate!(f_grid, f_ecco) + interpolate!(f_grid, f_ecco) set!(field, f_grid) return field @@ -372,7 +372,7 @@ function set!(field::Field, ecco2_metadata::ECCO2Metadata; filename="./inpainted kw...) f_grid = Field(ecco2_location[name], grid) - three_dimensional_interpolate!(f_grid, f) + interpolate!(f_grid, f) set!(field, f_grid) return field diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index c6e3940d..58c36a6b 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -103,43 +103,6 @@ function interpolate!(to_field::Field, from_field::AbstractField) return nothing end -function three_dimensional_interpolate!(a, b) - target_grid = a.grid isa ImmersedBoundaryGrid ? a.grid.underlying_grid : a.grid - source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid - - topo = topology(source_grid) - arch = architecture(target_grid) - arch = child_architecture(arch) - - target_y = yt = cpu_face_constructor_y(target_grid) - target_z = zt = cpu_face_constructor_z(target_grid) - - target_size = Nt = size(target_grid) - - source_x = xs = cpu_face_constructor_x(source_grid) - source_y = ys = cpu_face_constructor_y(source_grid) - - source_size = Ns = size(source_grid) - - # Start by regridding in z - @debug "Interpolating in z" - zgrid = construct_grid(typeof(target_grid), arch, (Ns[1], Ns[2], Nt[3]), (xs, ys, zt), topo) - field_z = Field(location(b), zgrid) - interpolate!(field_z, b) - - # regrid in y - @debug "Interpolating in y" - ygrid = construct_grid(typeof(target_grid), arch, (Ns[1], Nt[2], Nt[3]), (xs, yt, zt), topo) - field_y = Field(location(b), ygrid); - interpolate!(field_y, field_z) - - # Finally regrid in x - @debug "Interpolating in x" - interpolate!(a, field_y) - - return a -end - include("diffuse_tracers.jl") end # module From a2eb628342727369a2f8b07c34716d76a52226da Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:19:49 -0400 Subject: [PATCH 401/716] name change --- prototype_omip_simulation/tripolar_specific_methods.jl | 6 +++--- .../CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index ff9665fe..c143a213 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -27,10 +27,10 @@ const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) -import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong, convert_to_native_grid +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, convert_to_native_frame_grid # Here we assume that the tripolar grid is locally orthogonal -@inline function convert_to_latlong(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) +@inline function convert_to_latlong_frame(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) @@ -39,7 +39,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong, conver return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) end -@inline function convert_to_native_grid(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) +@inline function convert_to_native_frame_grid(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i, j+1, 1, grid, Face(), Center(), Center()) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 3b4ef57b..fe341d64 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -232,7 +232,7 @@ end # Fallback @inline convert_to_latlon_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ -@inline convert_to_native_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_native_frame_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ # Fallback! limit_fluxes_over_sea_ice!(args...) = nothing @@ -330,7 +330,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert back from a zonal - meridional flux to the frame of # reference of the native ocean grid - τˣ, τʸ = convert_to_native_grid(i, j, grid, turbulent_fluxes.x_momentum, + τˣ, τʸ = convert_to_native_frame_grid(i, j, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) inactive = inactive_node(i, j, kᴺ, grid, c, c, c) From 0b6e50204e416151cfce6d8b15cce873a01f8beb Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:25:02 -0400 Subject: [PATCH 402/716] another bugfix --- .../similarity_theory_turbulent_fluxes.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index b7f54a4e..8a50e4bc 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -283,9 +283,9 @@ end ζ10 = ifelse(Ri < 0, χc * Ri / (1 + Ri / Riᶜ), χc * Ri * (1 + 27 / 9 * Ri / χc)) L10 = h / ζ10 - u★ = uτ * ϰ / bulk_coefficient(ψu, h, ℓu₀, L10) - θ★ = Δθ * ϰ / bulk_coefficient(ψθ, h, ℓθ₀, L10) - q★ = Δq * ϰ / bulk_coefficient(ψq, h, ℓθ₀, L10) + u★ = uτ * ϰ / similarity_theory.bulk_coefficients(ψu, h, ℓu₀, L10) + θ★ = Δθ * ϰ / similarity_theory.bulk_coefficients(ψθ, h, ℓθ₀, L10) + q★ = Δq * ϰ / similarity_theory.bulk_coefficients(ψq, h, ℓθ₀, L10) return SimilarityScales(u★, θ★, q★) end @@ -382,9 +382,9 @@ end ℓθ₀ = roughness_length(ℓθ, ℓu₀, u★, 𝒬ₒ, ℂ) # Transfer coefficients at height `h` - χu = ϰ / bulk_coefficient(ψu, h, ℓu₀, L★) - χθ = ϰ / bulk_coefficient(ψθ, h, ℓθ₀, L★) - χq = ϰ / bulk_coefficient(ψq, h, ℓq₀, L★) + χu = ϰ / similarity_theory.bulk_coefficients(ψu, h, ℓu₀, L★) + χθ = ϰ / similarity_theory.bulk_coefficients(ψθ, h, ℓθ₀, L★) + χq = ϰ / similarity_theory.bulk_coefficients(ψq, h, ℓq₀, L★) Δu = differences.u Δv = differences.v From d88ad0a7a84779de588a5b90b4d0511a986e3680 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 2 May 2024 18:30:29 -0400 Subject: [PATCH 403/716] Update src/OceanSimulations/OceanSimulations.jl Co-authored-by: Gregory L. Wagner --- src/OceanSimulations/OceanSimulations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 3352bc44..0545ae4f 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -101,7 +101,7 @@ function ocean_simulation(grid; Δt = 5minutes, tracer_advection = (; T = tracer_advection, S = tracer_advection, e = nothing) end - coriolis = HydrostaticSphericalCoriolis(; rotation_rate, scheme = ActiveCellEnstrophyConserving()) + coriolis = HydrostaticSphericalCoriolis(; rotation_rate) ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, From bdfb264cffce1f01c99c1be7aeb5a5c08ad84b01 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:45:28 -0400 Subject: [PATCH 404/716] convert_to_native_frame --- prototype_omip_simulation/tripolar_specific_methods.jl | 4 ++-- .../CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index c143a213..85c08c7d 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -27,7 +27,7 @@ const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) -import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, convert_to_native_frame_grid +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, convert_to_native_frame # Here we assume that the tripolar grid is locally orthogonal @inline function convert_to_latlong_frame(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) @@ -39,7 +39,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) end -@inline function convert_to_native_frame_grid(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) +@inline function convert_to_native_frame(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i, j+1, 1, grid, Face(), Center(), Center()) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index fe341d64..d1cb1f22 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -232,7 +232,7 @@ end # Fallback @inline convert_to_latlon_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ -@inline convert_to_native_frame_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_native_frame(i, j, grid, uₒ, vₒ) = uₒ, vₒ # Fallback! limit_fluxes_over_sea_ice!(args...) = nothing @@ -330,7 +330,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert back from a zonal - meridional flux to the frame of # reference of the native ocean grid - τˣ, τʸ = convert_to_native_frame_grid(i, j, grid, turbulent_fluxes.x_momentum, + τˣ, τʸ = convert_to_native_frame(i, j, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) inactive = inactive_node(i, j, kᴺ, grid, c, c, c) From 4ab2eb56b5cda0916a902481a44b8e8b7b65f1f3 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:50:20 -0400 Subject: [PATCH 405/716] correct reference name --- src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl | 4 ++-- .../CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl | 4 ++-- src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index 28152c56..aa2a4a81 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -61,7 +61,7 @@ end @inline roughness_length(ℓ::Number, args...) = ℓ # Momentum roughness length should be different from scalar roughness length. -# Temperature and water vapor can be considered the same (Edison et al 2013) +# Temperature and water vapor can be considered the same (Edson et al 2013) @inline function roughness_length(ℓ::MomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT g = ℓ.gravitational_acceleration α = ℓ._wave_parameter @@ -79,7 +79,7 @@ end return min(α * u★^2 / g + ℓᴿ, ℓm) end -# Edison 2013 formulation of scalar roughness length +# Edson 2013 formulation of scalar roughness length @inline function roughness_length(ℓ::ScalarRoughnessLength{FT}, ℓu, u★, 𝒬, ℂ) where FT ℓm = ℓ.maximum_roughness_length diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 8a50e4bc..965f2c00 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -352,7 +352,7 @@ end q★ = estimated_characteristic_scales.water_vapor uτ = velocity_scale - # Similarity functions from Edison et al. (2013) + # Similarity functions from Edson et al. (2013) ψu = similarity_theory.stability_functions.momentum ψθ = similarity_theory.stability_functions.temperature ψq = similarity_theory.stability_functions.water_vapor @@ -396,7 +396,7 @@ end θ★ = χθ * Δθ q★ = χq * Δq - # Buoyancy flux characteristic scale for gustiness (Edison 2013) + # Buoyancy flux characteristic scale for gustiness (Edson 2013) ε★ = - u★ * b★ uᴳ = β * cbrt(ε★ * zᵢ) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index ba45e25b..8fe9351f 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -17,7 +17,7 @@ end Statistics.norm(a::SimilarityScales) = norm(a.momentum) + norm(a.temperature) + norm(a.water_vapor) -# Implementation of stability functions that follow Edison et al (2013) +# Implementation of stability functions that follow Edson et al (2013) # We can swap them out easily if we define new types `NewStability` with a method `(f::NewStability)(ζ)` struct MomentumStabilityFunction end struct ScalarStabilityFunction end @@ -25,7 +25,7 @@ struct InitialMomentumStabilityFunction end function default_stability_functions(FT = Float64) - # Edison et al. (2013) + # Edson et al. (2013) ψu = MomentumStabilityFunction() ψc = ScalarStabilityFunction() From d15097f0d097d37cb02e84c3d4a36fc8ab48e49a Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 18:54:21 -0400 Subject: [PATCH 406/716] some changes --- .../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 965f2c00..10abc3c5 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -249,10 +249,10 @@ end uτ = sqrt(Δu^2 + Δv^2 + convert(FT, 0.25)) # u10 at the reference ten meter height, assuming the initial roughness length is `1e-4` m - u10 = uτ / log(h / ℓuᵢ) * 11.5129 # log(10 / 1e-4) == 11.5129 + u10 = uτ / log(h / ℓuᵢ) * convert(FT, 11.5129) # log(10 / 1e-4) == 11.5129 u★ = convert(FT, 0.035) * u10 - ℓu₀ = roughness_length(ℓu, u★, 𝒬ₐ, ℂₐ) + ℓu₀ = roughness_length(ℓu, u★, 𝒬ₒ, ℂₐ) # Initial neutral coefficients at 10 meter height χuₙ = (ϰ / log(hᵢ / ℓu₀))^2 From f5fa9770ab5825dafd48c1013e328bdda6b84351 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 2 May 2024 19:04:06 -0400 Subject: [PATCH 407/716] first commit --- .../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 10abc3c5..3ac6f8ac 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -278,8 +278,8 @@ end Riᶜ = - h / zᵢ / convert(FT, 0.004) / β^3 # - h / zi / 0.004 / β^3 # Calculating the first stability coefficient and the MO length - # TODO: explain this formulation of the stability function. Is it empirical? - # Found in COARE3.6 + # TODO: explain this formulation of the stability function. + # Is it empirical? (Found in COARE3.6) ζ10 = ifelse(Ri < 0, χc * Ri / (1 + Ri / Riᶜ), χc * Ri * (1 + 27 / 9 * Ri / χc)) L10 = h / ζ10 From c80c2069d00b227da288d026fb2aa5ae3a79b774 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 5 May 2024 14:33:04 -0400 Subject: [PATCH 408/716] some restructuring --- .buildkite/pipeline.yml | 6 +- Manifest.toml | 26 +- Project.toml | 2 + docs/make.jl | 2 +- docs/src/library/internals.md | 4 +- docs/src/library/public.md | 4 +- examples/freely_decaying_mediterranean.jl | 10 +- ...ct_ecco2_data.jl => inspect_ecco4_data.jl} | 26 +- .../freely_decaying_regional_simulation.jl | 8 +- experiments/single_column_omip_simulation.jl | 10 +- .../comparison_to_coare.jl | 16 +- .../ecco2_immersed_grid.jl | 4 +- .../prototype_omip_simulation.jl | 10 +- src/ClimaOcean.jl | 15 +- src/DataWrangling/DataWrangling.jl | 5 +- src/DataWrangling/ECCO2.jl | 384 -------------- src/DataWrangling/ECCO4.jl | 418 +++++++++++++++ src/DataWrangling/ECCO4_climatology.jl | 72 +++ src/DataWrangling/JRA55.jl | 477 +---------------- src/DataWrangling/inpaint_mask.jl | 12 +- .../reanalysis_field_time_series.jl | 488 ++++++++++++++++++ test/runtests.jl | 4 +- test/test_downloading.jl | 2 +- test/test_ecco2.jl | 51 -- test/test_ecco4.jl | 51 ++ test/test_jra55.jl | 12 +- 26 files changed, 1145 insertions(+), 974 deletions(-) rename examples/{inspect_ecco2_data.jl => inspect_ecco4_data.jl} (77%) delete mode 100644 src/DataWrangling/ECCO2.jl create mode 100644 src/DataWrangling/ECCO4.jl create mode 100644 src/DataWrangling/ECCO4_climatology.jl create mode 100644 src/DataWrangling/reanalysis_field_time_series.jl delete mode 100644 test/test_ecco2.jl create mode 100644 test/test_ecco4.jl diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index da06bc30..47e321aa 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -31,10 +31,10 @@ steps: commands: - "julia --project -e 'using Pkg; Pkg.test()'" - - label: "Run ECCO2 tests" - key: "tests_ecco2" + - label: "Run ECCO4 tests" + key: "tests_ecco4" env: CUDA_VISIBLE_DEVICES: "-1" - TEST_GROUP: "ecco2" + TEST_GROUP: "ecco4" commands: - "julia --project -e 'using Pkg; Pkg.test()'" diff --git a/Manifest.toml b/Manifest.toml index 58f5b96f..e360c857 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.3" manifest_format = "2.0" -project_hash = "2a8f25db6ea4e6c9eea1b6a1b3d7fec975bd0d16" +project_hash = "c27b53d61e818e623bc97d879dda37485ae23df0" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -195,6 +195,12 @@ git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" version = "0.1.12" +[[deps.CodeTracking]] +deps = ["InteractiveUtils", "UUIDs"] +git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386" +uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" +version = "1.3.5" + [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" @@ -646,6 +652,12 @@ git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" version = "1.13.2" +[[deps.JuliaInterpreter]] +deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] +git-tree-sha1 = "e9648d90370e2d0317f9518c9c6e0841db54a90b" +uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" +version = "0.9.31" + [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" @@ -830,6 +842,12 @@ weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] SpecialFunctionsExt = "SpecialFunctions" +[[deps.LoweredCodeUtils]] +deps = ["JuliaInterpreter"] +git-tree-sha1 = "31e27f0b0bf0df3e3e951bfcc43fe8c730a219f6" +uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" +version = "2.4.5" + [[deps.Lz4_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" @@ -1205,6 +1223,12 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" +[[deps.Revise]] +deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"] +git-tree-sha1 = "12aa2d7593df490c407a3bbd8b86b8b515017f3e" +uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" +version = "3.5.14" + [[deps.RootSolvers]] deps = ["ForwardDiff"] git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" diff --git a/Project.toml b/Project.toml index d97e9d8f..2329cae6 100644 --- a/Project.toml +++ b/Project.toml @@ -6,6 +6,7 @@ version = "0.2.0" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +CFTime = "179af706-886a-5703-950a-314cd64e0468" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" CubicSplines = "9c784101-8907-5a6d-9be6-98f00873c89b" @@ -20,6 +21,7 @@ KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" diff --git a/docs/make.jl b/docs/make.jl index 9724e318..93f1ad7f 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,7 +15,7 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - "inspect_ecco2_data.jl", + "inspect_ecco4_data.jl", ] for file in to_be_literated diff --git a/docs/src/library/internals.md b/docs/src/library/internals.md index 173ade94..fa16548a 100644 --- a/docs/src/library/internals.md +++ b/docs/src/library/internals.md @@ -31,10 +31,10 @@ Modules = [ClimaOcean.DataWrangling] Public = false ``` -## ECCO2 +## ECCO4 ```@autodocs -Modules = [ClimaOcean.ECCO2] +Modules = [ClimaOcean.ECCO4] Public = false ``` diff --git a/docs/src/library/public.md b/docs/src/library/public.md index 65a7fed6..b0accc8a 100644 --- a/docs/src/library/public.md +++ b/docs/src/library/public.md @@ -32,10 +32,10 @@ Modules = [ClimaOcean.DataWrangling] Private = false ``` -## ECCO2 +## ECCO4 ```@autodocs -Modules = [ClimaOcean.ECCO2] +Modules = [ClimaOcean.ECCO4] Private = false ``` diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 83b719c4..f860f535 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -2,7 +2,7 @@ using GLMakie using Oceananigans using Oceananigans: architecture using ClimaOcean -using ClimaOcean.ECCO2 +using ClimaOcean.ECCO4 using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units @@ -70,14 +70,14 @@ model = HydrostaticFreeSurfaceModel(; grid, # Initializing the model # -# the model can be initialized with custom values or with ecco2 fields. -# In this case, our ECCO2 dataset has access to a temperature and a salinity -# field, so we initialize T and S from ECCO2. +# the model can be initialized with custom values or with ecco4 fields. +# In this case, our ECCO4 dataset has access to a temperature and a salinity +# field, so we initialize T and S from ECCO4. # We initialize our passive tracer with a surface blob near to the coasts of Libia @info "initializing model" libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 -set!(model, T = ECCO2Metadata(:temperature), S = ECCO2Metadata(:salinity), c = libia_blob) +set!(model, T = ECCOMetadata(:temperature), S = ECCOMetadata(:salinity), c = libia_blob) fig = Figure() ax = Axis(fig[1, 1]) diff --git a/examples/inspect_ecco2_data.jl b/examples/inspect_ecco4_data.jl similarity index 77% rename from examples/inspect_ecco2_data.jl rename to examples/inspect_ecco4_data.jl index 4c61392b..30030f02 100644 --- a/examples/inspect_ecco2_data.jl +++ b/examples/inspect_ecco4_data.jl @@ -1,28 +1,28 @@ -# # A quick look at ECCO2 data +# # A quick look at ECCO4 data # -# ClimaOcean can download and utilize data from the "ECCO2" state estimate, +# ClimaOcean can download and utilize data from the "ECCO4" state estimate, # which stands for "Estimating the Circulation and Climate of the Ocean" --- two! # # This script shows how to download three-dimensional temperature and salinity fields -# from ECCO2, and makes a short animation to showcase the fields' content. +# from ECCO4, and makes a short animation to showcase the fields' content. # # For this example we need Oceananigans for Field utilities, CairoMakie for plotting # Printf for nice labeling, and of course ClimaOcean to actually download and construct -# the ECCO2 fields. +# the ECCO4 fields. using Oceananigans using CairoMakie using Printf -using ClimaOcean: ECCO2 +using ClimaOcean: ECCO4 -# The function `ecco2_field` provided by `ClimaOcean.DataWrangling.ECCO2` will automatically -# download ECCO2 data if it doesn't already exist at the default location. +# The function `ecco4_field` provided by `ClimaOcean.DataWrangling.ECCO4` will automatically +# download ECCO4 data if it doesn't already exist at the default location. -T = ECCO2.ecco2_field(:temperature) -S = ECCO2.ecco2_field(:salinity) +T = ECCO4.ecco4_field(:temperature) +S = ECCO4.ecco4_field(:salinity) -# Next, we massage the ECCO2 data by inserting NaNs in "land cells", which +# Next, we massage the ECCO4 data by inserting NaNs in "land cells", which # are diagnosed by having an unphysically low temperature. Tp = parent(T) @@ -30,10 +30,10 @@ Sp = parent(S) Sp[Tp .< -10] .= NaN Tp[Tp .< -10] .= NaN -# # Plotting ECCO2 data +# # Plotting ECCO4 data # # We're ready to plot. We'll make an animation -# that depicts how the ECCO2 data changes with depth. +# that depicts how the ECCO4 data changes with depth. fig = Figure(size=(1200, 1400)) @@ -76,7 +76,7 @@ text!(axS, 50, 50, text=depth_str, justification=:center, fontsize=24) stillframes = 10 movingframes = Nz -record(fig, "ECCO2_temperature_salinity.gif", framerate=4) do io +record(fig, "ECCO4_temperature_salinity.gif", framerate=4) do io [recordframe!(io) for _ = 1:stillframes] diff --git a/experiments/freely_decaying_regional_simulation.jl b/experiments/freely_decaying_regional_simulation.jl index 23585c82..172a90cf 100644 --- a/experiments/freely_decaying_regional_simulation.jl +++ b/experiments/freely_decaying_regional_simulation.jl @@ -7,7 +7,7 @@ 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.ECCO4: ecco4_field # using GLMakie using Printf @@ -21,9 +21,9 @@ 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) +Te = ecco4_field(:temperature, date) +Se = ecco4_field(:salinity, date) +# ℋe = ecco4_field(:sea_ice_thickness, date) land = interior(Te) .< -10 interior(Te)[land] .= NaN diff --git a/experiments/single_column_omip_simulation.jl b/experiments/single_column_omip_simulation.jl index 093b9415..1166e726 100644 --- a/experiments/single_column_omip_simulation.jl +++ b/experiments/single_column_omip_simulation.jl @@ -4,7 +4,7 @@ using Oceananigans.BuoyancyModels: buoyancy_frequency using Oceananigans.Units: Time using ClimaOcean -using ClimaOcean.DataWrangling.ECCO2: ecco2_column +using ClimaOcean.DataWrangling.ECCO4: ecco4_column using GLMakie using Printf @@ -28,8 +28,8 @@ 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) +Tᵢ = ecco4_field(:temperature, date) +Sᵢ = ecco4_field(:salinity, date) elapsed = time_ns() - start_time @info "Initial condition built. " * prettytime(elapsed * 1e-9) @@ -43,7 +43,7 @@ Nz = 80 H = 400 arch = CPU() λ★, φ★ = locations[location] -i★, j★, longitude, latitude = ecco2_column(λ★, φ★) +i★, j★, longitude, latitude = ecco4_column(λ★, φ★) grid = LatitudeLongitudeGrid(arch; longitude, latitude, size = (1, 1, Nz), @@ -52,7 +52,7 @@ grid = LatitudeLongitudeGrid(arch; longitude, latitude, ocean = omip_ocean_component(grid) -backend = JRA55NetCDFBackend(8 * 60) +backend = NetCDFBackend(8 * 60) atmosphere = JRA55_prescribed_atmosphere(:; longitude, latitude, backend) ocean.model.clock.time = start_seconds diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index 97ab36e2..a573c202 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -3,20 +3,20 @@ using Oceananigans.Units using ClimaOcean using Oceananigans using Oceananigans.Operators -using ClimaOcean.ECCO2 +using ClimaOcean.ECCO4 using ClimaOcean.OceanSimulations using Oceananigans.Units using ClimaOcean.JRA55: JRA55_prescribed_atmosphere using ClimaOcean.OceanSeaIceModels: Radiation -# Upload ECCO2 fields -T = ECCO2.ecco2_field(:temperature) -S = ECCO2.ecco2_field(:salinity) -u = ECCO2.ecco2_field(:u_velocity) -v = ECCO2.ecco2_field(:v_velocity) +# Upload ECCO4 fields +T = ECCO4.ecco4_field(:temperature) +S = ECCO4.ecco4_field(:salinity) +u = ECCO4.ecco4_field(:u_velocity) +v = ECCO4.ecco4_field(:v_velocity) -include("ecco2_immersed_grid.jl") -grid = ecco2_immersed_grid() +include("ecco4_immersed_grid.jl") +grid = ecco4_immersed_grid() # Let's leave out the radiation for the moment (too simple to test) atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory(), grid = grid.underlying_grid) diff --git a/prototype_omip_simulation/ecco2_immersed_grid.jl b/prototype_omip_simulation/ecco2_immersed_grid.jl index 64977ccc..f3de1573 100644 --- a/prototype_omip_simulation/ecco2_immersed_grid.jl +++ b/prototype_omip_simulation/ecco2_immersed_grid.jl @@ -1,7 +1,7 @@ using Oceananigans.Grids: architecture, location, node, with_halo -function ecco2_immersed_grid() - mask = ecco2_center_mask() +function ecco4_immersed_grid() + mask = ecco4_center_mask() grid = with_halo((3, 3, 3), mask.grid) Nx, Ny, Nz = size(grid) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 7dad4d01..72cee915 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -6,7 +6,7 @@ using OrthogonalSphericalShellGrids using Oceananigans using Oceananigans: architecture using ClimaOcean -using ClimaOcean.ECCO2 +using ClimaOcean.ECCO4 using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units @@ -15,7 +15,7 @@ using ClimaOcean.OceanSeaIceModels using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 -using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere +using ClimaOcean.JRA55: NetCDFBackend, JRA55_prescribed_atmosphere using ClimaOcean.Bathymetry include("tripolar_specific_methods.jl") @@ -64,14 +64,14 @@ ocean = ocean_simulation(grid; free_surface, closure) model = ocean.model set!(model, - T = ECCO2Metadata(:temperature), - S = ECCO2Metadata(:salinity)) + T = ECCOMetadata(:temperature), + S = ECCOMetadata(:salinity)) ##### ##### The atmosphere ##### -backend = JRA55NetCDFBackend(4) +backend = NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation(arch) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 2786733f..a5b5366b 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -5,13 +5,13 @@ export MinimumTemperatureSeaIce, Radiation, JRA55_prescribed_atmosphere, - JRA55NetCDFBackend, - ecco2_field, + NetCDFBackend, + ecco4_field, regrid_bathymetry, stretched_vertical_faces, PowerLawStretching, LinearStretching, jra55_field_time_series, - ecco2_field, ECCO2Metadata, + ecco4_field, ECCOMetadata, initialize! using Oceananigans @@ -29,13 +29,14 @@ include("OceanSimulations/OceanSimulations.jl") using .VerticalGrids using .Bathymetry using .DataWrangling: JRA55 -using .DataWrangling: ECCO2 +using .DataWrangling: ECCO4 using .InitialConditions using .OceanSeaIceModels: OceanSeaIceModel using .OceanSimulations -using .DataWrangling: JRA55, ECCO2 -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend -using ClimaOcean.DataWrangling.ECCO2: ecco2_field +using .DataWrangling: JRA55, ECCO4 +using ClimaOcean.DataWrangling: NetCDFBackend +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO4: ecco4_field using .OceanSeaIceModels: OceanSeaIceModel, Radiation diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index 706c7dcf..3d514760 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -70,10 +70,11 @@ function save_field_time_series!(fts; path, name, overwrite_existing=false) end include("inpaint_mask.jl") +include("reanalysis_field_time_series.jl") include("JRA55.jl") -include("ECCO2.jl") +include("ECCO4.jl") using .JRA55 -using .ECCO2 +using .ECCO4 end # module diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl deleted file mode 100644 index 5c828e2e..00000000 --- a/src/DataWrangling/ECCO2.jl +++ /dev/null @@ -1,384 +0,0 @@ -module ECCO2 - -export ECCO2Metadata, ecco2_field, ecco2_center_mask, adjusted_ecco_tracers, initialize! - -using ClimaOcean.DataWrangling: inpaint_mask! -using ClimaOcean.InitialConditions: three_dimensional_regrid!, interpolate! - -using Oceananigans -using Oceananigans.Architectures: architecture, child_architecture -using Oceananigans.BoundaryConditions -using Oceananigans.DistributedComputations: DistributedField, all_reduce, barrier! -using Oceananigans.Utils -using KernelAbstractions: @kernel, @index -using NCDatasets -using Downloads: download - -import Oceananigans.Fields: set! - -# Ecco field used to set model's initial conditions -struct ECCO2Metadata - name :: Symbol - year :: Int - month :: Int - day :: Int -end - -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, -] - -# We only have 1992 at the moment -ECCO2Metadata(name::Symbol) = ECCO2Metadata(name, 1992, 1, 2) - -filename(data::ECCO2Metadata) = "ecco2_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).nc" - -ecco2_file_names = Dict( - :temperature => "THETA.1440x720x50.19920102.nc", - :salinity => "SALT.1440x720x50.19920102.nc", - :sea_ice_thickness => "SIheff.1440x720.19920102.nc", - :sea_ice_area_fraction => "SIarea.1440x720.19920102.nc", - :u_velocity => "UVEL.1440x720.19920102.nc", - :v_velocity => "VVEL.1440x720.19920102.nc", -) - -variable_is_three_dimensional = Dict( - :temperature => true, - :salinity => true, - :u_velocity => true, - :v_velocity => true, - :sea_ice_thickness => false, - :sea_ice_area_fraction => false, -) - -ecco2_short_names = Dict( - :temperature => "THETA", - :salinity => "SALT", - :u_velocity => "UVEL", - :v_velocity => "VVEL", - :sea_ice_thickness => "SIheff", - :sea_ice_area_fraction => "SIarea" -) - -ecco2_location = Dict( - :temperature => (Center, Center, Center), - :salinity => (Center, Center, Center), - :sea_ice_thickness => (Center, Center, Nothing), - :sea_ice_area_fraction => (Center, Center, Nothing), - :u_velocity => (Face, Center, Center), - :v_velocity => (Center, Face, Center), -) - -ecco2_urls = Dict( - :temperature => "https://www.dropbox.com/scl/fi/01h96yo2fhnnvt2zkmu0d/THETA.1440x720x50.19920102.nc?rlkey=ycso2v09gc6v2qb5j0lff0tjs", - :salinity => "https://www.dropbox.com/scl/fi/t068we10j5skphd461zg8/SALT.1440x720x50.19920102.nc?rlkey=r5each0ytdtzh5icedvzpe7bw", - :sea_ice_thickness => "https://www.dropbox.com/scl/fi/x0v9gjrfebwsef4tv1dvn/SIheff.1440x720.19920102.nc?rlkey=2uel3jtzbsplr28ejcnx3u6am", - :sea_ice_area_fraction => "https://www.dropbox.com/scl/fi/q14moq3201zicppu8ff8h/SIarea.1440x720.19920102.nc?rlkey=pt7pt80gr7r6mmjm9e0u4f5n1", - :u_velocity => "https://www.dropbox.com/scl/fi/myur9kpanc5mprrf5ge32/UVEL.1440x720x50.19920102.nc?rlkey=7a5dpvfgoc87yr6q5ktrqwndu", - :v_velocity => "https://www.dropbox.com/scl/fi/buic35gssyeyfqohenkeo/VVEL.1440x720x50.19920102.nc?rlkey=fau48w4t5ruop4s6gm8t7z0a0", -) - -surface_variable(variable_name) = variable_name == :sea_ice_thickness - -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 = (5, 5)) - - variable_name = data.name - - location = ecco2_location[variable_name] - - longitude = (0, 360) - latitude = (-90, 90) - TX, TY = (Periodic, Bounded) - - if variable_is_three_dimensional[variable_name] - z = ECCO2_z - # add vertical halo for 3D fields - halo = (horizontal_halo..., 1) - LZ = Center - TZ = Bounded - N = (ECCO2_Nx, ECCO2_Ny, ECCO2_Nz) - else - z = nothing - halo = horizontal_halo - LZ = Nothing - TZ = Flat - N = (ECCO2_Nx, ECCO2_Ny) - end - - # Flat in z if the variable is two-dimensional - grid = LatitudeLongitudeGrid(architecture; halo, size = N, topology = (TX, TY, TZ), - longitude, latitude, z) - - return Field{location...}(grid) -end - -""" - ecco2_field(variable_name; - architecture = CPU(), - horizontal_halo = (1, 1), - user_data = nothing, - url = ecco2_urls[variable_name], - filename = ecco2_file_names[variable_name], - short_name = ecco2_short_names[variable_name]) - -Retrieve the ecco2 field corresponding to `variable_name`. -The data is either: -(1) retrieved from `filename`, -(2) dowloaded from `url` if `filename` does not exists, -(3) filled from `user_data` if `user_data` is provided. -""" -function ecco2_field(variable_name; - architecture = CPU(), - horizontal_halo = (5, 5), - user_data = nothing, - year = 1992, - month = 1, - day = 2, - url = ecco2_urls[variable_name], - filename = ecco2_file_names[variable_name], - short_name = ecco2_short_names[variable_name]) - - ecco2_data = ECCO2Metadata(variable_name, year, month, day) - - isfile(filename) || download(url, filename) - - if user_data isa Nothing - ds = Dataset(filename) - if variable_is_three_dimensional[variable_name] - data = ds[short_name][:, :, :, 1] - # The surface layer in three-dimensional ECCO fields is at `k = 1` - data = reverse(data, dims = 3) - else - data = ds[short_name][:, :, 1] - end - else - data = user_data - end - - field = empty_ecco2_field(ecco2_data; architecture, horizontal_halo) - FT = eltype(field) - data = if location(field)[2] == Face - new_data = zeros(FT, size(field)) - new_data[:, 1:end-1, :] .= data - new_data - else - convert.(FT, data) - end - - set!(field, data) - fill_halo_regions!(field) - - return field -end - -@kernel function _set_ecco2_mask!(mask, Tᵢ, minimum_value) - i, j, k = @index(Global, NTuple) - @inbounds mask[i, j, k] = Tᵢ[i, j, k] < minimum_value -end - -""" - ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) - -A boolean field where `false` represents a missing value in the ECCO2 :temperature dataset. -""" -function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) - Tᵢ = ecco2_field(:temperature; architecture) - mask = CenterField(Tᵢ.grid, Bool) - - # Set the mask with ones where T is defined - launch!(architecture, Tᵢ.grid, :xyz, _set_ecco2_mask!, mask, Tᵢ, minimum_value) - - return mask -end - -""" - inpainted_ecco2_field(variable_name; - architecture = CPU(), - filename = "./inpainted_ecco2_fields.nc", - mask = ecco2_center_mask(architecture)) - -Retrieve the ECCO2 field corresponding to `variable_name` inpainted to fill all the -missing values in the original dataset. - -Arguments: -========== - -- `variable_name`: the variable name corresponding to the Dataset. - -Keyword Arguments: -================== - -- `architecture`: either `CPU()` or `GPU()`. - -- `filename`: the path where to retrieve the data from. If the file does not exist, - the data will be retrived from the ECCO2 dataset, inpainted, and - saved to `filename`. - -- `mask`: the mask used to inpaint the field (see `inpaint_mask!`). -""" -function inpainted_ecco2_field(variable_name; - architecture = CPU(), - filename = "./inpainted_ecco2_fields.nc", - mask = ecco2_center_mask(architecture), - kw...) - - if !isfile(filename) - f = ecco2_field(variable_name; architecture) - - # Make sure all values are extended properly - @info "In-painting ecco $variable_name and saving it in $filename" - inpaint_mask!(f, mask; kw...) - - fill_halo_regions!(f) - - ds = Dataset(filename, "c") - defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) - - close(ds) - else - ds = Dataset(filename, "a") - - if haskey(ds, string(variable_name)) - data = ds[variable_name][:, :, :] - f = ecco2_field(variable_name; architecture, user_data = data) - fill_halo_regions!(f) - else - f = ecco2_field(variable_name; architecture) - # Make sure all values are inpainted properly - @info "In-painting ecco $variable_name and saving it in $filename" - inpaint_mask!(f, mask; kw...) - fill_halo_regions!(f) - - defVar(ds, string(variable_name), Array(interior(f)), ("lat", "lon", "z")) - end - - close(ds) - end - - return f -end - -function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename="./inpainted_ecco2_fields.nc", kw...) - # Fields initialized from ECCO2 - grid = field.grid - arch = architecture(grid) - child_arch = child_architecture(arch) - name = ecco2_metadata.name - - f_ecco = if arch.local_rank == 0 # Make sure we read/write the file using only one core - mask = ecco2_center_mask(child_arch) - - inpainted_ecco2_field(name; filename, mask, - architecture = child_arch, - kw...) - else - empty_ecco2_field(ecco2_metadata; architecture = child_arch) - end - - barrier!(arch) - - # Distribute ecco field to all workers - parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) - - f_grid = Field(ecco2_location[name], grid) - interpolate!(f_grid, f_ecco) - set!(field, f_grid) - - return field -end - -function set!(field::Field, ecco2_metadata::ECCO2Metadata; filename="./inpainted_ecco2_fields.nc", kw...) - - # Fields initialized from ECCO2 - grid = field.grid - name = ecco2_metadata.name - - mask = ecco2_center_mask(architecture(grid)) - - f = inpainted_ecco2_field(name; filename, mask, - architecture = architecture(grid), - kw...) - - f_grid = Field(ecco2_location[name], grid) - interpolate!(f_grid, f) - set!(field, f_grid) - - return field -end - -end # module - - - diff --git a/src/DataWrangling/ECCO4.jl b/src/DataWrangling/ECCO4.jl new file mode 100644 index 00000000..1fb1f325 --- /dev/null +++ b/src/DataWrangling/ECCO4.jl @@ -0,0 +1,418 @@ +module ECCO4 + +export ECCOMetadata, ecco4_field, ecco4_center_mask, adjusted_ecco_tracers, initialize! + +using ClimaOcean.DataWrangling: inpaint_mask! +using ClimaOcean.InitialConditions: three_dimensional_regrid!, interpolate! + +using Oceananigans +using Oceananigans.Architectures: architecture, child_architecture +using Oceananigans.BoundaryConditions +using Oceananigans.DistributedComputations: DistributedField, all_reduce, barrier! +using Oceananigans.Utils +using KernelAbstractions: @kernel, @index +using NCDatasets +using Downloads: download +using Dates + +import Oceananigans.Fields: set! + +# Ecco field used to set model's initial conditions +struct ECCOMetadata + name :: Symbol + year :: Int + month :: Int + day :: Int +end + +const ECCO_Nx = 720 +const ECCO_Ny = 360 +const ECCO_Nz = 50 + +# Vertical coordinate +const ECCO_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, +] + +unprocessed_ecco4_file_prefix = Dict( + :temperature => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), + :salinity => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), +) + +# We only have 1992 at the moment +ECCOMetadata(name::Symbol) = ECCOMetadata(name, 1992, 1, 2) + +function ECCOMetadata(name::Symbol, date::DateTimeAllLeap) + year = Dates.year(date) + month = Dates.month(date) + day = Dates.day(date) + + return ECCOMetadata(name, year, month, day) +end + +date(data::ECCOMetadata) = DateTimeAllLeap(data.year, data.month, data.day) + +function ecco4_filename(metadata::ECCOMetadata) + variable_name = metadata.name + prefix, postfix = unprocessed_ecco4_file_prefix[variable_name] + + yearstr = string(year) + monthstr = string(month, pad=2) + daystr = string(day, pad=2) + datestr = "$(yearstr)-$(monthstr)-$(daystr)" + filename = prefix * datestr * postfix + + return filename +end + +filename(data::ECCOMetadata) = "ecco4_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).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, +) + +ecco4_short_names = Dict( + :temperature => "THETA", + :salinity => "SALT", + :u_velocity => "UVEL", + :v_velocity => "VVEL", + :sea_ice_thickness => "SIheff", + :sea_ice_area_fraction => "SIarea" +) + +ecco4_location = Dict( + :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), +) + +ecco4_remote_folder = Dict( + :temperature => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4" + :salinity => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4" + :sea_ice_thickness => (Center, Center, Nothing), + :sea_ice_area_fraction => (Center, Center, Nothing), + :u_velocity => (Face, Center, Center), + :v_velocity => (Center, Face, Center), +) + +surface_variable(variable_name) = variable_name == :sea_ice_thickness + +function empty_ecco4_field(metadata::ECCOMetadata; kw...) + variable_name = metadata.name + return empty_ecco4_field(variable_name; kw...) +end + +function empty_ecco4_field(variable_name::Symbol; + Nx = ECCO_Nx, + Ny = ECCO_Ny, + Nz = ECCO_Nz, + z_faces = ECCO_z, + architecture = CPU(), + horizontal_halo = (3, 3)) + + + location = ecco4_location[variable_name] + + longitude = (0, 360) + latitude = (-90, 90) + TX, TY = (Periodic, Bounded) + + if variable_is_three_dimensional[variable_name] + z = z_faces + # add vertical halo for 3D fields + halo = (horizontal_halo..., 3) + LZ = Center + TZ = Bounded + N = (Nx, Ny, Nz) + else + z = nothing + halo = horizontal_halo + LZ = Nothing + TZ = Flat + N = (Nx, Ny) + end + + # Flat in z if the variable is two-dimensional + grid = LatitudeLongitudeGrid(architecture; halo, size = N, topology = (TX, TY, TZ), + longitude, latitude, z) + + return Field{location...}(grid) +end + +""" + ecco4_field(variable_name; + architecture = CPU(), + horizontal_halo = (1, 1), + user_data = nothing, + url = ecco4_urls[variable_name], + filename = ecco4_file_names[variable_name], + short_name = ecco4_short_names[variable_name]) + +Retrieve the ecco4 field corresponding to `variable_name`. +The data is either: +(1) retrieved from `filename`, +(2) dowloaded from `url` if `filename` does not exists, +(3) filled from `user_data` if `user_data` is provided. +""" +function ecco4_field(metadata::ECCOMetadata; + architecture = CPU(), + horizontal_halo = (3, 3), + user_data = nothing, + filename = ecco4_filename(metadata), + remote_folder = ecco4_remote_folder[metadata.name]) + + variable_name = metadata.name + short_name = ecco4_short_names[variable_name] + + if !isfile(filename) + cmd = `podaac-data-downloader -c $(remote_folder) -d ./ --start-date $(datestr)T00:00:00Z --end-date $(datestr)T00:00:00Z -e .nc` + @info "downloading $(filename) from $(remote_folder)" + run(cmd) + end + + if user_data isa Nothing + ds = Dataset(filename) + if variable_is_three_dimensional[variable_name] + data = ds[short_name][:, :, :, 1] + # The surface layer in three-dimensional ECCO fields is at `k = 1` + data = reverse(data, dims = 3) + else + data = ds[short_name][:, :, 1] + end + close(ds) + else + data = user_data + end + + field = empty_ecco4_field(metadata; architecture, horizontal_halo) + FT = eltype(field) + data[ismissing.(data)] .= 1e10 # Artificially large number! + data = if location(field)[2] == Face + new_data = zeros(FT, size(field)) + new_data[:, 1:end-1, :] .= data + new_data + else + convert.(FT, data) + end + + set!(field, data) + fill_halo_regions!(field) + + return field +end + +@kernel function _set_ecco4_mask!(mask, Tᵢ, minimum_value, maximum_value) + i, j, k = @index(Global, NTuple) + @inbounds mask[i, j, k] = (Tᵢ[i, j, k] < minimum_value) | (Tᵢ[i, j, k] > maximum_value) +end + +""" + ecco4_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) + +A boolean field where `false` represents a missing value in the ECCO :temperature dataset. +""" +function ecco4_center_mask(architecture = CPU(); + minimum_value = Float32(-1e5), + maximum_value = Float32(1e5), + filename = ecco4_file_names[:temperature]) + + Tᵢ = ecco4_field(:temperature; architecture, filename) + mask = CenterField(Tᵢ.grid, Bool) + + # Set the mask with ones where T is defined + launch!(architecture, Tᵢ.grid, :xyz, _set_ecco4_mask!, mask, Tᵢ, minimum_value, maximum_value) + + return mask +end + +""" + inpainted_ecco4_field(variable_name; + architecture = CPU(), + filename = "./inpainted_ecco4_fields.nc", + mask = ecco4_center_mask(architecture)) + +Retrieve the ECCO field corresponding to `variable_name` inpainted to fill all the +missing values in the original dataset. + +Arguments: +========== + +- `variable_name`: the variable name corresponding to the Dataset. + +Keyword Arguments: +================== + +- `architecture`: either `CPU()` or `GPU()`. + +- `filename`: the path where to retrieve the data from. If the file does not exist, + the data will be retrived from the ECCO dataset, inpainted, and + saved to `filename`. + +- `mask`: the mask used to inpaint the field (see `inpaint_mask!`). +""" +function inpainted_ecco4_field(metadata::ECCOMetadata; + architecture = CPU(), + inpainted_filename = nothing, + filename = ecco4_file_names[metadata.name], + mask = ecco4_center_mask(architecture; filename), + maxiter = Inf, + kw...) + + if isnothing(inpainted_filename) + f = ecco4_field(metadata; architecture, filename, kw...) + + # Make sure all values are extended properly + @info "In-painting ecco $(metadata.name)" + inpaint_mask!(f, mask; maxiter) + + fill_halo_regions!(f) + + elseif !isfile(inpainted_filename) + f = ecco4_field(metadata; architecture, filename, kw...) + + # Make sure all values are extended properly + @info "In-painting ecco $(metadata.name) and saving it in $filename" + inpaint_mask!(f, mask; maxiter) + + fill_halo_regions!(f) + + ds = Dataset(inpainted_filename, "c") + defVar(ds, string(metadata.name), Array(interior(f)), ("lat", "lon", "z")) + + close(ds) + + else + ds = Dataset(inpainted_filename, "a") + + if haskey(ds, string(metadata.name)) + data = ds[metadata.name][:, :, :] + f = ecco4_field(metadata; architecture, filename, user_data = data, kw...) + fill_halo_regions!(f) + else + f = ecco4_field(metadata; architecture, kw...) + # Make sure all values are inpainted properly + @info "In-painting ecco $(metadata.name) and saving it in $filename" + inpaint_mask!(f, mask; maxiter) + fill_halo_regions!(f) + + defVar(ds, string(metadata.name), Array(interior(f)), ("lat", "lon", "z")) + end + + close(ds) + end + + return f +end + +function set!(field::DistributedField, ecco4_metadata::ECCOMetadata; filename="./inpainted_ecco4_fields.nc", kw...) + # Fields initialized from ECCO + grid = field.grid + arch = architecture(grid) + child_arch = child_architecture(arch) + name = ecco4_metadata.name + + f_ecco = if arch.local_rank == 0 # Make sure we read/write the file using only one core + mask = ecco4_center_mask(child_arch) + + inpainted_ecco4_field(name; filename, mask, + architecture = child_arch, + kw...) + else + empty_ecco4_field(ecco4_metadata; architecture = child_arch) + end + + barrier!(arch) + + # Distribute ecco field to all workers + parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) + + f_grid = Field(ecco4_location[name], grid) + interpolate!(f_grid, f_ecco) + set!(field, f_grid) + + return field +end + +function set!(field::Field, ecco4_metadata::ECCOMetadata; filename="./inpainted_ecco4_fields.nc", kw...) + + # Fields initialized from ECCO + grid = field.grid + name = ecco4_metadata.name + + mask = ecco4_center_mask(architecture(grid)) + + f = inpainted_ecco4_field(name; filename, mask, + architecture = architecture(grid), + kw...) + + f_grid = Field(ecco4_location[name], grid) + interpolate!(f_grid, f) + set!(field, f_grid) + + return field +end + +include("ECCO4_climatology.jl") + +end # module + + + diff --git a/src/DataWrangling/ECCO4_climatology.jl b/src/DataWrangling/ECCO4_climatology.jl new file mode 100644 index 00000000..dec47bb3 --- /dev/null +++ b/src/DataWrangling/ECCO4_climatology.jl @@ -0,0 +1,72 @@ +using CFTime +using Dates + +function generate_ECCO_restoring_dataset(variable_name; + architecture = CPU(), + dataset_filename = "ciao.nc", + start_date = DateTimeAllLeap(1992, 1, 2), + end_date = DateTimeAllLeap(2017, 12, 31)) + + Nt = 0 + date = start_date + while date <= end_date + Nt += 1 + date = date + Day(1) + end + + field = empty_ecco4_field(variable_name) + + # Open a new dataset + ds = Dataset(dataset_filename, "c") + + # Define the dimension "lon", "lat", "z" and "time", + # with the size ECCO_Nx, ECCO_Ny, ECCO_Nz, and Nt, respectively. + defDim(ds, "lon", ECCO_Nx) + defDim(ds, "lat", ECCO_Ny) + defDim(ds, "z", ECCO_Nz) + defDim(ds, "time", Nt) + + # Define the variables with the attribute units + data = defVar(ds, string(variable_name), Float32, ("lon", "lat", "z", "time")) + time = defVar(ds, "time", Float32, ("time",)) + lat = defVar(ds, "lat", Float32, ("lat",)) + lon = defVar(ds, "lon", Float32, ("lon",)) + zvar = defVar(ds, "z", Float32, ("z", )) + + # Fill in the spatial nodes + λ, φ, z = nodes(field) + lat .= λ + lon .= φ + zvar .= z + + # Start filling in time-specific data + n = 1 + date = start_date + while date <= end_date + metadata = ECCOMetadata(variable_name, date) + + @info "retrieving inpainted $(variable_name) at $(date)" + field = inpainted_ecco4_field(metadata; architecture, filename) + copyto!(data[:, :, :, n], interior(field)) + time[n] = date.instant.periods.value / 1000 # Converting milliseconds to seconds + + n += 1 + + date = date + Day(1) + end + + close(ds) + + return nothing +end + +function ECCO_forcing(variable_name; + time_indices = :, + mask = nothing, + architecture = CPU(), + backend = NetCDFBackend(4)) + + restoring_field = reanalysis_field_time_series(variable_name; time_indices, backend) + + return restoring_field +end \ No newline at end of file diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 1f545219..a813eb78 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -125,457 +125,6 @@ urls = Dict( "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", ) -compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing -compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds - -# TODO: remove the allowscalar -function compute_bounding_nodes(::Nothing, grid, LH, hnodes) - hg = hnodes(grid, LH()) - h₁ = @allowscalar minimum(hg) - h₂ = @allowscalar maximum(hg) - return h₁, h₂ -end - -function compute_bounding_indices(::Nothing, hc) - Nh = length(hc) - return 1, Nh -end - -function compute_bounding_indices(bounds, hc) - h₁, h₂ = bounds - Nh = length(hc) - - # The following should work. If ᵒ are the extrema of nodes we want to - # interpolate to, and the following is a sketch of the JRA55 native grid, - # - # 1 2 3 4 5 - # | | | | | | - # | x ᵒ | x | x | x ᵒ | x | - # | | | | | | - # 1 2 3 4 5 6 - # - # then for example, we should find that (iᵢ, i₂) = (1, 5). - # So we want to reduce the first index by one, and limit them - # both by the available data. There could be some mismatch due - # to the use of different coordinate systems (ie whether λ ∈ (0, 360) - # which we may also need to handle separately. - i₁ = searchsortedfirst(hc, h₁) - i₂ = searchsortedfirst(hc, h₂) - i₁ = max(1, i₁ - 1) - i₂ = min(Nh, i₂) - - return i₁, i₂ -end - -infer_longitudinal_topology(::Nothing) = Periodic - -function infer_longitudinal_topology(λbounds) - λ₁, λ₂ = λbounds - TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded - return TX -end - -function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) - λbounds = compute_bounding_nodes(longitude, grid, LX, λnodes) - φbounds = compute_bounding_nodes(latitude, grid, LY, φnodes) - - i₁, i₂ = compute_bounding_indices(λbounds, λc) - j₁, j₂ = compute_bounding_indices(φbounds, φc) - TX = infer_longitudinal_topology(λbounds) - - return i₁, i₂, j₁, j₂, TX -end - -# Convert dates to range until Oceananigans supports dates natively -function jra55_times(native_times, start_time=DateTimeNoLeap(1900, 01, 01)) - Nt = length(native_times) - Δt = native_times[2] - native_times[1] # assume all times are equispaced - Δt = Second(Δt).value - - start_time = native_times[1] - start_time - start_time = Second(start_time).value - - stop_time = start_time + Δt * (Nt - 1) - times = start_time:Δt:stop_time - - return times -end - -struct JRA55NetCDFBackend <: AbstractInMemoryBackend{Int} - start :: Int - length :: Int -end - -""" - JRA55NetCDFBackend(length) - -Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. -""" -JRA55NetCDFBackend(length) = JRA55NetCDFBackend(1, length) - -Base.length(backend::JRA55NetCDFBackend) = backend.length -Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") - -const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} - -function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) - - ds = Dataset(path) - - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - LX, LY, LZ = location(fts) - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) - - ti = time_indices(fts) - ti = collect(ti) - data = ds[name][i₁:i₂, j₁:j₂, ti] - close(ds) - - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) - - return nothing -end - -new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length) - -""" - JRA55_field_time_series(variable_name; - architecture = CPU(), - location = nothing, - url = nothing, - filename = nothing, - shortname = nothing, - backend = InMemory(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) - -Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, -which describes one of the variables in the "repeat year forcing" dataset derived -from the Japanese 55-year atmospheric reanalysis for driving ocean-sea-ice models (JRA55-do). -For more information about the derivation of the repeat year forcing dataset, see - -"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 `shortname`s used in NetCDF files) -available from the JRA55-do are: - - - `: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 -================= - - - `architecture`: Architecture for the `FieldTimeSeries`. - Default: CPU() - - - `time_indices`: Indices of the timeseries to extract from file. - For example, `time_indices=1:3` returns a - `FieldTimeSeries` with the first three time snapshots - of `variable_name`. - - - `url`: The url accessed to download the data for `variable_name`. - Default: `ClimaOcean.JRA55.urls[variable_name]`. - - - `filename`: The name of the downloaded file. - Default: `ClimaOcean.JRA55.filenames[variable_name]`. - - - `shortname`: The "short name" of `variable_name` inside its NetCDF file. - Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. - - - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. - If it does not exist it will be generated. - - - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is - loaded (not recommended). -""" -function JRA55_field_time_series(variable_name; - architecture = CPU(), - grid = nothing, - location = nothing, - url = nothing, - filename = nothing, - shortname = nothing, - latitude = nothing, - longitude = nothing, - backend = InMemory(), - time_indexing = Cyclical(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) - - # OnDisk backends do not support time interpolation! - # Disallow OnDisk for JRA55 dataset loading - if backend isa OnDisk - msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") - throw(ArgumentError(msg)) - end - - if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) - variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) - variables_msg = prod(variable_strs) - - msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', - "The variables provided by the JRA55-do dataset are:", '\n', - variables_msg) - - throw(ArgumentError(msg)) - end - - if !isnothing(filename) && !isfile(filename) && isnothing(url) - throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ - If intended, please provide both the filename and url that should be used \n \ - to download the new file.")) - end - - isnothing(shortname) && (shortname = jra55_short_names[variable_name]) - isnothing(filename) && (filename = filenames[variable_name]) - isnothing(url) && (url = urls[variable_name]) - - # Record some important user decisions - totally_in_memory = backend isa TotallyInMemory - on_native_grid = isnothing(grid) - !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") - - jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") - fts_name = field_time_series_short_names[variable_name] - - # Note, we don't re-use existing jld2 files. - isfile(filename) || download(url, filename) - isfile(jld2_filename) && rm(jld2_filename) - - # Determine default time indices - if totally_in_memory - # In this case, the whole time series is in memory. - # Either the time series is short, or we are doing a limited-area - # simulation, like in a single column. So, we conservatively - # set a default `time_indices = 1:2`. - isnothing(time_indices) && (time_indices = 1:2) - time_indices_in_memory = time_indices - native_fts_architecture = architecture - else - # In this case, part or all of the time series will be stored in a file. - # Note: if the user has provided a grid, we will have to preprocess the - # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers - # to the time_indices that we will preprocess; - # by default we choose all of them. The architecture is only the - # architecture used for preprocessing, which typically will be CPU() - # even if we would like the final FieldTimeSeries on the GPU. - isnothing(time_indices) && (time_indices = :) - - if backend isa JRA55NetCDFBackend - time_indices_in_memory = 1:length(backend) - native_fts_architecture = architecture - else # then `time_indices_in_memory` refers to preprocessing - maximum_index = min(preprocess_chunk_size, length(time_indices)) - time_indices_in_memory = 1:maximum_index - native_fts_architecture = preprocess_architecture - end - end - - # Set a default location. - if isnothing(location) - LX = LY = Center - else - LX, LY = location - end - - ds = Dataset(filename) - - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - - # 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!(φn, 90) - push!(λn, λn[1] + 360) - - # TODO: support loading just part of the JRA55 data. - # Probably with arguments that take latitude, longitude bounds. - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) - - native_times = ds["time"][time_indices] - data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - λr = λn[i₁:i₂+1] - φr = φn[j₁:j₂+1] - Nrx, Nry, Nt = size(data) - close(ds) - - JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; - halo = (3, 3), - size = (Nrx, Nry), - longitude = λr, - latitude = φr, - topology = (TX, Bounded, Flat)) - - boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) - times = jra55_times(native_times) - - if backend isa JRA55NetCDFBackend - fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - backend, - time_indexing, - boundary_conditions, - path = filename, - name = shortname) - - # Fill the data in a GPU-friendly manner - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) - - 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) - - if on_native_grid && totally_in_memory - return native_fts - - elseif totally_in_memory # but not on the native grid! - boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) - fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) - interpolate!(fts, native_fts) - return fts - end - end - - @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - - preprocessing_grid = on_native_grid ? JRA55_native_grid : grid - - # Re-open the dataset! - ds = Dataset(filename) - all_datetimes = ds["time"][time_indices] - all_Nt = length(all_datetimes) - - all_times = jra55_times(all_datetimes) - - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; - boundary_conditions, - backend = OnDisk(), - path = jld2_filename, - name = fts_name) - - # Save data to disk, one field at a time - start_clock = time_ns() - n = 1 # on disk - m = 0 # in memory - - times_in_memory = all_times[time_indices_in_memory] - - fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; - boundary_conditions, - backend = InMemory(), - path = jld2_filename, - name = fts_name) - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) - end - - while n <= all_Nt - print(" ... processing time index $n of $all_Nt \r") - - if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory - m += 1 - else # load new data - # Update time_indices - time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size - n₁ = first(time_indices_in_memory) - - # Clip time_indices if they extend past the end of the dataset - if last(time_indices_in_memory) > all_Nt - time_indices_in_memory = UnitRange(n₁, all_Nt) - end - - # Re-compute times - new_times = jra55_times(all_times[time_indices_in_memory], all_times[n₁]) - native_fts.times = new_times - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - fts.times = new_times - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) - end - - m = 1 # reset - end - - set!(on_disk_fts, fts[m], n, fts.times[m]) - - n += 1 - end - - elapsed = 1e-9 * (time_ns() - start_clock) - elapsed_str = prettytime(elapsed) - @info " ... done ($elapsed_str)" * repeat(" ", 20) - - close(ds) - - user_fts = FieldTimeSeries(jld2_filename, fts_name; architecture, backend, time_indexing) - fill_halo_regions!(user_fts) - - return user_fts -end - const AA = Oceananigans.Architectures.AbstractArchitecture JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = @@ -600,24 +149,24 @@ 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 = JRA55NetCDFBackend(Nf) + backend = NetCDFBackend(Nf) end kw = (; time_indices, time_indexing, backend, architecture) kw = merge(kw, other_kw) - ua = JRA55_field_time_series(:eastward_velocity; kw...) - va = JRA55_field_time_series(:northward_velocity; kw...) - Ta = JRA55_field_time_series(:temperature; kw...) - qa = JRA55_field_time_series(:specific_humidity; kw...) - ra = JRA55_field_time_series(:relative_humidity; kw...) - pa = JRA55_field_time_series(:sea_level_pressure; kw...) - Fra = JRA55_field_time_series(:rain_freshwater_flux; kw...) - Fsn = JRA55_field_time_series(:snow_freshwater_flux; kw...) - Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) - Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) - Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) - Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) + ua = reanalysis_field_time_series(:eastward_velocity; kw...) + va = reanalysis_field_time_series(:northward_velocity; kw...) + Ta = reanalysis_field_time_series(:temperature; kw...) + qa = reanalysis_field_time_series(:specific_humidity; kw...) + ra = reanalysis_field_time_series(:relative_humidity; kw...) + pa = reanalysis_field_time_series(:sea_level_pressure; kw...) + Fra = reanalysis_field_time_series(:rain_freshwater_flux; kw...) + Fsn = reanalysis_field_time_series(:snow_freshwater_flux; kw...) + Fri = reanalysis_field_time_series(:river_freshwater_flux; kw...) + Fic = reanalysis_field_time_series(:iceberg_freshwater_flux; kw...) + Ql = reanalysis_field_time_series(:downwelling_longwave_radiation; kw...) + Qs = reanalysis_field_time_series(:downwelling_shortwave_radiation; kw...) times = ua.times diff --git a/src/DataWrangling/inpaint_mask.jl b/src/DataWrangling/inpaint_mask.jl index f5a3df19..3a515994 100644 --- a/src/DataWrangling/inpaint_mask.jl +++ b/src/DataWrangling/inpaint_mask.jl @@ -46,9 +46,9 @@ end propagate_horizontally!(field, ::Nothing, tmp_field=deepcopy(field); kw...) = field -function propagating(field, mask, iter, max_iter) +function propagating(field, mask, iter, maxiter) mask_sum = sum(field; condition=interior(mask)) - return isnan(mask_sum) && iter < max_iter + return isnan(mask_sum) && iter < maxiter end """ @@ -58,7 +58,7 @@ Horizontally propagate the values of `field` into the `mask`. In other words, cells where `mask[i, j, k] == false` are preserved, and cells where `mask[i, j, k] == true` are painted over. """ -function propagate_horizontally!(field, mask, tmp_field=deepcopy(field); max_iter = Inf) +function propagate_horizontally!(field, mask, tmp_field=deepcopy(field); maxiter = Inf) iter = 0 grid = field.grid arch = architecture(grid) @@ -69,7 +69,7 @@ function propagate_horizontally!(field, mask, tmp_field=deepcopy(field); max_ite # Need temporary field to avoid a race condition parent(tmp_field) .= parent(field) - while propagating(field, mask, iter, max_iter) + while propagating(field, mask, iter, maxiter) launch!(arch, grid, :xyz, _propagate_field!, field, tmp_field) launch!(arch, grid, :xyz, _substitute_values!, field, tmp_field) iter += 1 @@ -120,9 +120,9 @@ Arguments - `max_iter`: Maximum iterations for inpainting. Non-Inf values mean that NaN's can occur within the mask. """ -function inpaint_mask!(field, mask; max_iter = Inf) +function inpaint_mask!(field, mask; maxiter = Inf) continue_downwards!(field, mask) - propagate_horizontally!(field, mask; max_iter) + propagate_horizontally!(field, mask; maxiter) return field end diff --git a/src/DataWrangling/reanalysis_field_time_series.jl b/src/DataWrangling/reanalysis_field_time_series.jl new file mode 100644 index 00000000..4d439b40 --- /dev/null +++ b/src/DataWrangling/reanalysis_field_time_series.jl @@ -0,0 +1,488 @@ +using Oceananigans +using Oceananigans.Units + +using Oceananigans.Architectures: arch_array +using Oceananigans.DistributedComputations +using Oceananigans.DistributedComputations: child_architecture +using Oceananigans.BoundaryConditions: fill_halo_regions! +using Oceananigans.Grids: λnodes, φnodes, on_architecture +using Oceananigans.Fields: interpolate! +using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices + +using CUDA: @allowscalar + +using NCDatasets +using JLD2 +using Dates + +import Oceananigans.Fields: set! +import Oceananigans.OutputReaders: new_backend, update_field_time_series! +using Downloads: download + +compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing +compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds + +# TODO: remove the allowscalar +function compute_bounding_nodes(::Nothing, grid, LH, hnodes) + hg = hnodes(grid, LH()) + h₁ = @allowscalar minimum(hg) + h₂ = @allowscalar maximum(hg) + return h₁, h₂ +end + +function compute_bounding_indices(::Nothing, hc) + Nh = length(hc) + return 1, Nh +end + +function compute_bounding_indices(bounds, hc) + h₁, h₂ = bounds + Nh = length(hc) + + # The following should work. If ᵒ are the extrema of nodes we want to + # interpolate to, and the following is a sketch of the JRA55 native grid, + # + # 1 2 3 4 5 + # | | | | | | + # | x ᵒ | x | x | x ᵒ | x | + # | | | | | | + # 1 2 3 4 5 6 + # + # then for example, we should find that (iᵢ, i₂) = (1, 5). + # So we want to reduce the first index by one, and limit them + # both by the available data. There could be some mismatch due + # to the use of different coordinate systems (ie whether λ ∈ (0, 360) + # which we may also need to handle separately. + i₁ = searchsortedfirst(hc, h₁) + i₂ = searchsortedfirst(hc, h₂) + i₁ = max(1, i₁ - 1) + i₂ = min(Nh, i₂) + + return i₁, i₂ +end + +infer_longitudinal_topology(::Nothing) = Periodic + +function infer_longitudinal_topology(λbounds) + λ₁, λ₂ = λbounds + TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded + return TX +end + +function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + λbounds = compute_bounding_nodes(longitude, grid, LX, λnodes) + φbounds = compute_bounding_nodes(latitude, grid, LY, φnodes) + + i₁, i₂ = compute_bounding_indices(λbounds, λc) + j₁, j₂ = compute_bounding_indices(φbounds, φc) + TX = infer_longitudinal_topology(λbounds) + + return i₁, i₂, j₁, j₂, TX +end + +# Convert dates to range until Oceananigans supports dates natively +function fts_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 NetCDFBackend <: AbstractInMemoryBackend{Int} + start :: Int + length :: Int +end + +""" + NetCDFBackend(length) + +Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. +""" +NetCDFBackend(length) = NetCDFBackend(1, length) + +Base.length(backend::NetCDFBackend) = backend.length +Base.summary(backend::NetCDFBackend) = string("NetCDFBackend(", backend.start, ", ", backend.length, ")") + +const NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:NetCDFBackend} + +function set!(fts::NetCDFFTS, path::String=fts.path, name::String=fts.name) + + ds = Dataset(path) + + # Note that each file should have the variables + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data + + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + LX, LY, LZ = location(fts) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) + + Nz = size(fts, 3) + + ti = time_indices(fts) + ti = collect(ti) + data = Nz == 1 ? ds[name][i₁:i₂, j₁:j₂, ti] : ds[name][i₁:i₂, j₁:j₂, :, ti] + close(ds) + + copyto!(interior(fts), reshape(data, size(fts)...)) + fill_halo_regions!(fts) + + return nothing +end + +new_backend(::NetCDFBackend, start, length) = NetCDFBackend(start, length) + +""" + reanalysis_field_time_series(variable_name; + architecture = CPU(), + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + backend = InMemory(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + +Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, +which describes one of the variables in the "repeat year forcing" dataset derived +from the Japanese 55-year atmospheric reanalysis for driving ocean-sea-ice models (JRA55-do). +For more information about the derivation of the repeat year forcing dataset, see + +"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 `shortname`s used in NetCDF files) +available from the JRA55-do are: + + - `: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 +================= + + - `architecture`: Architecture for the `FieldTimeSeries`. + Default: CPU() + + - `time_indices`: Indices of the timeseries to extract from file. + For example, `time_indices=1:3` returns a + `FieldTimeSeries` with the first three time snapshots + of `variable_name`. + + - `url`: The url accessed to download the data for `variable_name`. + Default: `ClimaOcean.JRA55.urls[variable_name]`. + + - `filename`: The name of the downloaded file. + Default: `ClimaOcean.JRA55.filenames[variable_name]`. + + - `shortname`: The "short name" of `variable_name` inside its NetCDF file. + Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. + + - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. + If it does not exist it will be generated. + + - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is + loaded (not recommended). +""" +function reanalysis_field_time_series(variable_name; + architecture = CPU(), + grid = nothing, + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + latitude = nothing, + longitude = nothing, + tridimensional_data = false, + backend = InMemory(), + time_indexing = Cyclical(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + + # OnDisk backends do not support time interpolation! + # Disallow OnDisk for JRA55 dataset loading + if backend isa OnDisk + msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") + throw(ArgumentError(msg)) + end + + if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) + variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) + variables_msg = prod(variable_strs) + + msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', + "The variables provided by the JRA55-do dataset are:", '\n', + variables_msg) + + throw(ArgumentError(msg)) + end + + if !isnothing(filename) && !isfile(filename) && isnothing(url) + throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ + If intended, please provide both the filename and url that should be used \n \ + to download the new file.")) + end + + isnothing(shortname) && (shortname = jra55_short_names[variable_name]) + isnothing(filename) && (filename = filenames[variable_name]) + isnothing(url) && (url = urls[variable_name]) + + # Record some important user decisions + totally_in_memory = backend isa TotallyInMemory + on_native_grid = isnothing(grid) + !on_native_grid && backend isa NetCDFBackend && error("Can't use custom grid with NetCDFBackend.") + + jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") + fts_name = field_time_series_short_names[variable_name] + + # Note, we don't re-use existing jld2 files. + isfile(filename) || download(url, filename) + isfile(jld2_filename) && rm(jld2_filename) + + # Determine default time indices + if totally_in_memory + # In this case, the whole time series is in memory. + # Either the time series is short, or we are doing a limited-area + # simulation, like in a single column. So, we conservatively + # set a default `time_indices = 1:2`. + isnothing(time_indices) && (time_indices = 1:2) + time_indices_in_memory = time_indices + native_fts_architecture = architecture + else + # In this case, part or all of the time series will be stored in a file. + # Note: if the user has provided a grid, we will have to preprocess the + # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers + # to the time_indices that we will preprocess; + # by default we choose all of them. The architecture is only the + # architecture used for preprocessing, which typically will be CPU() + # even if we would like the final FieldTimeSeries on the GPU. + isnothing(time_indices) && (time_indices = :) + + if backend isa NetCDFBackend + time_indices_in_memory = 1:length(backend) + native_fts_architecture = architecture + else # then `time_indices_in_memory` refers to preprocessing + maximum_index = min(preprocess_chunk_size, length(time_indices)) + time_indices_in_memory = 1:maximum_index + native_fts_architecture = preprocess_architecture + end + end + + # Set a default location. + if isnothing(location) + LX = LY = Center + location = tridimensional_data ? (LX, LY, Center) : (LX, LY, Nothing) + end + + ds = Dataset(filename) + + # Note that each file should have the variables + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data + + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + zc = tridimensional_data ? ds["z"][:] : nothing + + # 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!(φn, 90) + push!(λn, λn[1] + 360) + + # TODO: support loading just part of the JRA55 data. + # Probably with arguments that take latitude, longitude bounds. + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, location[1], location[2], λc, φc) + + native_times = ds["time"][time_indices] + data = tridimensional_data ? ds[shortname][i₁:i₂, j₁:j₂, :, time_indices_in_memory] : ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + λr = λn[i₁:i₂+1] + φr = φn[j₁:j₂+1] + + Nrx, Nry, Nz = size(data) # Nz is the time index if the variable is twodimensional + close(ds) + + native_grid = if tridimensional_data + LatitudeLongitudeGrid(native_fts_architecture, Float32; + halo = (3, 3, 3), + size = (Nrx, Nry, Nz), + longitude = λr, + latitude = φr, + z = zc, + topology = (TX, Bounded, Flat)) + else + LatitudeLongitudeGrid(native_fts_architecture, Float32; + halo = (3, 3), + size = (Nrx, Nry), + longitude = λr, + latitude = φr, + topology = (TX, Bounded, Flat)) + end + + boundary_conditions = FieldBoundaryConditions(native_grid, location) + times = fts_times(native_times) + + if backend isa NetCDFBackend + fts = FieldTimeSeries{location...}(native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = filename, + name = shortname) + + # Fill the data in a GPU-friendly manner + copyto!(interior(fts), reshape(data, size(fts)...)) + 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{location...}(native_grid, times; + time_indexing, + boundary_conditions) + + # Fill the data in a GPU-friendly manner + copyto!(interior(native_fts), reshape(data, size(native_fts)...)) + fill_halo_regions!(native_fts) + + if on_native_grid && totally_in_memory + return native_fts + + elseif totally_in_memory # but not on the native grid! + boundary_conditions = FieldBoundaryConditions(grid, location) + fts = FieldTimeSeries{location...}(grid, times; time_indexing, boundary_conditions) + interpolate!(fts, native_fts) + return fts + end + end + + @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." + + preprocessing_grid = on_native_grid ? native_grid : grid + + # Re-open the dataset! + ds = Dataset(filename) + all_datetimes = ds["time"][time_indices] + all_Nt = length(all_datetimes) + + all_times = fts_times(all_datetimes) + + on_disk_fts = FieldTimeSeries{location...}(preprocessing_grid, all_times; + boundary_conditions, + backend = OnDisk(), + path = jld2_filename, + name = fts_name) + + # Save data to disk, one field at a time + start_clock = time_ns() + n = 1 # on disk + m = 0 # in memory + + times_in_memory = all_times[time_indices_in_memory] + + fts = FieldTimeSeries{location...}(preprocessing_grid, times_in_memory; + boundary_conditions, + backend = InMemory(), + path = jld2_filename, + name = fts_name) + + # Re-compute data + new_data = tridimensional_data ? ds[shortname][i₁:i₂, j₁:j₂, :, time_indices_in_memory] : + ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + + if !on_native_grid + copyto!(interior(native_fts), reshape(new_data, size(native_fts)...)) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts), reshape(new_data, size(fts)...)) + end + + while n <= all_Nt + print(" ... processing time index $n of $all_Nt \r") + + if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory + m += 1 + else # load new data + # Update time_indices + time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size + n₁ = first(time_indices_in_memory) + + # Clip time_indices if they extend past the end of the dataset + if last(time_indices_in_memory) > all_Nt + time_indices_in_memory = UnitRange(n₁, all_Nt) + end + + # Re-compute times + new_times = fts_times(all_times[time_indices_in_memory], all_times[n₁]) + native_fts.times = new_times + + # Re-compute data + new_data = tridimensional_data ? ds[shortname][i₁:i₂, j₁:j₂, :, time_indices_in_memory] : + ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + + fts.times = new_times + + if !on_native_grid + copyto!(interior(native_fts), reshape(new_data, size(native_fts)...)) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts), reshape(new_data, size(fts)...)) + end + + m = 1 # reset + end + + set!(on_disk_fts, fts[m], n, fts.times[m]) + + n += 1 + end + + elapsed = 1e-9 * (time_ns() - start_clock) + elapsed_str = prettytime(elapsed) + @info " ... done ($elapsed_str)" * repeat(" ", 20) + + close(ds) + + user_fts = FieldTimeSeries(jld2_filename, fts_name; architecture, backend, time_indexing) + fill_halo_regions!(user_fts) + + return user_fts +end diff --git a/test/runtests.jl b/test/runtests.jl index 36879aab..3a88eed0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -9,8 +9,8 @@ if test_group == :jra55 || test_group == :all include("test_jra55.jl") end -if test_group == :ecco2 || test_group == :all - include("test_ecco2.jl") +if test_group == :ecco4 || test_group == :all + include("test_ecco4.jl") end # Tests that we can download JRA55 utilities diff --git a/test/test_downloading.jl b/test/test_downloading.jl index 7bc53331..388feb1c 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=2:3) + fts = ClimaOcean.JRA55.reanalysis_field_time_series(name; time_indices=2:3) end end diff --git a/test/test_ecco2.jl b/test/test_ecco2.jl deleted file mode 100644 index abbebec2..00000000 --- a/test/test_ecco2.jl +++ /dev/null @@ -1,51 +0,0 @@ -include("runtests_setup.jl") - -using ClimaOcean -using ClimaOcean.ECCO2 -using Oceananigans.Grids: topology - -@testset "ECCO2 fields utilities" begin - for arch in test_architectures - A = typeof(arch) - @info "Testing ecco2_field on $A..." - - temperature_filename = ECCO2.ecco2_file_names[:temperature] - ecco2_temperature = ECCO2.ecco2_field(:temperature; architecture=arch) - - @test isfile(temperature_filename) - rm(temperature_filename) - - @test ecco2_temperature isa Field - @test ecco2_temperature.grid isa LatitudeLongitudeGrid - @test topology(ecco2_temperature.grid) == (Periodic, Bounded, Bounded) - - Nx, Ny, Nz = size(ecco2_temperature) - @test Nx == 1440 - @test Ny == 720 - @test Nz == 50 - - 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) - - @test ecco2_ice_thickness isa Field - @test ecco2_ice_thickness.grid isa LatitudeLongitudeGrid - @test topology(ecco2_ice_thickness.grid) == (Periodic, Bounded, Flat) - - Nx, Ny, Nz = size(ecco2_ice_thickness) - @test Nx == 1440 - @test Ny == 720 - @test Nz == 1 - end -end - -@testset "setting a field with ECCO2" begin - for arch in test_architectures - grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (-5, 5), z = (-200, 0)) - field = CenterField(grid) - set!(field, ECCO2Metadata(:temperature)) - set!(field, ECCO2Metadata(:salinity)) - end -end diff --git a/test/test_ecco4.jl b/test/test_ecco4.jl new file mode 100644 index 00000000..54bcd1f9 --- /dev/null +++ b/test/test_ecco4.jl @@ -0,0 +1,51 @@ +include("runtests_setup.jl") + +using ClimaOcean +using ClimaOcean.ECCO4 +using Oceananigans.Grids: topology + +@testset "ECCO4 fields utilities" begin + for arch in test_architectures + A = typeof(arch) + @info "Testing ecco4_field on $A..." + + temperature_filename = ECCO4.ecco4_file_names[:temperature] + ecco4_temperature = ECCO4.ecco4_field(:temperature; architecture=arch) + + @test isfile(temperature_filename) + rm(temperature_filename) + + @test ecco4_temperature isa Field + @test ecco4_temperature.grid isa LatitudeLongitudeGrid + @test topology(ecco4_temperature.grid) == (Periodic, Bounded, Bounded) + + Nx, Ny, Nz = size(ecco4_temperature) + @test Nx == 1440 + @test Ny == 720 + @test Nz == 50 + + ice_thickness_filename = ECCO4.ecco4_file_names[:sea_ice_thickness] + ecco4_ice_thickness = ECCO4.ecco4_field(:sea_ice_thickness; architecture=arch) + + @test isfile(ice_thickness_filename) + rm(ice_thickness_filename) + + @test ecco4_ice_thickness isa Field + @test ecco4_ice_thickness.grid isa LatitudeLongitudeGrid + @test topology(ecco4_ice_thickness.grid) == (Periodic, Bounded, Flat) + + Nx, Ny, Nz = size(ecco4_ice_thickness) + @test Nx == 1440 + @test Ny == 720 + @test Nz == 1 + end +end + +@testset "setting a field with ECCO4" begin + for arch in test_architectures + grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (-5, 5), z = (-200, 0)) + field = CenterField(grid) + set!(field, ECCOMetadata(:temperature)) + set!(field, ECCOMetadata(:salinity)) + end +end diff --git a/test/test_jra55.jl b/test/test_jra55.jl index d13b3d4f..01848b12 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -3,7 +3,7 @@ include("runtests_setup.jl") @testset "JRA55 and data wrangling utilities" begin for arch in test_architectures A = typeof(arch) - @info "Testing JRA55_field_time_series on $A..." + @info "Testing reanalysis_field_time_series on $A..." test_name = :downwelling_shortwave_radiation test_filename = "RYF.rsds.1990_1991.nc" @@ -11,7 +11,7 @@ include("runtests_setup.jl") 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.DataWrangling.reanalysis_field_time_series(test_name; architecture=arch, time_indices) @test isfile(test_filename) @test jra55_fts isa FieldTimeSeries @@ -37,10 +37,10 @@ include("runtests_setup.jl") rm(test_jld2_filename, force=true) @info "Testing loading preprocessed JRA55 data on $A..." - in_memory_jra55_fts = ClimaOcean.JRA55.JRA55_field_time_series(test_name; - time_indices, - architecture = arch, - backend = InMemory(2)) + in_memory_jra55_fts = ClimaOcean.DataWrangling.reanalysis_field_time_series(test_name; + time_indices, + architecture = arch, + backend = InMemory(2)) @test in_memory_jra55_fts isa FieldTimeSeries From c9d01658792f581860db4ec47a428302a60add17 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 5 May 2024 14:37:20 -0400 Subject: [PATCH 409/716] some fixes --- src/DataWrangling/ECCO4_climatology.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/ECCO4_climatology.jl b/src/DataWrangling/ECCO4_climatology.jl index dec47bb3..b26df04e 100644 --- a/src/DataWrangling/ECCO4_climatology.jl +++ b/src/DataWrangling/ECCO4_climatology.jl @@ -3,9 +3,9 @@ using Dates function generate_ECCO_restoring_dataset(variable_name; architecture = CPU(), - dataset_filename = "ciao.nc", start_date = DateTimeAllLeap(1992, 1, 2), - end_date = DateTimeAllLeap(2017, 12, 31)) + end_date = DateTimeAllLeap(2017, 12, 31), + dataset_filename = "ciao.nc") Nt = 0 date = start_date @@ -44,7 +44,8 @@ function generate_ECCO_restoring_dataset(variable_name; date = start_date while date <= end_date metadata = ECCOMetadata(variable_name, date) - + filename = ecco4_filename(metadata) + @info "retrieving inpainted $(variable_name) at $(date)" field = inpainted_ecco4_field(metadata; architecture, filename) copyto!(data[:, :, :, n], interior(field)) From 6c5957c9503d4e5dcae071f7e4fdf0cbc39faa5e Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 5 May 2024 14:44:53 -0400 Subject: [PATCH 410/716] check what happens with atmospheric velocity instead of du, dv --- .../similarity_theory_turbulent_fluxes.jl | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 10abc3c5..33aed9e6 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -29,7 +29,7 @@ import SurfaceFluxes.Parameters: ##### Bulk turbulent fluxes based on similarity theory ##### -struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, F} <: AbstractSurfaceFluxesParameters +struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, F} <: AbstractSurfaceFluxesParameters gravitational_acceleration :: FT von_karman_constant :: FT turbulent_prandtl_number :: FT @@ -40,6 +40,7 @@ struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, F} <: AbstractSur water_mole_fraction :: W roughness_lengths :: R bulk_coefficients :: B + bulk_velocity :: V tolerance :: FT maxiter :: Int iteration :: Int @@ -65,6 +66,7 @@ Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt( adapt(to, fluxes.water_mole_fraction), adapt(to, fluxes.roughness_lengths), adapt(to, fluxes.bulk_coefficients), + adapt(to, fluxes.bulk_velocity), fluxes.iteration, fluxes.tolerance, fluxes.maxiter, @@ -96,6 +98,12 @@ end const PATP = PrescribedAtmosphereThermodynamicsParameters +""" only the atmosphere velocity is used in flux calculations """ +struct WindVelocity end + +""" the atmosphere - ocean velocity difference is used in flux calculations """ +struct RelativeVelocity end + function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; gravitational_acceleration = default_gravitational_acceleration, von_karman_constant = convert(FT, 0.4), @@ -107,6 +115,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; water_mole_fraction = convert(FT, 0.98), roughness_lengths = default_roughness_lengths(FT), bulk_coefficients = simplified_bulk_coefficients, + bulk_velocity = RelativeVelocity(), tolerance = 1e-8, maxiter = Inf, fields = nothing) @@ -121,6 +130,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; water_mole_fraction, roughness_lengths, bulk_coefficients, + bulk_velocity, tolerance, maxiter, 0, @@ -157,7 +167,12 @@ end # Prescribed difference between two states ℂₐ = thermodynamics_parameters - Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, atmos_state, surface_state, gravitational_acceleration) + Δh, Δu, Δv, Δθ, Δq = state_differences(ℂₐ, + atmos_state, + surface_state, + gravitational_acceleration, + similarity_theory.bulk_velocity) + differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) Σ₀ = SimilarityScales(0, 0, 0) @@ -305,18 +320,14 @@ end return b★ end -@inline function state_differences(ℂ, 𝒰₁, 𝒰₀, g) +@inline characteristic_velocities(𝒰₁, 𝒰₀, ::WindVelocity) = @inbounds 𝒰₁.u[1] - 𝒰₀.u[1], 𝒰₁.u[2] - 𝒰₀.u[2] +@inline characteristic_velocities(𝒰₁, 𝒰₀, ::RelativeVelocity) = @inbounds 𝒰₁.u[1], 𝒰₁.u[2] + +@inline function state_differences(ℂ, 𝒰₁, 𝒰₀, g, bulk_velocity) z₁ = 𝒰₁.z z₀ = 𝒰₀.z Δh = z₁ - z₀ - - U₁ = 𝒰₁.u - U₀ = 𝒰₀.u - - @inbounds begin - Δu = U₁[1] - U₀[1] - Δv = U₁[2] - U₀[2] - end + Δu, Δv = characteristic_velocities(𝒰₁, 𝒰₀, bulk_velocity) # Thermodynamic state 𝒬₁ = 𝒰₁.ts From 343b1cd1e91b8a4707a4c740e70916c9bfee0ffb Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 5 May 2024 14:47:50 -0400 Subject: [PATCH 411/716] add similarity theory to the model --- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index af775fac..0790511f 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -59,6 +59,7 @@ end function OceanSeaIceModel(ocean, sea_ice=nothing; atmosphere = nothing, radiation = nothing, + similarity_theory = nothing, ocean_reference_density = reference_density(ocean), ocean_heat_capacity = heat_capacity(ocean), clock = deepcopy(ocean.model.clock)) @@ -67,6 +68,7 @@ function OceanSeaIceModel(ocean, sea_ice=nothing; fluxes = OceanSeaIceSurfaceFluxes(ocean, sea_ice; atmosphere, ocean_reference_density, + similarity_theory, ocean_heat_capacity, radiation) From 3a6dc87c3a75db72739a3f4c3be9c0edc174f9d8 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 5 May 2024 15:46:28 -0400 Subject: [PATCH 412/716] more changes --- src/DataWrangling/ECCO4.jl | 37 +++++++++---------- src/DataWrangling/ECCO4_climatology.jl | 37 ++++++++++++++----- .../reanalysis_field_time_series.jl | 7 ++-- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/DataWrangling/ECCO4.jl b/src/DataWrangling/ECCO4.jl index 1fb1f325..b05d2888 100644 --- a/src/DataWrangling/ECCO4.jl +++ b/src/DataWrangling/ECCO4.jl @@ -102,17 +102,18 @@ end date(data::ECCOMetadata) = DateTimeAllLeap(data.year, data.month, data.day) +function date_string(metadata::ECCOMetadata) + yearstr = string(metadata.year) + monthstr = string(metadata.month, pad=2) + daystr = string(metadata.day, pad=2) + return "$(yearstr)-$(monthstr)-$(daystr)" +end + function ecco4_filename(metadata::ECCOMetadata) variable_name = metadata.name prefix, postfix = unprocessed_ecco4_file_prefix[variable_name] - - yearstr = string(year) - monthstr = string(month, pad=2) - daystr = string(day, pad=2) - datestr = "$(yearstr)-$(monthstr)-$(daystr)" - filename = prefix * datestr * postfix - - return filename + datestr = date_string(metadata) + return prefix * datestr * postfix end filename(data::ECCOMetadata) = "ecco4_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).nc" @@ -145,12 +146,8 @@ ecco4_location = Dict( ) ecco4_remote_folder = Dict( - :temperature => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4" - :salinity => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4" - :sea_ice_thickness => (Center, Center, Nothing), - :sea_ice_area_fraction => (Center, Center, Nothing), - :u_velocity => (Face, Center, Center), - :v_velocity => (Center, Face, Center), + :temperature => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", + :salinity => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", ) surface_variable(variable_name) = variable_name == :sea_ice_thickness @@ -221,6 +218,7 @@ function ecco4_field(metadata::ECCOMetadata; variable_name = metadata.name short_name = ecco4_short_names[variable_name] + datestr = date_string(metadata) if !isfile(filename) cmd = `podaac-data-downloader -c $(remote_folder) -d ./ --start-date $(datestr)T00:00:00Z --end-date $(datestr)T00:00:00Z -e .nc` @@ -272,13 +270,14 @@ A boolean field where `false` represents a missing value in the ECCO :temperatur function ecco4_center_mask(architecture = CPU(); minimum_value = Float32(-1e5), maximum_value = Float32(1e5), - filename = ecco4_file_names[:temperature]) + metadata = ECCOMetadata(:temperature, 1992, 1, 1), + filename = ecco4_filename(metadata)) - Tᵢ = ecco4_field(:temperature; architecture, filename) - mask = CenterField(Tᵢ.grid, Bool) + field = ecco4_field(metadata; architecture, filename) + mask = CenterField(field.grid, Bool) # Set the mask with ones where T is defined - launch!(architecture, Tᵢ.grid, :xyz, _set_ecco4_mask!, mask, Tᵢ, minimum_value, maximum_value) + launch!(architecture, field.grid, :xyz, _set_ecco4_mask!, mask, field, minimum_value, maximum_value) return mask end @@ -311,7 +310,7 @@ Keyword Arguments: function inpainted_ecco4_field(metadata::ECCOMetadata; architecture = CPU(), inpainted_filename = nothing, - filename = ecco4_file_names[metadata.name], + filename = ecco4_filename(metadata), mask = ecco4_center_mask(architecture; filename), maxiter = Inf, kw...) diff --git a/src/DataWrangling/ECCO4_climatology.jl b/src/DataWrangling/ECCO4_climatology.jl index b26df04e..4b75fbd9 100644 --- a/src/DataWrangling/ECCO4_climatology.jl +++ b/src/DataWrangling/ECCO4_climatology.jl @@ -1,6 +1,14 @@ using CFTime using Dates +import Base: reverse + +@inline reverse(::Face) = Center() +@inline reverse(::Center) = Face() + +@inline instantiate(T::DataType) = T() +@inline instantiate(T) = T + function generate_ECCO_restoring_dataset(variable_name; architecture = CPU(), start_date = DateTimeAllLeap(1992, 1, 2), @@ -23,31 +31,42 @@ function generate_ECCO_restoring_dataset(variable_name; # with the size ECCO_Nx, ECCO_Ny, ECCO_Nz, and Nt, respectively. defDim(ds, "lon", ECCO_Nx) defDim(ds, "lat", ECCO_Ny) - defDim(ds, "z", ECCO_Nz) + defDim(ds, "z", ECCO_Nz) + defDim(ds, "lon_bounds", ECCO_Nx) + defDim(ds, "lat_bounds", ECCO_Ny + 1) + defDim(ds, "z_bounds", ECCO_Nz + 1) defDim(ds, "time", Nt) # Define the variables with the attribute units data = defVar(ds, string(variable_name), Float32, ("lon", "lat", "z", "time")) time = defVar(ds, "time", Float32, ("time",)) - lat = defVar(ds, "lat", Float32, ("lat",)) lon = defVar(ds, "lon", Float32, ("lon",)) - zvar = defVar(ds, "z", Float32, ("z", )) + lat = defVar(ds, "lat", Float32, ("lat",)) + zn = defVar(ds, "z", Float32, ("z", )) + + lon_bounds = defVar(ds, "lon_bounds", Float32, ("lon_bounds",)) + lat_bounds = defVar(ds, "lat_bounds", Float32, ("lat_bounds",)) + z_bounds = defVar(ds, "z_bounds", Float32, ("z_bounds", )) # Fill in the spatial nodes - λ, φ, z = nodes(field) - lat .= λ - lon .= φ - zvar .= z + loc = instantiate.(location(field)) + λ, φ, z = nodes(field) + λr, φr, zr = nodes(field.grid, reverse.(loc)...) + lon .= λ + lat .= φ + zn .= z + lon_bounds .= λr + lat_bounds .= φr + z_bounds .= zr # Start filling in time-specific data n = 1 date = start_date while date <= end_date metadata = ECCOMetadata(variable_name, date) - filename = ecco4_filename(metadata) @info "retrieving inpainted $(variable_name) at $(date)" - field = inpainted_ecco4_field(metadata; architecture, filename) + field = inpainted_ecco4_field(metadata; architecture) copyto!(data[:, :, :, n], interior(field)) time[n] = date.instant.periods.value / 1000 # Converting milliseconds to seconds diff --git a/src/DataWrangling/reanalysis_field_time_series.jl b/src/DataWrangling/reanalysis_field_time_series.jl index 4d439b40..df45142f 100644 --- a/src/DataWrangling/reanalysis_field_time_series.jl +++ b/src/DataWrangling/reanalysis_field_time_series.jl @@ -316,6 +316,7 @@ function reanalysis_field_time_series(variable_name; # Interfaces for the "native" JRA55 grid λn = ds["lon_bnds"][1, :] φn = ds["lat_bnds"][1, :] + zr = tridimensional_data ? ds["z_bnds"][:] : nothing # The .nc coordinates lon_bnds and lat_bnds do not include # the last interface, so we push them here. @@ -330,7 +331,7 @@ function reanalysis_field_time_series(variable_name; data = tridimensional_data ? ds[shortname][i₁:i₂, j₁:j₂, :, time_indices_in_memory] : ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] φr = φn[j₁:j₂+1] - + Nrx, Nry, Nz = size(data) # Nz is the time index if the variable is twodimensional close(ds) @@ -340,8 +341,8 @@ function reanalysis_field_time_series(variable_name; size = (Nrx, Nry, Nz), longitude = λr, latitude = φr, - z = zc, - topology = (TX, Bounded, Flat)) + z = zr, + topology = (TX, Bounded, Bounded)) else LatitudeLongitudeGrid(native_fts_architecture, Float32; halo = (3, 3), From e7d6f727c456f9be3b68661783e651c384429920 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 5 May 2024 16:30:47 -0400 Subject: [PATCH 413/716] some changes --- src/DataWrangling/reanalysis_field_time_series.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DataWrangling/reanalysis_field_time_series.jl b/src/DataWrangling/reanalysis_field_time_series.jl index df45142f..d6575622 100644 --- a/src/DataWrangling/reanalysis_field_time_series.jl +++ b/src/DataWrangling/reanalysis_field_time_series.jl @@ -311,7 +311,6 @@ function reanalysis_field_time_series(variable_name; # Nodes at the variable location λc = ds["lon"][:] φc = ds["lat"][:] - zc = tridimensional_data ? ds["z"][:] : nothing # Interfaces for the "native" JRA55 grid λn = ds["lon_bnds"][1, :] From 16169e95564c8d08d2e0164ff3b993b5cde50b17 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 5 May 2024 16:31:53 -0400 Subject: [PATCH 414/716] small typo --- .../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 33aed9e6..ae0a7605 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -151,7 +151,7 @@ end # The complete bulk coefficient should include also `ψ(ℓ / L)`, but the # JRA55 atmosphere is adjusted to formulae without this last term so we exclude it -@inline simplified_bulk_coefficient(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) # + ψ(ℓ / L) +@inline simplified_bulk_coefficients(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) # + ψ(ℓ / L) ##### ##### Fixed-point iteration for roughness length From 3bf60f9c6f846bfc9124e19bc03ca5b123025c18 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 5 May 2024 19:11:59 -0400 Subject: [PATCH 415/716] almost working --- src/ClimaOcean.jl | 8 +- src/DataWrangling/DataWrangling.jl | 5 +- src/DataWrangling/ECCO4.jl | 119 ++---------- ...{ECCO4_climatology.jl => ECCO4_dataset.jl} | 66 +++---- src/DataWrangling/JRA55.jl | 131 ++----------- src/DataWrangling/abstract_metadata.jl | 178 ++++++++++++++++++ .../reanalysis_field_time_series.jl | 62 +++--- 7 files changed, 267 insertions(+), 302 deletions(-) rename src/DataWrangling/{ECCO4_climatology.jl => ECCO4_dataset.jl} (50%) create mode 100644 src/DataWrangling/abstract_metadata.jl diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index a5b5366b..547d68c2 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -28,15 +28,13 @@ include("OceanSimulations/OceanSimulations.jl") using .VerticalGrids using .Bathymetry -using .DataWrangling: JRA55 -using .DataWrangling: ECCO4 using .InitialConditions using .OceanSeaIceModels: OceanSeaIceModel using .OceanSimulations -using .DataWrangling: JRA55, ECCO4 +using .DataWrangling using ClimaOcean.DataWrangling: NetCDFBackend -using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere -using ClimaOcean.DataWrangling.ECCO4: ecco4_field +using ClimaOcean.DataWrangling: JRA55_prescribed_atmosphere +using ClimaOcean.DataWrangling: ecco4_field using .OceanSeaIceModels: OceanSeaIceModel, Radiation diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index 3d514760..69b7e2eb 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -70,11 +70,10 @@ function save_field_time_series!(fts; path, name, overwrite_existing=false) end include("inpaint_mask.jl") +include("abstract_metadata.jl") +include("ECCO4_dataset.jl") include("reanalysis_field_time_series.jl") include("JRA55.jl") include("ECCO4.jl") -using .JRA55 -using .ECCO4 - end # module diff --git a/src/DataWrangling/ECCO4.jl b/src/DataWrangling/ECCO4.jl index b05d2888..408ce71a 100644 --- a/src/DataWrangling/ECCO4.jl +++ b/src/DataWrangling/ECCO4.jl @@ -1,5 +1,3 @@ -module ECCO4 - export ECCOMetadata, ecco4_field, ecco4_center_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.DataWrangling: inpaint_mask! @@ -15,16 +13,6 @@ using NCDatasets using Downloads: download using Dates -import Oceananigans.Fields: set! - -# Ecco field used to set model's initial conditions -struct ECCOMetadata - name :: Symbol - year :: Int - month :: Int - day :: Int -end - const ECCO_Nx = 720 const ECCO_Ny = 360 const ECCO_Nz = 50 @@ -84,80 +72,9 @@ const ECCO_z = [ 0.0, ] -unprocessed_ecco4_file_prefix = Dict( - :temperature => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), - :salinity => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), -) - -# We only have 1992 at the moment -ECCOMetadata(name::Symbol) = ECCOMetadata(name, 1992, 1, 2) - -function ECCOMetadata(name::Symbol, date::DateTimeAllLeap) - year = Dates.year(date) - month = Dates.month(date) - day = Dates.day(date) - - return ECCOMetadata(name, year, month, day) -end - -date(data::ECCOMetadata) = DateTimeAllLeap(data.year, data.month, data.day) - -function date_string(metadata::ECCOMetadata) - yearstr = string(metadata.year) - monthstr = string(metadata.month, pad=2) - daystr = string(metadata.day, pad=2) - return "$(yearstr)-$(monthstr)-$(daystr)" -end +empty_ecco4_field(variable_name::Symbol; kw...) = empty_ecco4_field(ECCOMetadata(variable_name); kw...) -function ecco4_filename(metadata::ECCOMetadata) - variable_name = metadata.name - prefix, postfix = unprocessed_ecco4_file_prefix[variable_name] - datestr = date_string(metadata) - return prefix * datestr * postfix -end - -filename(data::ECCOMetadata) = "ecco4_" * string(data.name) * "_$(data.year)$(data.month)$(data.day).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, -) - -ecco4_short_names = Dict( - :temperature => "THETA", - :salinity => "SALT", - :u_velocity => "UVEL", - :v_velocity => "VVEL", - :sea_ice_thickness => "SIheff", - :sea_ice_area_fraction => "SIarea" -) - -ecco4_location = Dict( - :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), -) - -ecco4_remote_folder = Dict( - :temperature => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", - :salinity => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", -) - -surface_variable(variable_name) = variable_name == :sea_ice_thickness - -function empty_ecco4_field(metadata::ECCOMetadata; kw...) - variable_name = metadata.name - return empty_ecco4_field(variable_name; kw...) -end - -function empty_ecco4_field(variable_name::Symbol; +function empty_ecco4_field(metadata::ECCOMetadata; Nx = ECCO_Nx, Ny = ECCO_Ny, Nz = ECCO_Nz, @@ -165,14 +82,16 @@ function empty_ecco4_field(variable_name::Symbol; architecture = CPU(), horizontal_halo = (3, 3)) - + variable_name = metadata.name + location = field_location(metadata) + location = ecco4_location[variable_name] longitude = (0, 360) latitude = (-90, 90) TX, TY = (Periodic, Bounded) - if variable_is_three_dimensional[variable_name] + if variable_is_three_dimensional(metadata) z = z_faces # add vertical halo for 3D fields halo = (horizontal_halo..., 3) @@ -213,7 +132,7 @@ function ecco4_field(metadata::ECCOMetadata; architecture = CPU(), horizontal_halo = (3, 3), user_data = nothing, - filename = ecco4_filename(metadata), + filename = file_name(metadata), remote_folder = ecco4_remote_folder[metadata.name]) variable_name = metadata.name @@ -223,12 +142,19 @@ function ecco4_field(metadata::ECCOMetadata; if !isfile(filename) cmd = `podaac-data-downloader -c $(remote_folder) -d ./ --start-date $(datestr)T00:00:00Z --end-date $(datestr)T00:00:00Z -e .nc` @info "downloading $(filename) from $(remote_folder)" - run(cmd) + try + run(cmd) + catch error + @info "Note: to download ECCO4 data please install podaac-data-downloader using \\ + `pip install podaac`. Provide a username and password to the python environment. \\ + For details about the installation refer to " + throw(ArgumentError("The error is $error")) + end end if user_data isa Nothing ds = Dataset(filename) - if variable_is_three_dimensional[variable_name] + if variable_is_three_dimensional(metadata) data = ds[short_name][:, :, :, 1] # The surface layer in three-dimensional ECCO fields is at `k = 1` data = reverse(data, dims = 3) @@ -270,8 +196,8 @@ A boolean field where `false` represents a missing value in the ECCO :temperatur function ecco4_center_mask(architecture = CPU(); minimum_value = Float32(-1e5), maximum_value = Float32(1e5), - metadata = ECCOMetadata(:temperature, 1992, 1, 1), - filename = ecco4_filename(metadata)) + metadata = ECCOMetadata(:temperature), + filename = file_name(metadata)) field = ecco4_field(metadata; architecture, filename) mask = CenterField(field.grid, Bool) @@ -310,7 +236,7 @@ Keyword Arguments: function inpainted_ecco4_field(metadata::ECCOMetadata; architecture = CPU(), inpainted_filename = nothing, - filename = ecco4_filename(metadata), + filename = file_name(metadata), mask = ecco4_center_mask(architecture; filename), maxiter = Inf, kw...) @@ -408,10 +334,3 @@ function set!(field::Field, ecco4_metadata::ECCOMetadata; filename="./inpainted_ return field end - -include("ECCO4_climatology.jl") - -end # module - - - diff --git a/src/DataWrangling/ECCO4_climatology.jl b/src/DataWrangling/ECCO4_dataset.jl similarity index 50% rename from src/DataWrangling/ECCO4_climatology.jl rename to src/DataWrangling/ECCO4_dataset.jl index 4b75fbd9..e875325f 100644 --- a/src/DataWrangling/ECCO4_climatology.jl +++ b/src/DataWrangling/ECCO4_dataset.jl @@ -9,32 +9,36 @@ import Base: reverse @inline instantiate(T::DataType) = T() @inline instantiate(T) = T -function generate_ECCO_restoring_dataset(variable_name; - architecture = CPU(), - start_date = DateTimeAllLeap(1992, 1, 2), - end_date = DateTimeAllLeap(2017, 12, 31), - dataset_filename = "ciao.nc") - - Nt = 0 - date = start_date - while date <= end_date - Nt += 1 - date = date + Day(1) - end +function download_dataset!(metadata::ECCOMetadata) + dates = metadata.dates + output_filename = file_name(metadata) + isfile(output_filename) || + generate_ECCO_restoring_dataset!(metadata.name; dates, output_filename) + + return nothing +end +const all_ecco_4_dates = DateTimeAllLeap(1992, 1, 2) : Day(1) : DateTimeAllLeap(2017, 12, 31) + +function generate_ECCO_restoring_dataset!(variable_name; + architecture = CPU(), + dates = all_ecco_4_dates, + output_filename = "ecco4_$(metadata.name).nc") + + Nt = length(dates) field = empty_ecco4_field(variable_name) # Open a new dataset - ds = Dataset(dataset_filename, "c") + ds = Dataset(output_filename, "c") # Define the dimension "lon", "lat", "z" and "time", # with the size ECCO_Nx, ECCO_Ny, ECCO_Nz, and Nt, respectively. defDim(ds, "lon", ECCO_Nx) defDim(ds, "lat", ECCO_Ny) defDim(ds, "z", ECCO_Nz) - defDim(ds, "lon_bounds", ECCO_Nx) - defDim(ds, "lat_bounds", ECCO_Ny + 1) - defDim(ds, "z_bounds", ECCO_Nz + 1) + defDim(ds, "lon_bnds", ECCO_Nx) + defDim(ds, "lat_bnds", ECCO_Ny) + defDim(ds, "z_bnds", ECCO_Nz + 1) defDim(ds, "time", Nt) # Define the variables with the attribute units @@ -44,9 +48,9 @@ function generate_ECCO_restoring_dataset(variable_name; lat = defVar(ds, "lat", Float32, ("lat",)) zn = defVar(ds, "z", Float32, ("z", )) - lon_bounds = defVar(ds, "lon_bounds", Float32, ("lon_bounds",)) - lat_bounds = defVar(ds, "lat_bounds", Float32, ("lat_bounds",)) - z_bounds = defVar(ds, "z_bounds", Float32, ("z_bounds", )) + lon_bounds = defVar(ds, "lon_bnds", Float32, ("lon_bnds",)) + lat_bounds = defVar(ds, "lat_bnds", Float32, ("lat_bnds",)) + z_bounds = defVar(ds, "z_bnds", Float32, ("z_bnds", )) # Fill in the spatial nodes loc = instantiate.(location(field)) @@ -56,37 +60,21 @@ function generate_ECCO_restoring_dataset(variable_name; lat .= φ zn .= z lon_bounds .= λr - lat_bounds .= φr + lat_bounds .= φr[1:end-1] z_bounds .= zr # Start filling in time-specific data - n = 1 - date = start_date - while date <= end_date + for (n, date) in enumerate(dates) + metadata = ECCOMetadata(variable_name, date) @info "retrieving inpainted $(variable_name) at $(date)" field = inpainted_ecco4_field(metadata; architecture) - copyto!(data[:, :, :, n], interior(field)) + data[:, :, :, n] = Float32.(Array(interior(field))) time[n] = date.instant.periods.value / 1000 # Converting milliseconds to seconds - - n += 1 - - date = date + Day(1) end close(ds) return nothing -end - -function ECCO_forcing(variable_name; - time_indices = :, - mask = nothing, - architecture = CPU(), - backend = NetCDFBackend(4)) - - restoring_field = reanalysis_field_time_series(variable_name; time_indices, backend) - - return restoring_field end \ No newline at end of file diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index a813eb78..1d7c55bc 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -1,5 +1,3 @@ -module JRA55 - using Oceananigans using Oceananigans.Units @@ -25,106 +23,6 @@ import Oceananigans.Fields: set! import Oceananigans.OutputReaders: new_backend, update_field_time_series! using Downloads: download -# A list of all variables provided in the JRA55 dataset: -JRA55_variable_names = (:river_freshwater_flux, - :rain_freshwater_flux, - :snow_freshwater_flux, - :iceberg_freshwater_flux, - :specific_humidity, - :sea_level_pressure, - :relative_humidity, - :downwelling_longwave_radiation, - :downwelling_shortwave_radiation, - :temperature, - :eastward_velocity, - :northward_velocity) - -filenames = Dict( - :river_freshwater_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers - :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall - :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs - :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity - :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure - :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity - :downwelling_longwave_radiation => "RYF.rlds.1990_1991.nc", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "RYF.rsds.1990_1991.nc", # Downwelling shortwave radiation - :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 -) - -jra55_short_names = Dict( - :river_freshwater_flux => "friver", # Freshwater fluxes from rivers - :rain_freshwater_flux => "prra", # Freshwater flux from rainfall - :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "licalvf", # Freshwater flux from calving icebergs - :specific_humidity => "huss", # Surface specific humidity - :sea_level_pressure => "psl", # Sea level pressure - :relative_humidity => "rhuss", # Surface relative humidity - :downwelling_longwave_radiation => "rlds", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "rsds", # Downwelling shortwave radiation - :temperature => "tas", # Near-surface air temperature - :eastward_velocity => "uas", # Eastward near-surface wind - :northward_velocity => "vas", # Northward near-surface wind -) - -field_time_series_short_names = Dict( - :river_freshwater_flux => "Fri", # Freshwater fluxes from rivers - :rain_freshwater_flux => "Fra", # Freshwater flux from rainfall - :snow_freshwater_flux => "Fsn", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "Fic", # Freshwater flux from calving icebergs - :specific_humidity => "qa", # Surface specific humidity - :sea_level_pressure => "pa", # Sea level pressure - :relative_humidity => "rh", # Surface relative humidity - :downwelling_longwave_radiation => "Ql", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "Qs", # Downwelling shortwave radiation - :temperature => "Ta", # Near-surface air temperature - :eastward_velocity => "ua", # Eastward near-surface wind - :northward_velocity => "va", # Northward near-surface wind -) - -urls = Dict( - :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * - "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - - :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/" * - "RYF.prra.1990_1991.nc?rlkey=iifyjm4ppwyd8ztcek4dtx0k8&dl=0", - - :snow_freshwater_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * - "RYF.prsn.1990_1991.nc?rlkey=auyqpwn060cvy4w01a2yskfah&dl=0", - - :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/" * - "RYF.huss.1990_1991.nc?rlkey=107yq04aew8lrmfyorj68v4td&dl=0", - - :sea_level_pressure => "https://www.dropbox.com/scl/fi/0fk332027oru1iiseykgp/" * - "RYF.psl.1990_1991.nc?rlkey=4xpr9uah741483aukok6d7ctt&dl=0", - - :relative_humidity => "https://www.dropbox.com/scl/fi/1agwsp0lzvntuyf8bm9la/" * - "RYF.rhuss.1990_1991.nc?rlkey=8cd0vs7iy1rw58b9pc9t68gtz&dl=0", - - :downwelling_longwave_radiation => "https://www.dropbox.com/scl/fi/y6r62szkirrivua5nqq61/" * - "RYF.rlds.1990_1991.nc?rlkey=wt9yq3cyrvs2rbowoirf4nkum&dl=0", - - :downwelling_shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * - "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - - :temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * - "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", - - :eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * - "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", - - :northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * - "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", -) - const AA = Oceananigans.Architectures.AbstractArchitecture JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = @@ -155,18 +53,18 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); kw = (; time_indices, time_indexing, backend, architecture) kw = merge(kw, other_kw) - ua = reanalysis_field_time_series(:eastward_velocity; kw...) - va = reanalysis_field_time_series(:northward_velocity; kw...) - Ta = reanalysis_field_time_series(:temperature; kw...) - qa = reanalysis_field_time_series(:specific_humidity; kw...) - ra = reanalysis_field_time_series(:relative_humidity; kw...) - pa = reanalysis_field_time_series(:sea_level_pressure; kw...) - Fra = reanalysis_field_time_series(:rain_freshwater_flux; kw...) - Fsn = reanalysis_field_time_series(:snow_freshwater_flux; kw...) - Fri = reanalysis_field_time_series(:river_freshwater_flux; kw...) - Fic = reanalysis_field_time_series(:iceberg_freshwater_flux; kw...) - Ql = reanalysis_field_time_series(:downwelling_longwave_radiation; kw...) - Qs = reanalysis_field_time_series(:downwelling_shortwave_radiation; kw...) + ua = field_time_series_from_metadata(JRA55Metadata(:eastward_velocity, time_indices); kw...) + va = field_time_series_from_metadata(JRA55Metadata(:northward_velocity, time_indices); kw...) + Ta = field_time_series_from_metadata(JRA55Metadata(:temperature, time_indices); kw...) + qa = field_time_series_from_metadata(JRA55Metadata(:specific_humidity, time_indices); kw...) + ra = field_time_series_from_metadata(JRA55Metadata(:relative_humidity, time_indices); kw...) + pa = field_time_series_from_metadata(JRA55Metadata(:sea_level_pressure, time_indices); kw...) + Fra = field_time_series_from_metadata(JRA55Metadata(:rain_freshwater_flux, time_indices); kw...) + Fsn = field_time_series_from_metadata(JRA55Metadata(:snow_freshwater_flux, time_indices); kw...) + Fri = field_time_series_from_metadata(JRA55Metadata(:river_freshwater_flux, time_indices); kw...) + Fic = field_time_series_from_metadata(JRA55Metadata(:iceberg_freshwater_flux, time_indices); kw...) + Ql = field_time_series_from_metadata(JRA55Metadata(:downwelling_longwave_radiation, time_indices); kw...) + Qs = field_time_series_from_metadata(JRA55Metadata(:downwelling_shortwave_radiation, time_indices); kw...) times = ua.times @@ -198,7 +96,4 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); pressure) return atmosphere -end - -end # module - +end \ No newline at end of file diff --git a/src/DataWrangling/abstract_metadata.jl b/src/DataWrangling/abstract_metadata.jl new file mode 100644 index 00000000..825a6383 --- /dev/null +++ b/src/DataWrangling/abstract_metadata.jl @@ -0,0 +1,178 @@ +using CFTime +using Dates +import Dates: year, month, day +import Oceananigans.Fields: set! + +abstract type AbstractMetadata end + +# Ecco field used to set model's initial conditions +struct ECCOMetadata{D} <: AbstractMetadata + name :: Symbol + dates :: D +end + +unprocessed_ecco4_file_prefix = Dict( + :temperature => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), + :salinity => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), +) + +# We always start from 1992 +ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeAllLeap(1992, 1, 1)) +date(data::ECCOMetadata) = DateTimeAllLeap(data.year, data.month, data.day) + +function extract_time_indices(metadata::ECCOMetadata) + dates = metadata.dates + days = dates .- dates[1] + return ceil.(Int, days ./ Day(1) .+ 1) +end + +function date_string(metadata::ECCOMetadata{<:DateTimeAllLeap}) + yearstr = string(Dates.year(metadata.dates)) + monthstr = string(Dates.month(metadata.dates), pad=2) + daystr = string(Dates.day(metadata.dates), pad=2) + return "$(yearstr)-$(monthstr)-$(daystr)" +end + +function file_name(metadata::ECCOMetadata{<:DateTimeAllLeap}) + variable_name = metadata.name + prefix, postfix = unprocessed_ecco4_file_prefix[variable_name] + datestr = date_string(metadata) + return prefix * datestr * postfix +end + +file_name(metadata::ECCOMetadata) = "ecco_$(metadata.name).nc" + +variable_is_three_dimensional(data::ECCOMetadata) = + data.name == :temperature || + data.name == :salinity || + data.name == :u_velocity || + data.name == :v_velocity + +short_name(data::ECCOMetadata) = data.name +field_location(data::ECCOMetadata) = ecco4_location[data.name] + +ecco4_short_names = Dict( + :temperature => "THETA", + :salinity => "SALT", + :u_velocity => "UVEL", + :v_velocity => "VVEL", + :sea_ice_thickness => "SIheff", + :sea_ice_area_fraction => "SIarea" +) + +ecco4_location = Dict( + :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), +) + +ecco4_remote_folder = Dict( + :temperature => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", + :salinity => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", +) + +struct JRA55Metadata{I} <: AbstractMetadata + name :: Symbol + time_indices :: I +end + +# A list of all variables provided in the JRA55 dataset: +JRA55_variable_names = (:river_freshwater_flux, + :rain_freshwater_flux, + :snow_freshwater_flux, + :iceberg_freshwater_flux, + :specific_humidity, + :sea_level_pressure, + :relative_humidity, + :downwelling_longwave_radiation, + :downwelling_shortwave_radiation, + :temperature, + :eastward_velocity, + :northward_velocity) + +extract_time_indices(metadata::JRA55Metadata) = metadata.time_indices + +file_name(metadata::JRA55Metadata) = filenames[metadata.name] +short_name(metadata::JRA55Metadata) = jra55_short_names[metadata.name] +variable_is_three_dimensional(metadata::JRA55Metadata) = false + +function download_dataset!(metadata::JRA55Metadata) + filename = file_name(metadata) + url = urls[metadata.name] + isfile(filename) || download(url, filename) + return nothing +end + +filenames = Dict( + :river_freshwater_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers + :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall + :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs + :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity + :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure + :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity + :downwelling_longwave_radiation => "RYF.rlds.1990_1991.nc", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "RYF.rsds.1990_1991.nc", # Downwelling shortwave radiation + :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 +) + +jra55_short_names = Dict( + :river_freshwater_flux => "friver", # Freshwater fluxes from rivers + :rain_freshwater_flux => "prra", # Freshwater flux from rainfall + :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "licalvf", # Freshwater flux from calving icebergs + :specific_humidity => "huss", # Surface specific humidity + :sea_level_pressure => "psl", # Sea level pressure + :relative_humidity => "rhuss", # Surface relative humidity + :downwelling_longwave_radiation => "rlds", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "rsds", # Downwelling shortwave radiation + :temperature => "tas", # Near-surface air temperature + :eastward_velocity => "uas", # Eastward near-surface wind + :northward_velocity => "vas", # Northward near-surface wind +) + +urls = Dict( + :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * + "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", + + :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/" * + "RYF.prra.1990_1991.nc?rlkey=iifyjm4ppwyd8ztcek4dtx0k8&dl=0", + + :snow_freshwater_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * + "RYF.prsn.1990_1991.nc?rlkey=auyqpwn060cvy4w01a2yskfah&dl=0", + + :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/" * + "RYF.huss.1990_1991.nc?rlkey=107yq04aew8lrmfyorj68v4td&dl=0", + + :sea_level_pressure => "https://www.dropbox.com/scl/fi/0fk332027oru1iiseykgp/" * + "RYF.psl.1990_1991.nc?rlkey=4xpr9uah741483aukok6d7ctt&dl=0", + + :relative_humidity => "https://www.dropbox.com/scl/fi/1agwsp0lzvntuyf8bm9la/" * + "RYF.rhuss.1990_1991.nc?rlkey=8cd0vs7iy1rw58b9pc9t68gtz&dl=0", + + :downwelling_longwave_radiation => "https://www.dropbox.com/scl/fi/y6r62szkirrivua5nqq61/" * + "RYF.rlds.1990_1991.nc?rlkey=wt9yq3cyrvs2rbowoirf4nkum&dl=0", + + :downwelling_shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * + "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", + + :temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * + "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", + + :eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * + "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", + + :northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * + "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", +) diff --git a/src/DataWrangling/reanalysis_field_time_series.jl b/src/DataWrangling/reanalysis_field_time_series.jl index d6575622..4c085517 100644 --- a/src/DataWrangling/reanalysis_field_time_series.jl +++ b/src/DataWrangling/reanalysis_field_time_series.jl @@ -81,7 +81,7 @@ function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) end # Convert dates to range until Oceananigans supports dates natively -function fts_times(native_times, start_time=DateTimeNoLeap(1900, 01, 01)) +function fts_times(native_times, start_time=native_times[1]) Nt = length(native_times) Δt = native_times[2] - native_times[1] # assume all times are equispaced Δt = Second(Δt).value @@ -207,21 +207,21 @@ Keyword arguments - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is loaded (not recommended). """ -function reanalysis_field_time_series(variable_name; - architecture = CPU(), - grid = nothing, - location = nothing, - url = nothing, - filename = nothing, - shortname = nothing, - latitude = nothing, - longitude = nothing, - tridimensional_data = false, - backend = InMemory(), - time_indexing = Cyclical(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) +function field_time_series_from_metadata(metadata::AbstractMetadata; + architecture = CPU(), + grid = nothing, + location = nothing, + latitude = nothing, + longitude = nothing, + filename = nothing, + backend = InMemory(), + time_indexing = Cyclical(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU()) + + tridimensional_data = variable_is_three_dimensional(metadata) + time_indices = extract_time_indices(metadata) + shortname = short_name(metadata) # OnDisk backends do not support time interpolation! # Disallow OnDisk for JRA55 dataset loading @@ -230,38 +230,25 @@ function reanalysis_field_time_series(variable_name; throw(ArgumentError(msg)) end - if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) - variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) - variables_msg = prod(variable_strs) - - msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', - "The variables provided by the JRA55-do dataset are:", '\n', - variables_msg) - - throw(ArgumentError(msg)) - end - if !isnothing(filename) && !isfile(filename) && isnothing(url) throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ If intended, please provide both the filename and url that should be used \n \ to download the new file.")) end - isnothing(shortname) && (shortname = jra55_short_names[variable_name]) - isnothing(filename) && (filename = filenames[variable_name]) - isnothing(url) && (url = urls[variable_name]) + isnothing(filename) && (filename = file_name(metadata)) # Record some important user decisions totally_in_memory = backend isa TotallyInMemory on_native_grid = isnothing(grid) !on_native_grid && backend isa NetCDFBackend && error("Can't use custom grid with NetCDFBackend.") - jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") - fts_name = field_time_series_short_names[variable_name] + # Download the necessary data + download_dataset!(metadata) # Note, we don't re-use existing jld2 files. - isfile(filename) || download(url, filename) - isfile(jld2_filename) && rm(jld2_filename) + output_filename = "ciao123.jld2" + isfile(output_filename) && rm(output_filename) # Determine default time indices if totally_in_memory @@ -313,9 +300,9 @@ function reanalysis_field_time_series(variable_name; φc = ds["lat"][:] # Interfaces for the "native" JRA55 grid - λn = ds["lon_bnds"][1, :] - φn = ds["lat_bnds"][1, :] - zr = tridimensional_data ? ds["z_bnds"][:] : nothing + λn = tridimensional_data ? ds["lon_bnds"][:] : ds["lon_bnds"][1, :] + φn = tridimensional_data ? ds["lat_bnds"][:] : ds["lat_bnds"][1, :] + zr = tridimensional_data ? ds["z_bnds"][:] : nothing # The .nc coordinates lon_bnds and lat_bnds do not include # the last interface, so we push them here. @@ -327,6 +314,7 @@ function reanalysis_field_time_series(variable_name; i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, location[1], location[2], λc, φc) native_times = ds["time"][time_indices] + data = tridimensional_data ? ds[shortname][i₁:i₂, j₁:j₂, :, time_indices_in_memory] : ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] φr = φn[j₁:j₂+1] From c6c7e2e4c9d96d004bbc25bb14955608f08ac1f5 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 5 May 2024 19:24:06 -0400 Subject: [PATCH 416/716] new changes --- src/DataWrangling/abstract_metadata.jl | 3 ++- src/DataWrangling/reanalysis_field_time_series.jl | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/DataWrangling/abstract_metadata.jl b/src/DataWrangling/abstract_metadata.jl index 825a6383..e4015ee0 100644 --- a/src/DataWrangling/abstract_metadata.jl +++ b/src/DataWrangling/abstract_metadata.jl @@ -95,9 +95,10 @@ JRA55_variable_names = (:river_freshwater_flux, extract_time_indices(metadata::JRA55Metadata) = metadata.time_indices -file_name(metadata::JRA55Metadata) = filenames[metadata.name] +file_name(metadata::JRA55Metadata) = filenames[metadata.name] short_name(metadata::JRA55Metadata) = jra55_short_names[metadata.name] variable_is_three_dimensional(metadata::JRA55Metadata) = false +field_location(::JRA55Metadata) = (Center, Center, Nothing) function download_dataset!(metadata::JRA55Metadata) filename = file_name(metadata) diff --git a/src/DataWrangling/reanalysis_field_time_series.jl b/src/DataWrangling/reanalysis_field_time_series.jl index 4c085517..3eaa48b7 100644 --- a/src/DataWrangling/reanalysis_field_time_series.jl +++ b/src/DataWrangling/reanalysis_field_time_series.jl @@ -279,12 +279,10 @@ function field_time_series_from_metadata(metadata::AbstractMetadata; end end - # Set a default location. if isnothing(location) - LX = LY = Center - location = tridimensional_data ? (LX, LY, Center) : (LX, LY, Nothing) + location = field_location(metadata) end - + ds = Dataset(filename) # Note that each file should have the variables From 4813cd9a57bc23cdb8f05a82aeb6e3c36de16b61 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 6 May 2024 16:21:04 -0400 Subject: [PATCH 417/716] some changes --- src/DataWrangling/ECCO4.jl | 11 ++++------- src/DataWrangling/ECCO4_dataset.jl | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/DataWrangling/ECCO4.jl b/src/DataWrangling/ECCO4.jl index 408ce71a..1d299487 100644 --- a/src/DataWrangling/ECCO4.jl +++ b/src/DataWrangling/ECCO4.jl @@ -292,12 +292,11 @@ function set!(field::DistributedField, ecco4_metadata::ECCOMetadata; filename=". grid = field.grid arch = architecture(grid) child_arch = child_architecture(arch) - name = ecco4_metadata.name f_ecco = if arch.local_rank == 0 # Make sure we read/write the file using only one core mask = ecco4_center_mask(child_arch) - inpainted_ecco4_field(name; filename, mask, + inpainted_ecco4_field(ecco4_metadata; inpainted_filename = filename, mask, architecture = child_arch, kw...) else @@ -309,7 +308,7 @@ function set!(field::DistributedField, ecco4_metadata::ECCOMetadata; filename=". # Distribute ecco field to all workers parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) - f_grid = Field(ecco4_location[name], grid) + f_grid = Field(field_location(ecco4_metadata), grid) interpolate!(f_grid, f_ecco) set!(field, f_grid) @@ -320,15 +319,13 @@ function set!(field::Field, ecco4_metadata::ECCOMetadata; filename="./inpainted_ # Fields initialized from ECCO grid = field.grid - name = ecco4_metadata.name - mask = ecco4_center_mask(architecture(grid)) - f = inpainted_ecco4_field(name; filename, mask, + f = inpainted_ecco4_field(ecco4_metadata; inpainted_filename = filename, mask, architecture = architecture(grid), kw...) - f_grid = Field(ecco4_location[name], grid) + f_grid = Field(field_location(ecco4_metadata), grid) interpolate!(f_grid, f) set!(field, f_grid) diff --git a/src/DataWrangling/ECCO4_dataset.jl b/src/DataWrangling/ECCO4_dataset.jl index e875325f..65597f36 100644 --- a/src/DataWrangling/ECCO4_dataset.jl +++ b/src/DataWrangling/ECCO4_dataset.jl @@ -23,7 +23,7 @@ const all_ecco_4_dates = DateTimeAllLeap(1992, 1, 2) : Day(1) : DateTimeAllLeap( function generate_ECCO_restoring_dataset!(variable_name; architecture = CPU(), dates = all_ecco_4_dates, - output_filename = "ecco4_$(metadata.name).nc") + output_filename = "ecco4_$(variable_name).nc") Nt = length(dates) field = empty_ecco4_field(variable_name) From c5483844065934eb7bf5c3a87e1881da862a5619 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 6 May 2024 19:26:47 -0400 Subject: [PATCH 418/716] change bulk coefficients function --- .../similarity_theory_turbulent_fluxes.jl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index ae0a7605..e6532c94 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -67,9 +67,9 @@ Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt( adapt(to, fluxes.roughness_lengths), adapt(to, fluxes.bulk_coefficients), adapt(to, fluxes.bulk_velocity), - fluxes.iteration, fluxes.tolerance, fluxes.maxiter, + fluxes.iteration, adapt(to, fluxes.fields)) Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" @@ -114,10 +114,10 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), roughness_lengths = default_roughness_lengths(FT), - bulk_coefficients = simplified_bulk_coefficients, + bulk_coefficients = bulk_coefficients, bulk_velocity = RelativeVelocity(), tolerance = 1e-8, - maxiter = Inf, + maxiter = 100, fields = nothing) return SimilarityTheoryTurbulentFluxes(convert(FT, gravitational_acceleration), @@ -131,7 +131,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; roughness_lengths, bulk_coefficients, bulk_velocity, - tolerance, + convert(FT, tolerance), maxiter, 0, fields) @@ -149,10 +149,13 @@ function SimilarityTheoryTurbulentFluxes(grid::AbstractGrid; kw...) return SimilarityTheoryTurbulentFluxes(eltype(grid); kw..., fields) end -# The complete bulk coefficient should include also `ψ(ℓ / L)`, but the -# JRA55 atmosphere is adjusted to formulae without this last term so we exclude it +# The complete bulk coefficient should include also `ψ(ℓ / L)`, +# All this part is pretty @inline simplified_bulk_coefficients(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) # + ψ(ℓ / L) +# The complete bulk coefficient +@inline bulk_coefficients(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) + ψ(ℓ / L) + ##### ##### Fixed-point iteration for roughness length ##### From c507434e8eb8f98f7a5909ccbe25621813a2c05f Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 6 May 2024 19:27:35 -0400 Subject: [PATCH 419/716] better comment --- .../CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index e6532c94..83d5bbb8 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -149,8 +149,7 @@ function SimilarityTheoryTurbulentFluxes(grid::AbstractGrid; kw...) return SimilarityTheoryTurbulentFluxes(eltype(grid); kw..., fields) end -# The complete bulk coefficient should include also `ψ(ℓ / L)`, -# All this part is pretty +# Simplified coefficient a la COARE @inline simplified_bulk_coefficients(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) # + ψ(ℓ / L) # The complete bulk coefficient From 6ab58e77af811b051c50ea6c9a6df93e66c2e7cf Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 6 May 2024 22:57:42 -0400 Subject: [PATCH 420/716] All this works! --- prototype_omip_simulation/Manifest.toml | 32 +- .../comparison_to_coare.jl | 26 +- ...mmersed_grid.jl => ecco4_immersed_grid.jl} | 0 src/ClimaOcean.jl | 13 +- src/DataWrangling/DataWrangling.jl | 6 +- src/DataWrangling/ECCO4.jl | 10 + src/DataWrangling/ECCO4_dataset.jl | 80 --- src/DataWrangling/JRA55.jl | 584 +++++++++++++++++- src/DataWrangling/abstract_metadata.jl | 179 ------ src/DataWrangling/ecco4_field_time_series.jl | 159 +++++ src/DataWrangling/ecco4_metadata.jl | 81 +++ src/DataWrangling/inpaint_mask.jl | 7 + .../reanalysis_field_time_series.jl | 474 -------------- 13 files changed, 882 insertions(+), 769 deletions(-) rename prototype_omip_simulation/{ecco2_immersed_grid.jl => ecco4_immersed_grid.jl} (100%) delete mode 100644 src/DataWrangling/ECCO4_dataset.jl delete mode 100644 src/DataWrangling/abstract_metadata.jl create mode 100644 src/DataWrangling/ecco4_field_time_series.jl create mode 100644 src/DataWrangling/ecco4_metadata.jl delete mode 100644 src/DataWrangling/reanalysis_field_time_series.jl diff --git a/prototype_omip_simulation/Manifest.toml b/prototype_omip_simulation/Manifest.toml index 43145043..5de53617 100644 --- a/prototype_omip_simulation/Manifest.toml +++ b/prototype_omip_simulation/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.2" +julia_version = "1.10.3" manifest_format = "2.0" project_hash = "2b8dc0157e67ed69c1dbe71ccf1e8d7dd3d38b48" @@ -192,10 +192,10 @@ weakdeps = ["SparseArrays"] ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.ClimaOcean]] -deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "FFMPEG", "ImageMorphology", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +deps = ["Adapt", "CFTime", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "FFMPEG", "ImageMorphology", "JLD2", "JSON3", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "Revise", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] path = ".." uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -version = "0.1.0" +version = "0.2.0" [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] @@ -211,6 +211,12 @@ git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" version = "0.1.12" +[[deps.CodeTracking]] +deps = ["InteractiveUtils", "UUIDs"] +git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386" +uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" +version = "1.3.5" + [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" @@ -269,7 +275,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.0+0" +version = "1.1.1+0" [[deps.CompositionsBase]] git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" @@ -698,6 +704,12 @@ git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" version = "1.13.2" +[[deps.JuliaInterpreter]] +deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] +git-tree-sha1 = "e9648d90370e2d0317f9518c9c6e0841db54a90b" +uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" +version = "0.9.31" + [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" @@ -887,6 +899,12 @@ weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] SpecialFunctionsExt = "SpecialFunctions" +[[deps.LoweredCodeUtils]] +deps = ["JuliaInterpreter"] +git-tree-sha1 = "31e27f0b0bf0df3e3e951bfcc43fe8c730a219f6" +uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" +version = "2.4.5" + [[deps.Lz4_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" @@ -1282,6 +1300,12 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" +[[deps.Revise]] +deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"] +git-tree-sha1 = "12aa2d7593df490c407a3bbd8b86b8b515017f3e" +uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" +version = "3.5.14" + [[deps.RootSolvers]] deps = ["ForwardDiff"] git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index a573c202..4c4a4f45 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -3,23 +3,31 @@ using Oceananigans.Units using ClimaOcean using Oceananigans using Oceananigans.Operators -using ClimaOcean.ECCO4 +using ClimaOcean.DataWrangling using ClimaOcean.OceanSimulations using Oceananigans.Units -using ClimaOcean.JRA55: JRA55_prescribed_atmosphere +using ClimaOcean.DataWrangling: JRA55_prescribed_atmosphere using ClimaOcean.OceanSeaIceModels: Radiation # Upload ECCO4 fields -T = ECCO4.ecco4_field(:temperature) -S = ECCO4.ecco4_field(:salinity) -u = ECCO4.ecco4_field(:u_velocity) -v = ECCO4.ecco4_field(:v_velocity) +# T = DataWrangling.inpainted_ecco4_field(:temperature) +# S = DataWrangling.inpainted_ecco4_field(:salinity) +# u = DataWrangling.inpainted_ecco4_field(:u_velocity) +# v = DataWrangling.inpainted_ecco4_field(:v_velocity) + +# include("ecco4_immersed_grid.jl") +# grid = ecco4_immersed_grid() -include("ecco4_immersed_grid.jl") -grid = ecco4_immersed_grid() # Let's leave out the radiation for the moment (too simple to test) -atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory(), grid = grid.underlying_grid) +atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory()) #, grid = grid.underlying_grid) + +grid = atmosphere.fields.velocities.u.grid + +T = CenterField(grid) +S = CenterField(grid) +u = XFaceField(grid) +v = YFaceField(grid) ocean = ocean_simulation(grid; momentum_advection = nothing, tracer_advection = nothing) diff --git a/prototype_omip_simulation/ecco2_immersed_grid.jl b/prototype_omip_simulation/ecco4_immersed_grid.jl similarity index 100% rename from prototype_omip_simulation/ecco2_immersed_grid.jl rename to prototype_omip_simulation/ecco4_immersed_grid.jl diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 547d68c2..56782340 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -5,8 +5,8 @@ export MinimumTemperatureSeaIce, Radiation, JRA55_prescribed_atmosphere, - NetCDFBackend, - ecco4_field, + JRA55NetCDFBackend, + ecco2_field, regrid_bathymetry, stretched_vertical_faces, PowerLawStretching, LinearStretching, @@ -28,13 +28,14 @@ include("OceanSimulations/OceanSimulations.jl") using .VerticalGrids using .Bathymetry +using .DataWrangling: JRA55 +using .DataWrangling: ECCO4 using .InitialConditions using .OceanSeaIceModels: OceanSeaIceModel using .OceanSimulations -using .DataWrangling -using ClimaOcean.DataWrangling: NetCDFBackend -using ClimaOcean.DataWrangling: JRA55_prescribed_atmosphere -using ClimaOcean.DataWrangling: ecco4_field +using .DataWrangling: JRA55, ECCO4 +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend +using ClimaOcean.DataWrangling.ECCO4: ecco4_field using .OceanSeaIceModels: OceanSeaIceModel, Radiation diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index 69b7e2eb..a6a17944 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -70,10 +70,10 @@ function save_field_time_series!(fts; path, name, overwrite_existing=false) end include("inpaint_mask.jl") -include("abstract_metadata.jl") -include("ECCO4_dataset.jl") -include("reanalysis_field_time_series.jl") include("JRA55.jl") include("ECCO4.jl") +using .JRA55 +using .ECCO4 + end # module diff --git a/src/DataWrangling/ECCO4.jl b/src/DataWrangling/ECCO4.jl index 1d299487..484d4477 100644 --- a/src/DataWrangling/ECCO4.jl +++ b/src/DataWrangling/ECCO4.jl @@ -1,3 +1,5 @@ +module ECCO4 + export ECCOMetadata, ecco4_field, ecco4_center_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.DataWrangling: inpaint_mask! @@ -13,6 +15,8 @@ using NCDatasets using Downloads: download using Dates +include("ecco4_metadata.jl") + const ECCO_Nx = 720 const ECCO_Ny = 360 const ECCO_Nz = 50 @@ -287,6 +291,8 @@ function inpainted_ecco4_field(metadata::ECCOMetadata; return f end +inpainted_ecco4_field(variable_name::Symbol; kw...) = inpainted_ecco4_field(ECCOMetadata(variable_name); kw...) + function set!(field::DistributedField, ecco4_metadata::ECCOMetadata; filename="./inpainted_ecco4_fields.nc", kw...) # Fields initialized from ECCO grid = field.grid @@ -331,3 +337,7 @@ function set!(field::Field, ecco4_metadata::ECCOMetadata; filename="./inpainted_ return field end + +include("ecco4_field_time_series.jl") + +end # Module \ No newline at end of file diff --git a/src/DataWrangling/ECCO4_dataset.jl b/src/DataWrangling/ECCO4_dataset.jl deleted file mode 100644 index 65597f36..00000000 --- a/src/DataWrangling/ECCO4_dataset.jl +++ /dev/null @@ -1,80 +0,0 @@ -using CFTime -using Dates - -import Base: reverse - -@inline reverse(::Face) = Center() -@inline reverse(::Center) = Face() - -@inline instantiate(T::DataType) = T() -@inline instantiate(T) = T - -function download_dataset!(metadata::ECCOMetadata) - dates = metadata.dates - output_filename = file_name(metadata) - isfile(output_filename) || - generate_ECCO_restoring_dataset!(metadata.name; dates, output_filename) - - return nothing -end - -const all_ecco_4_dates = DateTimeAllLeap(1992, 1, 2) : Day(1) : DateTimeAllLeap(2017, 12, 31) - -function generate_ECCO_restoring_dataset!(variable_name; - architecture = CPU(), - dates = all_ecco_4_dates, - output_filename = "ecco4_$(variable_name).nc") - - Nt = length(dates) - field = empty_ecco4_field(variable_name) - - # Open a new dataset - ds = Dataset(output_filename, "c") - - # Define the dimension "lon", "lat", "z" and "time", - # with the size ECCO_Nx, ECCO_Ny, ECCO_Nz, and Nt, respectively. - defDim(ds, "lon", ECCO_Nx) - defDim(ds, "lat", ECCO_Ny) - defDim(ds, "z", ECCO_Nz) - defDim(ds, "lon_bnds", ECCO_Nx) - defDim(ds, "lat_bnds", ECCO_Ny) - defDim(ds, "z_bnds", ECCO_Nz + 1) - defDim(ds, "time", Nt) - - # Define the variables with the attribute units - data = defVar(ds, string(variable_name), Float32, ("lon", "lat", "z", "time")) - time = defVar(ds, "time", Float32, ("time",)) - lon = defVar(ds, "lon", Float32, ("lon",)) - lat = defVar(ds, "lat", Float32, ("lat",)) - zn = defVar(ds, "z", Float32, ("z", )) - - lon_bounds = defVar(ds, "lon_bnds", Float32, ("lon_bnds",)) - lat_bounds = defVar(ds, "lat_bnds", Float32, ("lat_bnds",)) - z_bounds = defVar(ds, "z_bnds", Float32, ("z_bnds", )) - - # Fill in the spatial nodes - loc = instantiate.(location(field)) - λ, φ, z = nodes(field) - λr, φr, zr = nodes(field.grid, reverse.(loc)...) - lon .= λ - lat .= φ - zn .= z - lon_bounds .= λr - lat_bounds .= φr[1:end-1] - z_bounds .= zr - - # Start filling in time-specific data - for (n, date) in enumerate(dates) - - metadata = ECCOMetadata(variable_name, date) - - @info "retrieving inpainted $(variable_name) at $(date)" - field = inpainted_ecco4_field(metadata; architecture) - data[:, :, :, n] = Float32.(Array(interior(field))) - time[n] = date.instant.periods.value / 1000 # Converting milliseconds to seconds - end - - close(ds) - - return nothing -end \ No newline at end of file diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 1d7c55bc..acafa58c 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -1,3 +1,5 @@ +module JRA55 + using Oceananigans using Oceananigans.Units @@ -23,6 +25,557 @@ import Oceananigans.Fields: set! import Oceananigans.OutputReaders: new_backend, update_field_time_series! using Downloads: download +# A list of all variables provided in the JRA55 dataset: +JRA55_variable_names = (:river_freshwater_flux, + :rain_freshwater_flux, + :snow_freshwater_flux, + :iceberg_freshwater_flux, + :specific_humidity, + :sea_level_pressure, + :relative_humidity, + :downwelling_longwave_radiation, + :downwelling_shortwave_radiation, + :temperature, + :eastward_velocity, + :northward_velocity) + +filenames = Dict( + :river_freshwater_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers + :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall + :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs + :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity + :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure + :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity + :downwelling_longwave_radiation => "RYF.rlds.1990_1991.nc", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "RYF.rsds.1990_1991.nc", # Downwelling shortwave radiation + :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 +) + +jra55_short_names = Dict( + :river_freshwater_flux => "friver", # Freshwater fluxes from rivers + :rain_freshwater_flux => "prra", # Freshwater flux from rainfall + :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "licalvf", # Freshwater flux from calving icebergs + :specific_humidity => "huss", # Surface specific humidity + :sea_level_pressure => "psl", # Sea level pressure + :relative_humidity => "rhuss", # Surface relative humidity + :downwelling_longwave_radiation => "rlds", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "rsds", # Downwelling shortwave radiation + :temperature => "tas", # Near-surface air temperature + :eastward_velocity => "uas", # Eastward near-surface wind + :northward_velocity => "vas", # Northward near-surface wind +) + +field_time_series_short_names = Dict( + :river_freshwater_flux => "Fri", # Freshwater fluxes from rivers + :rain_freshwater_flux => "Fra", # Freshwater flux from rainfall + :snow_freshwater_flux => "Fsn", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "Fic", # Freshwater flux from calving icebergs + :specific_humidity => "qa", # Surface specific humidity + :sea_level_pressure => "pa", # Sea level pressure + :relative_humidity => "rh", # Surface relative humidity + :downwelling_longwave_radiation => "Ql", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "Qs", # Downwelling shortwave radiation + :temperature => "Ta", # Near-surface air temperature + :eastward_velocity => "ua", # Eastward near-surface wind + :northward_velocity => "va", # Northward near-surface wind +) + +urls = Dict( + :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * + "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", + + :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/" * + "RYF.prra.1990_1991.nc?rlkey=iifyjm4ppwyd8ztcek4dtx0k8&dl=0", + + :snow_freshwater_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * + "RYF.prsn.1990_1991.nc?rlkey=auyqpwn060cvy4w01a2yskfah&dl=0", + + :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/" * + "RYF.huss.1990_1991.nc?rlkey=107yq04aew8lrmfyorj68v4td&dl=0", + + :sea_level_pressure => "https://www.dropbox.com/scl/fi/0fk332027oru1iiseykgp/" * + "RYF.psl.1990_1991.nc?rlkey=4xpr9uah741483aukok6d7ctt&dl=0", + + :relative_humidity => "https://www.dropbox.com/scl/fi/1agwsp0lzvntuyf8bm9la/" * + "RYF.rhuss.1990_1991.nc?rlkey=8cd0vs7iy1rw58b9pc9t68gtz&dl=0", + + :downwelling_longwave_radiation => "https://www.dropbox.com/scl/fi/y6r62szkirrivua5nqq61/" * + "RYF.rlds.1990_1991.nc?rlkey=wt9yq3cyrvs2rbowoirf4nkum&dl=0", + + :downwelling_shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * + "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", + + :temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * + "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", + + :eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * + "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", + + :northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * + "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", +) + +compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing +compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds + +# TODO: remove the allowscalar +function compute_bounding_nodes(::Nothing, grid, LH, hnodes) + hg = hnodes(grid, LH()) + h₁ = @allowscalar minimum(hg) + h₂ = @allowscalar maximum(hg) + return h₁, h₂ +end + +function compute_bounding_indices(::Nothing, hc) + Nh = length(hc) + return 1, Nh +end + +function compute_bounding_indices(bounds, hc) + h₁, h₂ = bounds + Nh = length(hc) + + # The following should work. If ᵒ are the extrema of nodes we want to + # interpolate to, and the following is a sketch of the JRA55 native grid, + # + # 1 2 3 4 5 + # | | | | | | + # | x ᵒ | x | x | x ᵒ | x | + # | | | | | | + # 1 2 3 4 5 6 + # + # then for example, we should find that (iᵢ, i₂) = (1, 5). + # So we want to reduce the first index by one, and limit them + # both by the available data. There could be some mismatch due + # to the use of different coordinate systems (ie whether λ ∈ (0, 360) + # which we may also need to handle separately. + i₁ = searchsortedfirst(hc, h₁) + i₂ = searchsortedfirst(hc, h₂) + i₁ = max(1, i₁ - 1) + i₂ = min(Nh, i₂) + + return i₁, i₂ +end + +infer_longitudinal_topology(::Nothing) = Periodic + +function infer_longitudinal_topology(λbounds) + λ₁, λ₂ = λbounds + TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded + return TX +end + +function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + λbounds = compute_bounding_nodes(longitude, grid, LX, λnodes) + φbounds = compute_bounding_nodes(latitude, grid, LY, φnodes) + + i₁, i₂ = compute_bounding_indices(λbounds, λc) + j₁, j₂ = compute_bounding_indices(φbounds, φc) + TX = infer_longitudinal_topology(λbounds) + + return i₁, i₂, j₁, j₂, TX +end + +# Convert dates to range until Oceananigans supports dates natively +function jra55_times(native_times, start_time=DateTimeProlepticGregorian(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(nothing, nothing, fts.grid, LX, LY, λc, φc) + + ti = time_indices(fts) + ti = collect(ti) + data = ds[name][i₁:i₂, j₁:j₂, ti] + close(ds) + + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) + + return nothing +end + +new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length) + +""" + JRA55_field_time_series(variable_name; + architecture = CPU(), + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + backend = InMemory(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + +Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, +which describes one of the variables in the "repeat year forcing" dataset derived +from the Japanese 55-year atmospheric reanalysis for driving ocean-sea-ice models (JRA55-do). +For more information about the derivation of the repeat year forcing dataset, see + +"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 `shortname`s used in NetCDF files) +available from the JRA55-do are: + + - `: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 +================= + + - `architecture`: Architecture for the `FieldTimeSeries`. + Default: CPU() + + - `time_indices`: Indices of the timeseries to extract from file. + For example, `time_indices=1:3` returns a + `FieldTimeSeries` with the first three time snapshots + of `variable_name`. + + - `url`: The url accessed to download the data for `variable_name`. + Default: `ClimaOcean.JRA55.urls[variable_name]`. + + - `filename`: The name of the downloaded file. + Default: `ClimaOcean.JRA55.filenames[variable_name]`. + + - `shortname`: The "short name" of `variable_name` inside its NetCDF file. + Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. + + - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. + If it does not exist it will be generated. + + - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is + loaded (not recommended). +""" +function JRA55_field_time_series(variable_name; + architecture = CPU(), + grid = nothing, + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + latitude = nothing, + longitude = nothing, + backend = InMemory(), + time_indexing = Cyclical(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + + # OnDisk backends do not support time interpolation! + # Disallow OnDisk for JRA55 dataset loading + if backend isa OnDisk + msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") + throw(ArgumentError(msg)) + end + + if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) + variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) + variables_msg = prod(variable_strs) + + msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', + "The variables provided by the JRA55-do dataset are:", '\n', + variables_msg) + + throw(ArgumentError(msg)) + end + + if !isnothing(filename) && !isfile(filename) && isnothing(url) + throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ + If intended, please provide both the filename and url that should be used \n \ + to download the new file.")) + end + + isnothing(shortname) && (shortname = jra55_short_names[variable_name]) + isnothing(filename) && (filename = filenames[variable_name]) + isnothing(url) && (url = urls[variable_name]) + + # Record some important user decisions + totally_in_memory = backend isa TotallyInMemory + on_native_grid = isnothing(grid) + !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") + + jld2_filename = string("JRA55_repeat_year_", variable_name, ".jld2") + fts_name = field_time_series_short_names[variable_name] + + # Note, we don't re-use existing jld2 files. + isfile(filename) || download(url, filename) + isfile(jld2_filename) && rm(jld2_filename) + + # Determine default time indices + if totally_in_memory + # In this case, the whole time series is in memory. + # Either the time series is short, or we are doing a limited-area + # simulation, like in a single column. So, we conservatively + # set a default `time_indices = 1:2`. + isnothing(time_indices) && (time_indices = 1:2) + time_indices_in_memory = time_indices + native_fts_architecture = architecture + else + # In this case, part or all of the time series will be stored in a file. + # Note: if the user has provided a grid, we will have to preprocess the + # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers + # to the time_indices that we will preprocess; + # by default we choose all of them. The architecture is only the + # architecture used for preprocessing, which typically will be CPU() + # even if we would like the final FieldTimeSeries on the GPU. + isnothing(time_indices) && (time_indices = :) + + if backend isa JRA55NetCDFBackend + time_indices_in_memory = 1:length(backend) + native_fts_architecture = architecture + else # then `time_indices_in_memory` refers to preprocessing + maximum_index = min(preprocess_chunk_size, length(time_indices)) + time_indices_in_memory = 1:maximum_index + native_fts_architecture = preprocess_architecture + end + end + + # Set a default location. + if isnothing(location) + LX = LY = Center + else + LX, LY = location + end + + ds = Dataset(filename) + + # Note that each file should have the variables + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data + + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + + # 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!(φn, 90) + push!(λn, λn[1] + 360) + + # TODO: support loading just part of the JRA55 data. + # Probably with arguments that take latitude, longitude bounds. + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + + native_times = ds["time"][time_indices] + data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + λr = λn[i₁:i₂+1] + φr = φn[j₁:j₂+1] + Nrx, Nry, Nt = size(data) + close(ds) + + JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; + halo = (3, 3), + size = (Nrx, Nry), + longitude = λr, + latitude = φr, + topology = (TX, Bounded, Flat)) + + boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) + times = jra55_times(native_times) + + if backend isa JRA55NetCDFBackend + fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = filename, + name = shortname) + + # Fill the data in a GPU-friendly manner + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) + + 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) + + if on_native_grid && totally_in_memory + return native_fts + + elseif totally_in_memory # but not on the native grid! + boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) + fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) + interpolate!(fts, native_fts) + return fts + end + end + + @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." + + preprocessing_grid = on_native_grid ? JRA55_native_grid : grid + + # Re-open the dataset! + ds = Dataset(filename) + all_datetimes = ds["time"][time_indices] + all_Nt = length(all_datetimes) + + all_times = jra55_times(all_datetimes) + + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; + boundary_conditions, + backend = OnDisk(), + path = jld2_filename, + name = fts_name) + + # Save data to disk, one field at a time + start_clock = time_ns() + n = 1 # on disk + m = 0 # in memory + + times_in_memory = all_times[time_indices_in_memory] + + fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; + boundary_conditions, + backend = InMemory(), + path = jld2_filename, + name = fts_name) + + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + + if !on_native_grid + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + end + + while n <= all_Nt + print(" ... processing time index $n of $all_Nt \r") + + if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory + m += 1 + else # load new data + # Update time_indices + time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size + n₁ = first(time_indices_in_memory) + + # Clip time_indices if they extend past the end of the dataset + if last(time_indices_in_memory) > all_Nt + time_indices_in_memory = UnitRange(n₁, all_Nt) + end + + # Re-compute times + new_times = jra55_times(all_times[time_indices_in_memory], all_times[n₁]) + native_fts.times = new_times + + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + fts.times = new_times + + if !on_native_grid + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + end + + m = 1 # reset + end + + set!(on_disk_fts, fts[m], n, fts.times[m]) + + n += 1 + end + + elapsed = 1e-9 * (time_ns() - start_clock) + elapsed_str = prettytime(elapsed) + @info " ... done ($elapsed_str)" * repeat(" ", 20) + + close(ds) + + user_fts = FieldTimeSeries(jld2_filename, fts_name; architecture, backend, time_indexing) + fill_halo_regions!(user_fts) + + return user_fts +end + const AA = Oceananigans.Architectures.AbstractArchitecture JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = @@ -47,24 +600,24 @@ 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 = NetCDFBackend(Nf) + backend = JRA55NetCDFBackend(Nf) end kw = (; time_indices, time_indexing, backend, architecture) kw = merge(kw, other_kw) - ua = field_time_series_from_metadata(JRA55Metadata(:eastward_velocity, time_indices); kw...) - va = field_time_series_from_metadata(JRA55Metadata(:northward_velocity, time_indices); kw...) - Ta = field_time_series_from_metadata(JRA55Metadata(:temperature, time_indices); kw...) - qa = field_time_series_from_metadata(JRA55Metadata(:specific_humidity, time_indices); kw...) - ra = field_time_series_from_metadata(JRA55Metadata(:relative_humidity, time_indices); kw...) - pa = field_time_series_from_metadata(JRA55Metadata(:sea_level_pressure, time_indices); kw...) - Fra = field_time_series_from_metadata(JRA55Metadata(:rain_freshwater_flux, time_indices); kw...) - Fsn = field_time_series_from_metadata(JRA55Metadata(:snow_freshwater_flux, time_indices); kw...) - Fri = field_time_series_from_metadata(JRA55Metadata(:river_freshwater_flux, time_indices); kw...) - Fic = field_time_series_from_metadata(JRA55Metadata(:iceberg_freshwater_flux, time_indices); kw...) - Ql = field_time_series_from_metadata(JRA55Metadata(:downwelling_longwave_radiation, time_indices); kw...) - Qs = field_time_series_from_metadata(JRA55Metadata(:downwelling_shortwave_radiation, time_indices); kw...) + ua = JRA55_field_time_series(:eastward_velocity; kw...) + va = JRA55_field_time_series(:northward_velocity; kw...) + Ta = JRA55_field_time_series(:temperature; kw...) + qa = JRA55_field_time_series(:specific_humidity; kw...) + ra = JRA55_field_time_series(:relative_humidity; kw...) + pa = JRA55_field_time_series(:sea_level_pressure; kw...) + Fra = JRA55_field_time_series(:rain_freshwater_flux; kw...) + Fsn = JRA55_field_time_series(:snow_freshwater_flux; kw...) + Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) + Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) + Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) + Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) times = ua.times @@ -96,4 +649,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); pressure) return atmosphere -end \ No newline at end of file +end + +end # module + diff --git a/src/DataWrangling/abstract_metadata.jl b/src/DataWrangling/abstract_metadata.jl deleted file mode 100644 index e4015ee0..00000000 --- a/src/DataWrangling/abstract_metadata.jl +++ /dev/null @@ -1,179 +0,0 @@ -using CFTime -using Dates -import Dates: year, month, day -import Oceananigans.Fields: set! - -abstract type AbstractMetadata end - -# Ecco field used to set model's initial conditions -struct ECCOMetadata{D} <: AbstractMetadata - name :: Symbol - dates :: D -end - -unprocessed_ecco4_file_prefix = Dict( - :temperature => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), - :salinity => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), -) - -# We always start from 1992 -ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeAllLeap(1992, 1, 1)) -date(data::ECCOMetadata) = DateTimeAllLeap(data.year, data.month, data.day) - -function extract_time_indices(metadata::ECCOMetadata) - dates = metadata.dates - days = dates .- dates[1] - return ceil.(Int, days ./ Day(1) .+ 1) -end - -function date_string(metadata::ECCOMetadata{<:DateTimeAllLeap}) - yearstr = string(Dates.year(metadata.dates)) - monthstr = string(Dates.month(metadata.dates), pad=2) - daystr = string(Dates.day(metadata.dates), pad=2) - return "$(yearstr)-$(monthstr)-$(daystr)" -end - -function file_name(metadata::ECCOMetadata{<:DateTimeAllLeap}) - variable_name = metadata.name - prefix, postfix = unprocessed_ecco4_file_prefix[variable_name] - datestr = date_string(metadata) - return prefix * datestr * postfix -end - -file_name(metadata::ECCOMetadata) = "ecco_$(metadata.name).nc" - -variable_is_three_dimensional(data::ECCOMetadata) = - data.name == :temperature || - data.name == :salinity || - data.name == :u_velocity || - data.name == :v_velocity - -short_name(data::ECCOMetadata) = data.name -field_location(data::ECCOMetadata) = ecco4_location[data.name] - -ecco4_short_names = Dict( - :temperature => "THETA", - :salinity => "SALT", - :u_velocity => "UVEL", - :v_velocity => "VVEL", - :sea_ice_thickness => "SIheff", - :sea_ice_area_fraction => "SIarea" -) - -ecco4_location = Dict( - :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), -) - -ecco4_remote_folder = Dict( - :temperature => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", - :salinity => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", -) - -struct JRA55Metadata{I} <: AbstractMetadata - name :: Symbol - time_indices :: I -end - -# A list of all variables provided in the JRA55 dataset: -JRA55_variable_names = (:river_freshwater_flux, - :rain_freshwater_flux, - :snow_freshwater_flux, - :iceberg_freshwater_flux, - :specific_humidity, - :sea_level_pressure, - :relative_humidity, - :downwelling_longwave_radiation, - :downwelling_shortwave_radiation, - :temperature, - :eastward_velocity, - :northward_velocity) - -extract_time_indices(metadata::JRA55Metadata) = metadata.time_indices - -file_name(metadata::JRA55Metadata) = filenames[metadata.name] -short_name(metadata::JRA55Metadata) = jra55_short_names[metadata.name] -variable_is_three_dimensional(metadata::JRA55Metadata) = false -field_location(::JRA55Metadata) = (Center, Center, Nothing) - -function download_dataset!(metadata::JRA55Metadata) - filename = file_name(metadata) - url = urls[metadata.name] - isfile(filename) || download(url, filename) - return nothing -end - -filenames = Dict( - :river_freshwater_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers - :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall - :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs - :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity - :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure - :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity - :downwelling_longwave_radiation => "RYF.rlds.1990_1991.nc", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "RYF.rsds.1990_1991.nc", # Downwelling shortwave radiation - :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 -) - -jra55_short_names = Dict( - :river_freshwater_flux => "friver", # Freshwater fluxes from rivers - :rain_freshwater_flux => "prra", # Freshwater flux from rainfall - :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "licalvf", # Freshwater flux from calving icebergs - :specific_humidity => "huss", # Surface specific humidity - :sea_level_pressure => "psl", # Sea level pressure - :relative_humidity => "rhuss", # Surface relative humidity - :downwelling_longwave_radiation => "rlds", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "rsds", # Downwelling shortwave radiation - :temperature => "tas", # Near-surface air temperature - :eastward_velocity => "uas", # Eastward near-surface wind - :northward_velocity => "vas", # Northward near-surface wind -) - -urls = Dict( - :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * - "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - - :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/" * - "RYF.prra.1990_1991.nc?rlkey=iifyjm4ppwyd8ztcek4dtx0k8&dl=0", - - :snow_freshwater_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * - "RYF.prsn.1990_1991.nc?rlkey=auyqpwn060cvy4w01a2yskfah&dl=0", - - :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/" * - "RYF.huss.1990_1991.nc?rlkey=107yq04aew8lrmfyorj68v4td&dl=0", - - :sea_level_pressure => "https://www.dropbox.com/scl/fi/0fk332027oru1iiseykgp/" * - "RYF.psl.1990_1991.nc?rlkey=4xpr9uah741483aukok6d7ctt&dl=0", - - :relative_humidity => "https://www.dropbox.com/scl/fi/1agwsp0lzvntuyf8bm9la/" * - "RYF.rhuss.1990_1991.nc?rlkey=8cd0vs7iy1rw58b9pc9t68gtz&dl=0", - - :downwelling_longwave_radiation => "https://www.dropbox.com/scl/fi/y6r62szkirrivua5nqq61/" * - "RYF.rlds.1990_1991.nc?rlkey=wt9yq3cyrvs2rbowoirf4nkum&dl=0", - - :downwelling_shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * - "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - - :temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * - "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", - - :eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * - "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", - - :northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * - "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", -) diff --git a/src/DataWrangling/ecco4_field_time_series.jl b/src/DataWrangling/ecco4_field_time_series.jl new file mode 100644 index 00000000..75eacb4d --- /dev/null +++ b/src/DataWrangling/ecco4_field_time_series.jl @@ -0,0 +1,159 @@ +using Oceananigans.Fields: interpolate! +using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices + +using CUDA: @allowscalar + +using NCDatasets +using JLD2 +using Dates + +import Oceananigans.Fields: set! +import Oceananigans.OutputReaders: new_backend, update_field_time_series! + +struct ECCO4NetCDFBackend <: AbstractInMemoryBackend{Int} + start :: Int + length :: Int +end + +""" + ECCO4NetCDFBackend(length) + +Represents an ECCO4 FieldTimeSeries backed by ECCO4 native .nc files. +""" +ECCO4NetCDFBackend(length) = ECCO4NetCDFBackend(1, length) + +Base.length(backend::ECCO4NetCDFBackend) = backend.length +Base.summary(backend::ECCO4NetCDFBackend) = string("ECCO4NetCDFBackend(", backend.start, ", ", backend.length, ")") + +const ECCO4NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:ECCO4NetCDFBackend} + +new_backend(::ECCO4NetCDFBackend, start, length) = ECCO4NetCDFBackend(start, length) + +function set!(fts::ECCO4NetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts.name) + + backend = fts.backend + start = backend.start + + for t in start:start+length(backend)-1 + + # find the file associated with the time index + metadata = @inbounds path[t] + + arch = architecture(fts) + f = inpainted_ecco4_field(metadata; architecture = arch, maxiter = 10) + set!(fts[t], f) + end + + fill_halo_regions!(fts) + + return nothing +end + +""" + download_dataset!(metadata::ECCOMetadata) + +Download the dataset specified by the given metadata. If the metadata contains a single date, +the dataset is downloaded directly. If the metadata contains multiple dates, the dataset is +downloaded for each date individually. + +# Arguments +- `metadata::ECCOMetadata`: The metadata specifying the dataset to be downloaded. +""" +function download_dataset!(metadata::ECCOMetadata) + + for data in metadata + filename = file_name(data) + + if !isfile(filename) + cmd = `podaac-data-downloader -c $(remote_folder) -d ./ --start-date $(datestr)T00:00:00Z --end-date $(datestr)T00:00:00Z -e .nc` + @info "downloading $(filename) from $(remote_folder)" + try + run(cmd) + catch error + @info "Note: to download ECCO4 data please install podaac-data-downloader using \\ + `pip install podaac`. Provide a username and password to the python environment. \\ + For details about the installation refer to " + throw(ArgumentError("The error is $error")) + end + else + @info "File $(filename) already exists" + end + end + + return nothing +end + +""" + ecco4_times(metadata; start_time = metadata.dates[1]) + +Extracts the time values from the given metadata and calculates the time difference +from the start time. + +# Arguments +- `metadata`: The metadata containing the date information. +- `start_time`: The start time for calculating the time difference. Defaults to the first date in the metadata. + +# Returns +An array of time differences in seconds. +""" +function ecco4_times(metadata; start_time = metadata.dates[1]) + times = [] + for data in metadata + date = data.dates + time = date - start_time + time = Second(time).value + push!(times, time) + end + + return times +end + +""" + ECCO4_field_time_series(variable_name; + architecture = CPU(), + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + backend = InMemory(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + +Return a `FieldTimeSeries` containing oceanic reanalysis data for `variable_name`, +which describes one of the variables in the "ECCO4" dataset. +""" +function ECCO4_field_time_series(metadata::ECCOMetadata; + architecture = CPU(), + backend = ECCO4NetCDFBackend(2), + time_indexing = Cyclical()) + + # ECCO4 data is too chunky to allow other backends + if !(backend isa ECCO4NetCDFBackend) + msg = string("We cannot load the ECCO4 dataset with an $(backend) backend, only ECCO4NetCDFBackend is allowed!") + throw(ArgumentError(msg)) + end + + # Making sure all the required individual files are downloaded + download_dataset!(metadata) + + location = field_location(metadata) + ftmp = empty_ecco4_field(first(metadata); architecture) + shortname = short_name(metadata) + + ECCO4_native_grid = ftmp.grid + boundary_conditions = FieldBoundaryConditions(ECCO4_native_grid, location) + times = ecco4_times(metadata) + + fts = FieldTimeSeries{location...}(ECCO4_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = metadata, + name = shortname) + + # Let's set the data + set!(fts) + + return fts +end \ No newline at end of file diff --git a/src/DataWrangling/ecco4_metadata.jl b/src/DataWrangling/ecco4_metadata.jl new file mode 100644 index 00000000..0c46d4f7 --- /dev/null +++ b/src/DataWrangling/ecco4_metadata.jl @@ -0,0 +1,81 @@ +using CFTime +using Dates +import Dates: year, month, day +import Oceananigans.Fields: set! +import Base + +# Ecco field used to set model's initial conditions +struct ECCOMetadata{D} + name :: Symbol + dates :: D +end + +unprocessed_ecco4_file_prefix = Dict( + :temperature => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), + :salinity => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), +) + +# We always start from 1992 +ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1)) + +# Treat Metadata as an array +Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i]) +Base.length(metadata::ECCOMetadata) = length(metadata.dates) +Base.size(metadata::ECCOMetadata) = size(metadata.dates) +Base.eltype(metadata::ECCOMetadata) = Base.eltype(metadata.dates) +Base.axes(metadata::ECCOMetadata) = Base.axes(metadata.dates) +Base.first(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[1]) +Base.last(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[end]) +Base.iterate(metadata::ECCOMetadata, i=1) = (@inline; (i % UInt) - 1 < length(metadata) ? (@inbounds ECCOMetadata(metadata.name, metadata.dates[i]), i + 1) : nothing) + +Base.axes(metadata::ECCOMetadata{<:AbstractCFDateTime}) = 1 +Base.first(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata +Base.last(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata + +function date_string(metadata::ECCOMetadata{<:AbstractCFDateTime}) + yearstr = string(Dates.year(metadata.dates)) + monthstr = string(Dates.month(metadata.dates), pad=2) + daystr = string(Dates.day(metadata.dates), pad=2) + return "$(yearstr)-$(monthstr)-$(daystr)" +end + +function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime}) + variable_name = metadata.name + prefix, postfix = unprocessed_ecco4_file_prefix[variable_name] + datestr = date_string(metadata) + return prefix * datestr * postfix +end + +# Convenience functions +short_name(data::ECCOMetadata) = ecco4_short_names[data.name] +field_location(data::ECCOMetadata) = ecco4_location[data.name] + +variable_is_three_dimensional(data::ECCOMetadata) = + data.name == :temperature || + data.name == :salinity || + data.name == :u_velocity || + data.name == :v_velocity + + +ecco4_short_names = Dict( + :temperature => "THETA", + :salinity => "SALT", + :u_velocity => "UVEL", + :v_velocity => "VVEL", + :sea_ice_thickness => "SIheff", + :sea_ice_area_fraction => "SIarea" +) + +ecco4_location = Dict( + :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), +) + +ecco4_remote_folder = Dict( + :temperature => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", + :salinity => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", +) \ No newline at end of file diff --git a/src/DataWrangling/inpaint_mask.jl b/src/DataWrangling/inpaint_mask.jl index 3a515994..60f8f53c 100644 --- a/src/DataWrangling/inpaint_mask.jl +++ b/src/DataWrangling/inpaint_mask.jl @@ -51,6 +51,11 @@ function propagating(field, mask, iter, maxiter) return isnan(mask_sum) && iter < maxiter end +@kernel function _fill_nans!(field) + i, j, k = @index(Global, NTuple) + @inbounds field[i, j, k] = ifelse(isnan(field[i, j, k]), 0, field[i, j, k]) +end + """ propagate_horizontally!(field, mask [, tmp_field=deepcopy(field)]; max_iter = Inf) @@ -76,6 +81,8 @@ function propagate_horizontally!(field, mask, tmp_field=deepcopy(field); maxiter @debug "Propagate pass $iter with sum $(sum(parent(field)))" end + launch!(arch, grid, :xyz, _fill_nans!, field) + fill_halo_regions!(field) return field diff --git a/src/DataWrangling/reanalysis_field_time_series.jl b/src/DataWrangling/reanalysis_field_time_series.jl deleted file mode 100644 index 3eaa48b7..00000000 --- a/src/DataWrangling/reanalysis_field_time_series.jl +++ /dev/null @@ -1,474 +0,0 @@ -using Oceananigans -using Oceananigans.Units - -using Oceananigans.Architectures: arch_array -using Oceananigans.DistributedComputations -using Oceananigans.DistributedComputations: child_architecture -using Oceananigans.BoundaryConditions: fill_halo_regions! -using Oceananigans.Grids: λnodes, φnodes, on_architecture -using Oceananigans.Fields: interpolate! -using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices - -using CUDA: @allowscalar - -using NCDatasets -using JLD2 -using Dates - -import Oceananigans.Fields: set! -import Oceananigans.OutputReaders: new_backend, update_field_time_series! -using Downloads: download - -compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing -compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds - -# TODO: remove the allowscalar -function compute_bounding_nodes(::Nothing, grid, LH, hnodes) - hg = hnodes(grid, LH()) - h₁ = @allowscalar minimum(hg) - h₂ = @allowscalar maximum(hg) - return h₁, h₂ -end - -function compute_bounding_indices(::Nothing, hc) - Nh = length(hc) - return 1, Nh -end - -function compute_bounding_indices(bounds, hc) - h₁, h₂ = bounds - Nh = length(hc) - - # The following should work. If ᵒ are the extrema of nodes we want to - # interpolate to, and the following is a sketch of the JRA55 native grid, - # - # 1 2 3 4 5 - # | | | | | | - # | x ᵒ | x | x | x ᵒ | x | - # | | | | | | - # 1 2 3 4 5 6 - # - # then for example, we should find that (iᵢ, i₂) = (1, 5). - # So we want to reduce the first index by one, and limit them - # both by the available data. There could be some mismatch due - # to the use of different coordinate systems (ie whether λ ∈ (0, 360) - # which we may also need to handle separately. - i₁ = searchsortedfirst(hc, h₁) - i₂ = searchsortedfirst(hc, h₂) - i₁ = max(1, i₁ - 1) - i₂ = min(Nh, i₂) - - return i₁, i₂ -end - -infer_longitudinal_topology(::Nothing) = Periodic - -function infer_longitudinal_topology(λbounds) - λ₁, λ₂ = λbounds - TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded - return TX -end - -function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) - λbounds = compute_bounding_nodes(longitude, grid, LX, λnodes) - φbounds = compute_bounding_nodes(latitude, grid, LY, φnodes) - - i₁, i₂ = compute_bounding_indices(λbounds, λc) - j₁, j₂ = compute_bounding_indices(φbounds, φc) - TX = infer_longitudinal_topology(λbounds) - - return i₁, i₂, j₁, j₂, TX -end - -# Convert dates to range until Oceananigans supports dates natively -function fts_times(native_times, start_time=native_times[1]) - 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 NetCDFBackend <: AbstractInMemoryBackend{Int} - start :: Int - length :: Int -end - -""" - NetCDFBackend(length) - -Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. -""" -NetCDFBackend(length) = NetCDFBackend(1, length) - -Base.length(backend::NetCDFBackend) = backend.length -Base.summary(backend::NetCDFBackend) = string("NetCDFBackend(", backend.start, ", ", backend.length, ")") - -const NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:NetCDFBackend} - -function set!(fts::NetCDFFTS, path::String=fts.path, name::String=fts.name) - - ds = Dataset(path) - - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - LX, LY, LZ = location(fts) - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) - - Nz = size(fts, 3) - - ti = time_indices(fts) - ti = collect(ti) - data = Nz == 1 ? ds[name][i₁:i₂, j₁:j₂, ti] : ds[name][i₁:i₂, j₁:j₂, :, ti] - close(ds) - - copyto!(interior(fts), reshape(data, size(fts)...)) - fill_halo_regions!(fts) - - return nothing -end - -new_backend(::NetCDFBackend, start, length) = NetCDFBackend(start, length) - -""" - reanalysis_field_time_series(variable_name; - architecture = CPU(), - location = nothing, - url = nothing, - filename = nothing, - shortname = nothing, - backend = InMemory(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) - -Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, -which describes one of the variables in the "repeat year forcing" dataset derived -from the Japanese 55-year atmospheric reanalysis for driving ocean-sea-ice models (JRA55-do). -For more information about the derivation of the repeat year forcing dataset, see - -"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 `shortname`s used in NetCDF files) -available from the JRA55-do are: - - - `: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 -================= - - - `architecture`: Architecture for the `FieldTimeSeries`. - Default: CPU() - - - `time_indices`: Indices of the timeseries to extract from file. - For example, `time_indices=1:3` returns a - `FieldTimeSeries` with the first three time snapshots - of `variable_name`. - - - `url`: The url accessed to download the data for `variable_name`. - Default: `ClimaOcean.JRA55.urls[variable_name]`. - - - `filename`: The name of the downloaded file. - Default: `ClimaOcean.JRA55.filenames[variable_name]`. - - - `shortname`: The "short name" of `variable_name` inside its NetCDF file. - Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. - - - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. - If it does not exist it will be generated. - - - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is - loaded (not recommended). -""" -function field_time_series_from_metadata(metadata::AbstractMetadata; - architecture = CPU(), - grid = nothing, - location = nothing, - latitude = nothing, - longitude = nothing, - filename = nothing, - backend = InMemory(), - time_indexing = Cyclical(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU()) - - tridimensional_data = variable_is_three_dimensional(metadata) - time_indices = extract_time_indices(metadata) - shortname = short_name(metadata) - - # OnDisk backends do not support time interpolation! - # Disallow OnDisk for JRA55 dataset loading - if backend isa OnDisk - msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") - throw(ArgumentError(msg)) - end - - if !isnothing(filename) && !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 = file_name(metadata)) - - # Record some important user decisions - totally_in_memory = backend isa TotallyInMemory - on_native_grid = isnothing(grid) - !on_native_grid && backend isa NetCDFBackend && error("Can't use custom grid with NetCDFBackend.") - - # Download the necessary data - download_dataset!(metadata) - - # Note, we don't re-use existing jld2 files. - output_filename = "ciao123.jld2" - isfile(output_filename) && rm(output_filename) - - # Determine default time indices - if totally_in_memory - # In this case, the whole time series is in memory. - # Either the time series is short, or we are doing a limited-area - # simulation, like in a single column. So, we conservatively - # set a default `time_indices = 1:2`. - isnothing(time_indices) && (time_indices = 1:2) - time_indices_in_memory = time_indices - native_fts_architecture = architecture - else - # In this case, part or all of the time series will be stored in a file. - # Note: if the user has provided a grid, we will have to preprocess the - # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers - # to the time_indices that we will preprocess; - # by default we choose all of them. The architecture is only the - # architecture used for preprocessing, which typically will be CPU() - # even if we would like the final FieldTimeSeries on the GPU. - isnothing(time_indices) && (time_indices = :) - - if backend isa NetCDFBackend - time_indices_in_memory = 1:length(backend) - native_fts_architecture = architecture - else # then `time_indices_in_memory` refers to preprocessing - maximum_index = min(preprocess_chunk_size, length(time_indices)) - time_indices_in_memory = 1:maximum_index - native_fts_architecture = preprocess_architecture - end - end - - if isnothing(location) - location = field_location(metadata) - end - - ds = Dataset(filename) - - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - - # Interfaces for the "native" JRA55 grid - λn = tridimensional_data ? ds["lon_bnds"][:] : ds["lon_bnds"][1, :] - φn = tridimensional_data ? ds["lat_bnds"][:] : ds["lat_bnds"][1, :] - zr = tridimensional_data ? ds["z_bnds"][:] : nothing - - # The .nc coordinates lon_bnds and lat_bnds do not include - # the last interface, so we push them here. - push!(φn, 90) - push!(λn, λn[1] + 360) - - # TODO: support loading just part of the JRA55 data. - # Probably with arguments that take latitude, longitude bounds. - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, location[1], location[2], λc, φc) - - native_times = ds["time"][time_indices] - - data = tridimensional_data ? ds[shortname][i₁:i₂, j₁:j₂, :, time_indices_in_memory] : ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - λr = λn[i₁:i₂+1] - φr = φn[j₁:j₂+1] - - Nrx, Nry, Nz = size(data) # Nz is the time index if the variable is twodimensional - close(ds) - - native_grid = if tridimensional_data - LatitudeLongitudeGrid(native_fts_architecture, Float32; - halo = (3, 3, 3), - size = (Nrx, Nry, Nz), - longitude = λr, - latitude = φr, - z = zr, - topology = (TX, Bounded, Bounded)) - else - LatitudeLongitudeGrid(native_fts_architecture, Float32; - halo = (3, 3), - size = (Nrx, Nry), - longitude = λr, - latitude = φr, - topology = (TX, Bounded, Flat)) - end - - boundary_conditions = FieldBoundaryConditions(native_grid, location) - times = fts_times(native_times) - - if backend isa NetCDFBackend - fts = FieldTimeSeries{location...}(native_grid, times; - backend, - time_indexing, - boundary_conditions, - path = filename, - name = shortname) - - # Fill the data in a GPU-friendly manner - copyto!(interior(fts), reshape(data, size(fts)...)) - 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{location...}(native_grid, times; - time_indexing, - boundary_conditions) - - # Fill the data in a GPU-friendly manner - copyto!(interior(native_fts), reshape(data, size(native_fts)...)) - fill_halo_regions!(native_fts) - - if on_native_grid && totally_in_memory - return native_fts - - elseif totally_in_memory # but not on the native grid! - boundary_conditions = FieldBoundaryConditions(grid, location) - fts = FieldTimeSeries{location...}(grid, times; time_indexing, boundary_conditions) - interpolate!(fts, native_fts) - return fts - end - end - - @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - - preprocessing_grid = on_native_grid ? native_grid : grid - - # Re-open the dataset! - ds = Dataset(filename) - all_datetimes = ds["time"][time_indices] - all_Nt = length(all_datetimes) - - all_times = fts_times(all_datetimes) - - on_disk_fts = FieldTimeSeries{location...}(preprocessing_grid, all_times; - boundary_conditions, - backend = OnDisk(), - path = jld2_filename, - name = fts_name) - - # Save data to disk, one field at a time - start_clock = time_ns() - n = 1 # on disk - m = 0 # in memory - - times_in_memory = all_times[time_indices_in_memory] - - fts = FieldTimeSeries{location...}(preprocessing_grid, times_in_memory; - boundary_conditions, - backend = InMemory(), - path = jld2_filename, - name = fts_name) - - # Re-compute data - new_data = tridimensional_data ? ds[shortname][i₁:i₂, j₁:j₂, :, time_indices_in_memory] : - ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - - if !on_native_grid - copyto!(interior(native_fts), reshape(new_data, size(native_fts)...)) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts), reshape(new_data, size(fts)...)) - end - - while n <= all_Nt - print(" ... processing time index $n of $all_Nt \r") - - if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory - m += 1 - else # load new data - # Update time_indices - time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size - n₁ = first(time_indices_in_memory) - - # Clip time_indices if they extend past the end of the dataset - if last(time_indices_in_memory) > all_Nt - time_indices_in_memory = UnitRange(n₁, all_Nt) - end - - # Re-compute times - new_times = fts_times(all_times[time_indices_in_memory], all_times[n₁]) - native_fts.times = new_times - - # Re-compute data - new_data = tridimensional_data ? ds[shortname][i₁:i₂, j₁:j₂, :, time_indices_in_memory] : - ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - - fts.times = new_times - - if !on_native_grid - copyto!(interior(native_fts), reshape(new_data, size(native_fts)...)) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts), reshape(new_data, size(fts)...)) - end - - m = 1 # reset - end - - set!(on_disk_fts, fts[m], n, fts.times[m]) - - n += 1 - end - - elapsed = 1e-9 * (time_ns() - start_clock) - elapsed_str = prettytime(elapsed) - @info " ... done ($elapsed_str)" * repeat(" ", 20) - - close(ds) - - user_fts = FieldTimeSeries(jld2_filename, fts_name; architecture, backend, time_indexing) - fill_halo_regions!(user_fts) - - return user_fts -end From 1658b463daca6199fdc5d398cac20f76b9b9ff9d Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 6 May 2024 23:29:28 -0400 Subject: [PATCH 421/716] should work? --- src/DataWrangling/ECCO4.jl | 14 +----- src/DataWrangling/ecco4_field_time_series.jl | 36 +-------------- src/DataWrangling/ecco4_metadata.jl | 47 +++++++++++++++++--- 3 files changed, 44 insertions(+), 53 deletions(-) diff --git a/src/DataWrangling/ECCO4.jl b/src/DataWrangling/ECCO4.jl index 484d4477..19bd91f6 100644 --- a/src/DataWrangling/ECCO4.jl +++ b/src/DataWrangling/ECCO4.jl @@ -141,20 +141,8 @@ function ecco4_field(metadata::ECCOMetadata; variable_name = metadata.name short_name = ecco4_short_names[variable_name] - datestr = date_string(metadata) - if !isfile(filename) - cmd = `podaac-data-downloader -c $(remote_folder) -d ./ --start-date $(datestr)T00:00:00Z --end-date $(datestr)T00:00:00Z -e .nc` - @info "downloading $(filename) from $(remote_folder)" - try - run(cmd) - catch error - @info "Note: to download ECCO4 data please install podaac-data-downloader using \\ - `pip install podaac`. Provide a username and password to the python environment. \\ - For details about the installation refer to " - throw(ArgumentError("The error is $error")) - end - end + download_dataset!(metadata) if user_data isa Nothing ds = Dataset(filename) diff --git a/src/DataWrangling/ecco4_field_time_series.jl b/src/DataWrangling/ecco4_field_time_series.jl index 75eacb4d..ffd5886d 100644 --- a/src/DataWrangling/ecco4_field_time_series.jl +++ b/src/DataWrangling/ecco4_field_time_series.jl @@ -40,7 +40,7 @@ function set!(fts::ECCO4NetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts metadata = @inbounds path[t] arch = architecture(fts) - f = inpainted_ecco4_field(metadata; architecture = arch, maxiter = 10) + f = inpainted_ecco4_field(metadata; architecture = arch, maxiter = 5) set!(fts[t], f) end @@ -49,40 +49,6 @@ function set!(fts::ECCO4NetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts return nothing end -""" - download_dataset!(metadata::ECCOMetadata) - -Download the dataset specified by the given metadata. If the metadata contains a single date, -the dataset is downloaded directly. If the metadata contains multiple dates, the dataset is -downloaded for each date individually. - -# Arguments -- `metadata::ECCOMetadata`: The metadata specifying the dataset to be downloaded. -""" -function download_dataset!(metadata::ECCOMetadata) - - for data in metadata - filename = file_name(data) - - if !isfile(filename) - cmd = `podaac-data-downloader -c $(remote_folder) -d ./ --start-date $(datestr)T00:00:00Z --end-date $(datestr)T00:00:00Z -e .nc` - @info "downloading $(filename) from $(remote_folder)" - try - run(cmd) - catch error - @info "Note: to download ECCO4 data please install podaac-data-downloader using \\ - `pip install podaac`. Provide a username and password to the python environment. \\ - For details about the installation refer to " - throw(ArgumentError("The error is $error")) - end - else - @info "File $(filename) already exists" - end - end - - return nothing -end - """ ecco4_times(metadata; start_time = metadata.dates[1]) diff --git a/src/DataWrangling/ecco4_metadata.jl b/src/DataWrangling/ecco4_metadata.jl index 0c46d4f7..3589b0be 100644 --- a/src/DataWrangling/ecco4_metadata.jl +++ b/src/DataWrangling/ecco4_metadata.jl @@ -4,7 +4,7 @@ import Dates: year, month, day import Oceananigans.Fields: set! import Base -# Ecco field used to set model's initial conditions +# Metadata that holds all the ECCO4 information struct ECCOMetadata{D} name :: Symbol dates :: D @@ -28,9 +28,11 @@ Base.first(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name Base.last(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[end]) Base.iterate(metadata::ECCOMetadata, i=1) = (@inline; (i % UInt) - 1 < length(metadata) ? (@inbounds ECCOMetadata(metadata.name, metadata.dates[i]), i + 1) : nothing) -Base.axes(metadata::ECCOMetadata{<:AbstractCFDateTime}) = 1 -Base.first(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata -Base.last(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata +Base.axes(metadata::ECCOMetadata{<:AbstractCFDateTime}) = 1 +Base.first(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata +Base.last(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata +Base.iterate(metadata::ECCOMetadata{<:AbstractCFDateTime}) = (metadata, nothing) +Base.iterate(::ECCOMetadata{<:AbstractCFDateTime}, ::Any) = nothing function date_string(metadata::ECCOMetadata{<:AbstractCFDateTime}) yearstr = string(Dates.year(metadata.dates)) @@ -78,4 +80,39 @@ ecco4_location = Dict( ecco4_remote_folder = Dict( :temperature => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", :salinity => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", -) \ No newline at end of file +) + +""" + download_dataset!(metadata::ECCOMetadata) + +Download the dataset specified by the given metadata. If the metadata contains a single date, +the dataset is downloaded directly. If the metadata contains multiple dates, the dataset is +downloaded for each date individually. + +# Arguments +- `metadata::ECCOMetadata`: The metadata specifying the dataset to be downloaded. +""" +function download_dataset!(metadata::ECCOMetadata) + + remote_folder = ecco4_remote_folder[metadata.name] + + for data in metadata + datestr = date_string(data) + filename = file_name(data) + + if !isfile(filename) + cmd = `podaac-data-downloader -c $(remote_folder) -d ./ --start-date $(datestr)T00:00:00Z --end-date $(datestr)T00:00:00Z -e .nc` + @info "downloading $(filename) from $(remote_folder)" + try + run(cmd) + catch error + @info "Note: to download ECCO4 data please install podaac-data-downloader using \\ + `pip install podaac`. Provide a username and password to the python environment. \\ + For details about the installation refer to " + throw(ArgumentError("The error is $error")) + end + end + end + + return nothing +end \ No newline at end of file From d65decf32d44fedc0016bf707d07517ae2c62735 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 01:05:48 -0400 Subject: [PATCH 422/716] bunch of changes --- .buildkite/pipeline.yml | 6 +- docs/make.jl | 2 +- docs/src/library/internals.md | 4 +- docs/src/library/public.md | 4 +- examples/freely_decaying_mediterranean.jl | 8 +- examples/inspect_ecco4_data.jl | 26 +- .../freely_decaying_regional_simulation.jl | 8 +- experiments/single_column_omip_simulation.jl | 8 +- .../comparison_to_coare.jl | 16 +- .../ecco4_immersed_grid.jl | 4 +- .../prototype_omip_simulation.jl | 2 +- src/ClimaOcean.jl | 39 ++- src/DataWrangling/DataWrangling.jl | 4 +- src/DataWrangling/ECCO.jl | 288 +++++++++++++++ src/DataWrangling/ECCO4.jl | 331 ------------------ src/DataWrangling/ecco4_field_time_series.jl | 125 ------- src/DataWrangling/ecco_field_time_series.jl | 225 ++++++++++++ .../{ecco4_metadata.jl => ecco_metadata.jl} | 96 ++--- src/DataWrangling/inpaint_mask.jl | 2 +- .../CrossRealmFluxes/CrossRealmFluxes.jl | 20 +- src/OceanSeaIceModels/OceanSeaIceModels.jl | 7 +- test/runtests.jl | 4 +- test/test_ecco.jl | 51 +++ test/test_ecco4.jl | 51 --- 24 files changed, 704 insertions(+), 627 deletions(-) create mode 100644 src/DataWrangling/ECCO.jl delete mode 100644 src/DataWrangling/ECCO4.jl delete mode 100644 src/DataWrangling/ecco4_field_time_series.jl create mode 100644 src/DataWrangling/ecco_field_time_series.jl rename src/DataWrangling/{ecco4_metadata.jl => ecco_metadata.jl} (53%) create mode 100644 test/test_ecco.jl delete mode 100644 test/test_ecco4.jl diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 47e321aa..0fa2e39b 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -31,10 +31,10 @@ steps: commands: - "julia --project -e 'using Pkg; Pkg.test()'" - - label: "Run ECCO4 tests" - key: "tests_ecco4" + - label: "Run ECCO tests" + key: "tests_ecco" env: CUDA_VISIBLE_DEVICES: "-1" - TEST_GROUP: "ecco4" + TEST_GROUP: "ecco" commands: - "julia --project -e 'using Pkg; Pkg.test()'" diff --git a/docs/make.jl b/docs/make.jl index 93f1ad7f..c6378776 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,7 +15,7 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - "inspect_ecco4_data.jl", + "inspect_ecco_data.jl", ] for file in to_be_literated diff --git a/docs/src/library/internals.md b/docs/src/library/internals.md index fa16548a..e04aeeec 100644 --- a/docs/src/library/internals.md +++ b/docs/src/library/internals.md @@ -31,10 +31,10 @@ Modules = [ClimaOcean.DataWrangling] Public = false ``` -## ECCO4 +## ECCO ```@autodocs -Modules = [ClimaOcean.ECCO4] +Modules = [ClimaOcean.ECCO] Public = false ``` diff --git a/docs/src/library/public.md b/docs/src/library/public.md index b0accc8a..13f94c53 100644 --- a/docs/src/library/public.md +++ b/docs/src/library/public.md @@ -32,10 +32,10 @@ Modules = [ClimaOcean.DataWrangling] Private = false ``` -## ECCO4 +## ECCO ```@autodocs -Modules = [ClimaOcean.ECCO4] +Modules = [ClimaOcean.ECCO] Private = false ``` diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index f860f535..2a05e79b 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -2,7 +2,7 @@ using GLMakie using Oceananigans using Oceananigans: architecture using ClimaOcean -using ClimaOcean.ECCO4 +using ClimaOcean.ECCO using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units @@ -70,9 +70,9 @@ model = HydrostaticFreeSurfaceModel(; grid, # Initializing the model # -# the model can be initialized with custom values or with ecco4 fields. -# In this case, our ECCO4 dataset has access to a temperature and a salinity -# field, so we initialize T and S from ECCO4. +# the model can be initialized with custom values or with ecco fields. +# In this case, our ECCO dataset has access to a temperature and a salinity +# field, so we initialize T and S from ECCO. # We initialize our passive tracer with a surface blob near to the coasts of Libia @info "initializing model" libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 diff --git a/examples/inspect_ecco4_data.jl b/examples/inspect_ecco4_data.jl index 30030f02..71ec6609 100644 --- a/examples/inspect_ecco4_data.jl +++ b/examples/inspect_ecco4_data.jl @@ -1,28 +1,28 @@ -# # A quick look at ECCO4 data +# # A quick look at ECCO data # -# ClimaOcean can download and utilize data from the "ECCO4" state estimate, +# ClimaOcean can download and utilize data from the "ECCO" state estimate, # which stands for "Estimating the Circulation and Climate of the Ocean" --- two! # # This script shows how to download three-dimensional temperature and salinity fields -# from ECCO4, and makes a short animation to showcase the fields' content. +# from ECCO, and makes a short animation to showcase the fields' content. # # For this example we need Oceananigans for Field utilities, CairoMakie for plotting # Printf for nice labeling, and of course ClimaOcean to actually download and construct -# the ECCO4 fields. +# the ECCO fields. using Oceananigans using CairoMakie using Printf -using ClimaOcean: ECCO4 +using ClimaOcean: ECCO -# The function `ecco4_field` provided by `ClimaOcean.DataWrangling.ECCO4` will automatically -# download ECCO4 data if it doesn't already exist at the default location. +# The function `ecco_field` provided by `ClimaOcean.DataWrangling.ECCO` will automatically +# download ECCO data if it doesn't already exist at the default location. -T = ECCO4.ecco4_field(:temperature) -S = ECCO4.ecco4_field(:salinity) +T = ECCO.ecco_field(:temperature) +S = ECCO.ecco_field(:salinity) -# Next, we massage the ECCO4 data by inserting NaNs in "land cells", which +# Next, we massage the ECCO data by inserting NaNs in "land cells", which # are diagnosed by having an unphysically low temperature. Tp = parent(T) @@ -30,10 +30,10 @@ Sp = parent(S) Sp[Tp .< -10] .= NaN Tp[Tp .< -10] .= NaN -# # Plotting ECCO4 data +# # Plotting ECCO data # # We're ready to plot. We'll make an animation -# that depicts how the ECCO4 data changes with depth. +# that depicts how the ECCO data changes with depth. fig = Figure(size=(1200, 1400)) @@ -76,7 +76,7 @@ text!(axS, 50, 50, text=depth_str, justification=:center, fontsize=24) stillframes = 10 movingframes = Nz -record(fig, "ECCO4_temperature_salinity.gif", framerate=4) do io +record(fig, "ECCO_temperature_salinity.gif", framerate=4) do io [recordframe!(io) for _ = 1:stillframes] diff --git a/experiments/freely_decaying_regional_simulation.jl b/experiments/freely_decaying_regional_simulation.jl index 172a90cf..6130064e 100644 --- a/experiments/freely_decaying_regional_simulation.jl +++ b/experiments/freely_decaying_regional_simulation.jl @@ -7,7 +7,7 @@ using Oceananigans.Units: Time using ClimaOcean using ClimaOcean.OceanSeaIceModels: Radiation using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere -using ClimaOcean.DataWrangling.ECCO4: ecco4_field +using ClimaOcean.DataWrangling.ECCO: ecco_field # using GLMakie using Printf @@ -21,9 +21,9 @@ arch = CPU() epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) start_seconds = Second(date - epoch).value -Te = ecco4_field(:temperature, date) -Se = ecco4_field(:salinity, date) -# ℋe = ecco4_field(:sea_ice_thickness, date) +Te = ecco_field(:temperature, date) +Se = ecco_field(:salinity, date) +# ℋe = ecco_field(:sea_ice_thickness, date) land = interior(Te) .< -10 interior(Te)[land] .= NaN diff --git a/experiments/single_column_omip_simulation.jl b/experiments/single_column_omip_simulation.jl index 1166e726..af3b05f9 100644 --- a/experiments/single_column_omip_simulation.jl +++ b/experiments/single_column_omip_simulation.jl @@ -4,7 +4,7 @@ using Oceananigans.BuoyancyModels: buoyancy_frequency using Oceananigans.Units: Time using ClimaOcean -using ClimaOcean.DataWrangling.ECCO4: ecco4_column +using ClimaOcean.DataWrangling.ECCO: ecco_column using GLMakie using Printf @@ -28,8 +28,8 @@ start_time = time_ns() epoch = Date(1992, 1, 1) date = Date(1992, 10, 1) start_seconds = Second(date - epoch).value -Tᵢ = ecco4_field(:temperature, date) -Sᵢ = ecco4_field(:salinity, date) +Tᵢ = ecco_field(:temperature, date) +Sᵢ = ecco_field(:salinity, date) elapsed = time_ns() - start_time @info "Initial condition built. " * prettytime(elapsed * 1e-9) @@ -43,7 +43,7 @@ Nz = 80 H = 400 arch = CPU() λ★, φ★ = locations[location] -i★, j★, longitude, latitude = ecco4_column(λ★, φ★) +i★, j★, longitude, latitude = ecco_column(λ★, φ★) grid = LatitudeLongitudeGrid(arch; longitude, latitude, size = (1, 1, Nz), diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index 4c4a4f45..f162d184 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -9,14 +9,14 @@ using Oceananigans.Units using ClimaOcean.DataWrangling: JRA55_prescribed_atmosphere using ClimaOcean.OceanSeaIceModels: Radiation -# Upload ECCO4 fields -# T = DataWrangling.inpainted_ecco4_field(:temperature) -# S = DataWrangling.inpainted_ecco4_field(:salinity) -# u = DataWrangling.inpainted_ecco4_field(:u_velocity) -# v = DataWrangling.inpainted_ecco4_field(:v_velocity) - -# include("ecco4_immersed_grid.jl") -# grid = ecco4_immersed_grid() +# Upload ECCO fields +# T = DataWrangling.inpainted_ecco_field(:temperature) +# S = DataWrangling.inpainted_ecco_field(:salinity) +# u = DataWrangling.inpainted_ecco_field(:u_velocity) +# v = DataWrangling.inpainted_ecco_field(:v_velocity) + +# include("ecco_immersed_grid.jl") +# grid = ecco_immersed_grid() # Let's leave out the radiation for the moment (too simple to test) diff --git a/prototype_omip_simulation/ecco4_immersed_grid.jl b/prototype_omip_simulation/ecco4_immersed_grid.jl index f3de1573..76eb6753 100644 --- a/prototype_omip_simulation/ecco4_immersed_grid.jl +++ b/prototype_omip_simulation/ecco4_immersed_grid.jl @@ -1,7 +1,7 @@ using Oceananigans.Grids: architecture, location, node, with_halo -function ecco4_immersed_grid() - mask = ecco4_center_mask() +function ecco_immersed_grid() + mask = ecco_center_mask() grid = with_halo((3, 3, 3), mask.grid) Nx, Ny, Nz = size(grid) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 72cee915..cc9da97e 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -6,7 +6,7 @@ using OrthogonalSphericalShellGrids using Oceananigans using Oceananigans: architecture using ClimaOcean -using ClimaOcean.ECCO4 +using ClimaOcean.ECCO using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 56782340..24330b36 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -11,13 +11,44 @@ export stretched_vertical_faces, PowerLawStretching, LinearStretching, jra55_field_time_series, - ecco4_field, ECCOMetadata, + ecco_field, ECCOMetadata, initialize! using Oceananigans using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ using DataDeps +using Oceananigans.OutputReaders: GPUAdaptedFieldTimeSeries, FieldTimeSeries + +const SomeKindOfFieldTimeSeries = Union{FieldTimeSeries, + GPUAdaptedFieldTimeSeries} + +const SKOFTS = SomeKindOfFieldTimeSeries + +@inline stateindex(a::Number, i, j, k, args...) = a +@inline stateindex(a::AbstractArray, i, j, k, args...) = @inbounds a[i, j, k] +@inline stateindex(a::SKOFTS, i, j, k, grid, time, args...) = @inbounds a[i, j, k, time] + +@inline function stateindex(a::Function, i, j, k, grid, time, loc) + LX, LY, LZ = loc + λ, φ, z = node(i, j, k, grid, LX(), LY(), LZ()) + + return a(λ, φ, z, time) +end + +@inline function stateindex(a::Tuple, i, j, k, grid, time) + N = length(a) + ntuple(Val(N)) do n + stateindex(a[n], i, j, k, grid, time) + end +end + +@inline function stateindex(a::NamedTuple, i, j, k, grid, time) + vals = stateindex(values(a), i, j, k, grid, time) + names = keys(a) + return NamedTuple{names}(vals) +end + include("OceanSeaIceModels/OceanSeaIceModels.jl") include("VerticalGrids.jl") include("InitialConditions/InitialConditions.jl") @@ -29,13 +60,13 @@ include("OceanSimulations/OceanSimulations.jl") using .VerticalGrids using .Bathymetry using .DataWrangling: JRA55 -using .DataWrangling: ECCO4 +using .DataWrangling: ECCO using .InitialConditions using .OceanSeaIceModels: OceanSeaIceModel using .OceanSimulations -using .DataWrangling: JRA55, ECCO4 +using .DataWrangling: JRA55, ECCO using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend -using ClimaOcean.DataWrangling.ECCO4: ecco4_field +using ClimaOcean.DataWrangling.ECCO: ecco_field using .OceanSeaIceModels: OceanSeaIceModel, Radiation diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index a6a17944..af9ce21c 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -71,9 +71,9 @@ end include("inpaint_mask.jl") include("JRA55.jl") -include("ECCO4.jl") +include("ECCO.jl") using .JRA55 -using .ECCO4 +using .ECCO end # module diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl new file mode 100644 index 00000000..7825bcb5 --- /dev/null +++ b/src/DataWrangling/ECCO.jl @@ -0,0 +1,288 @@ +module ECCO + +export ECCOMetadata, ecco_field, ecco_center_mask, adjusted_ecco_tracers, initialize! + +using ClimaOcean.DataWrangling: inpaint_mask! +using ClimaOcean.InitialConditions: three_dimensional_regrid!, interpolate! + +using Oceananigans +using Oceananigans.Architectures: architecture, child_architecture +using Oceananigans.BoundaryConditions +using Oceananigans.DistributedComputations: DistributedField, all_reduce, barrier! +using Oceananigans.Utils +using KernelAbstractions: @kernel, @index +using NCDatasets +using Downloads: download +using Dates + +include("ecco_metadata.jl") + +import Base + +Base.size(data::ECCOMetadata{<:Any, <:ECCO2}) = (1440, 720, 50, length(data.dates)) +Base.size(data::ECCOMetadata{<:Any, <:ECCO4}) = (720, 360, 50, length(data.dates)) + +# Vertical coordinate +const ECCO_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, +] + +empty_ecco_field(variable_name::Symbol; kw...) = empty_ecco_field(ECCOMetadata(variable_name); kw...) + +function empty_ecco_field(metadata::ECCOMetadata; + architecture = CPU(), + horizontal_halo = (3, 3)) + + Nx, Ny, Nz, _ = size(metadata) + + variable_name = metadata.name + location = field_location(metadata) + + location = ecco_location[variable_name] + + longitude = (0, 360) + latitude = (-90, 90) + TX, TY = (Periodic, Bounded) + + if variable_is_three_dimensional(metadata) + z = ECCO_z + # add vertical halo for 3D fields + halo = (horizontal_halo..., 3) + LZ = Center + TZ = Bounded + N = (Nx, Ny, Nz) + else + z = nothing + halo = horizontal_halo + LZ = Nothing + TZ = Flat + N = (Nx, Ny) + end + + # Flat in z if the variable is two-dimensional + grid = LatitudeLongitudeGrid(architecture; halo, size = N, topology = (TX, TY, TZ), + longitude, latitude, z) + + return Field{location...}(grid) +end + +""" + ecco_field(variable_name; + architecture = CPU(), + horizontal_halo = (1, 1), + user_data = nothing, + url = ecco_urls[variable_name], + filename = ecco_file_names[variable_name], + short_name = ecco_short_names[variable_name]) + +Retrieve the ecco field corresponding to `variable_name`. +The data is either: +(1) retrieved from `filename`, +(2) dowloaded from `url` if `filename` does not exists, +(3) filled from `user_data` if `user_data` is provided. +""" +function ecco_field(metadata::ECCOMetadata; + architecture = CPU(), + horizontal_halo = (3, 3), + filename = file_name(metadata)) + + shortname = short_name(metadata) + + download_dataset!(metadata) + + ds = Dataset(filename) + if variable_is_three_dimensional(metadata) + data = ds[shortname][:, :, :, 1] + # The surface layer in three-dimensional ECCO fields is at `k = 1` + data = reverse(data, dims = 3) + else + data = ds[shortname][:, :, 1] + end + close(ds) + + field = empty_ecco_field(metadata; architecture, horizontal_halo) + + FT = eltype(field) + data[ismissing.(data)] .= 1e10 # Artificially large number! + data = if location(field)[2] == Face + new_data = zeros(FT, size(field)) + new_data[:, 1:end-1, :] .= data + new_data + else + convert.(FT, data) + end + + set!(field, data) + fill_halo_regions!(field) + + return field +end + +@kernel function _set_ecco_mask!(mask, Tᵢ, minimum_value, maximum_value) + i, j, k = @index(Global, NTuple) + @inbounds mask[i, j, k] = (Tᵢ[i, j, k] < minimum_value) | (Tᵢ[i, j, k] > maximum_value) +end + +""" + ecco_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) + +A boolean field where `false` represents a missing value in the ECCO :temperature dataset. +""" +function ecco_center_mask(architecture = CPU(); + minimum_value = Float32(-1e5), + maximum_value = Float32(1e5), + metadata = ECCOMetadata(:temperature), + filename = file_name(metadata)) + + field = ecco_field(metadata; architecture, filename) + mask = CenterField(field.grid, Bool) + + # Set the mask with ones where T is defined + launch!(architecture, field.grid, :xyz, _set_ecco_mask!, mask, field, minimum_value, maximum_value) + + return mask +end + +""" + inpainted_ecco_field(variable_name; + architecture = CPU(), + filename = "./inpainted_ecco_fields.nc", + mask = ecco_center_mask(architecture)) + +Retrieve the ECCO field corresponding to `variable_name` inpainted to fill all the +missing values in the original dataset. + +Arguments: +========== + +- `variable_name`: the variable name corresponding to the Dataset. + +Keyword Arguments: +================== + +- `architecture`: either `CPU()` or `GPU()`. + +- `filename`: the path where to retrieve the data from. If the file does not exist, + the data will be retrived from the ECCO dataset, inpainted, and + saved to `filename`. + +- `mask`: the mask used to inpaint the field (see `inpaint_mask!`). +""" +function inpainted_ecco_field(metadata::ECCOMetadata; + architecture = CPU(), + filename = file_name(metadata), + mask = ecco_center_mask(architecture; filename), + maxiter = Inf, + kw...) + + f = ecco_field(metadata; architecture, filename, kw...) + + # Make sure all values are extended properly + @info "In-painting ecco $(metadata.name)" + inpaint_mask!(f, mask; maxiter) + + fill_halo_regions!(f) + + return f +end + +inpainted_ecco_field(variable_name::Symbol; kw...) = inpainted_ecco_field(ECCOMetadata(variable_name); kw...) + +function set!(field::DistributedField, ecco_metadata::ECCOMetadata; kw...) + # Fields initialized from ECCO + grid = field.grid + arch = architecture(grid) + child_arch = child_architecture(arch) + + f_ecco = if arch.local_rank == 0 # Make sure we read/write the file using only one core + mask = ecco_center_mask(child_arch) + + inpainted_ecco_field(ecco_metadata; mask, + architecture = child_arch, + kw...) + else + empty_ecco_field(ecco_metadata; architecture = child_arch) + end + + barrier!(arch) + + # Distribute ecco field to all workers + parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) + + f_grid = Field(field_location(ecco_metadata), grid) + interpolate!(f_grid, f_ecco) + set!(field, f_grid) + + return field +end + +function set!(field::Field, ecco_metadata::ECCOMetadata; kw...) + + # Fields initialized from ECCO + grid = field.grid + mask = ecco_center_mask(architecture(grid)) + + f = inpainted_ecco_field(ecco_metadata; mask, + architecture = architecture(grid), + kw...) + + f_grid = Field(field_location(ecco_metadata), grid) + interpolate!(f_grid, f) + set!(field, f_grid) + + return field +end + +include("ecco_field_time_series.jl") + +end # Module \ No newline at end of file diff --git a/src/DataWrangling/ECCO4.jl b/src/DataWrangling/ECCO4.jl deleted file mode 100644 index 19bd91f6..00000000 --- a/src/DataWrangling/ECCO4.jl +++ /dev/null @@ -1,331 +0,0 @@ -module ECCO4 - -export ECCOMetadata, ecco4_field, ecco4_center_mask, adjusted_ecco_tracers, initialize! - -using ClimaOcean.DataWrangling: inpaint_mask! -using ClimaOcean.InitialConditions: three_dimensional_regrid!, interpolate! - -using Oceananigans -using Oceananigans.Architectures: architecture, child_architecture -using Oceananigans.BoundaryConditions -using Oceananigans.DistributedComputations: DistributedField, all_reduce, barrier! -using Oceananigans.Utils -using KernelAbstractions: @kernel, @index -using NCDatasets -using Downloads: download -using Dates - -include("ecco4_metadata.jl") - -const ECCO_Nx = 720 -const ECCO_Ny = 360 -const ECCO_Nz = 50 - -# Vertical coordinate -const ECCO_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, -] - -empty_ecco4_field(variable_name::Symbol; kw...) = empty_ecco4_field(ECCOMetadata(variable_name); kw...) - -function empty_ecco4_field(metadata::ECCOMetadata; - Nx = ECCO_Nx, - Ny = ECCO_Ny, - Nz = ECCO_Nz, - z_faces = ECCO_z, - architecture = CPU(), - horizontal_halo = (3, 3)) - - variable_name = metadata.name - location = field_location(metadata) - - location = ecco4_location[variable_name] - - longitude = (0, 360) - latitude = (-90, 90) - TX, TY = (Periodic, Bounded) - - if variable_is_three_dimensional(metadata) - z = z_faces - # add vertical halo for 3D fields - halo = (horizontal_halo..., 3) - LZ = Center - TZ = Bounded - N = (Nx, Ny, Nz) - else - z = nothing - halo = horizontal_halo - LZ = Nothing - TZ = Flat - N = (Nx, Ny) - end - - # Flat in z if the variable is two-dimensional - grid = LatitudeLongitudeGrid(architecture; halo, size = N, topology = (TX, TY, TZ), - longitude, latitude, z) - - return Field{location...}(grid) -end - -""" - ecco4_field(variable_name; - architecture = CPU(), - horizontal_halo = (1, 1), - user_data = nothing, - url = ecco4_urls[variable_name], - filename = ecco4_file_names[variable_name], - short_name = ecco4_short_names[variable_name]) - -Retrieve the ecco4 field corresponding to `variable_name`. -The data is either: -(1) retrieved from `filename`, -(2) dowloaded from `url` if `filename` does not exists, -(3) filled from `user_data` if `user_data` is provided. -""" -function ecco4_field(metadata::ECCOMetadata; - architecture = CPU(), - horizontal_halo = (3, 3), - user_data = nothing, - filename = file_name(metadata), - remote_folder = ecco4_remote_folder[metadata.name]) - - variable_name = metadata.name - short_name = ecco4_short_names[variable_name] - - download_dataset!(metadata) - - if user_data isa Nothing - ds = Dataset(filename) - if variable_is_three_dimensional(metadata) - data = ds[short_name][:, :, :, 1] - # The surface layer in three-dimensional ECCO fields is at `k = 1` - data = reverse(data, dims = 3) - else - data = ds[short_name][:, :, 1] - end - close(ds) - else - data = user_data - end - - field = empty_ecco4_field(metadata; architecture, horizontal_halo) - FT = eltype(field) - data[ismissing.(data)] .= 1e10 # Artificially large number! - data = if location(field)[2] == Face - new_data = zeros(FT, size(field)) - new_data[:, 1:end-1, :] .= data - new_data - else - convert.(FT, data) - end - - set!(field, data) - fill_halo_regions!(field) - - return field -end - -@kernel function _set_ecco4_mask!(mask, Tᵢ, minimum_value, maximum_value) - i, j, k = @index(Global, NTuple) - @inbounds mask[i, j, k] = (Tᵢ[i, j, k] < minimum_value) | (Tᵢ[i, j, k] > maximum_value) -end - -""" - ecco4_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) - -A boolean field where `false` represents a missing value in the ECCO :temperature dataset. -""" -function ecco4_center_mask(architecture = CPU(); - minimum_value = Float32(-1e5), - maximum_value = Float32(1e5), - metadata = ECCOMetadata(:temperature), - filename = file_name(metadata)) - - field = ecco4_field(metadata; architecture, filename) - mask = CenterField(field.grid, Bool) - - # Set the mask with ones where T is defined - launch!(architecture, field.grid, :xyz, _set_ecco4_mask!, mask, field, minimum_value, maximum_value) - - return mask -end - -""" - inpainted_ecco4_field(variable_name; - architecture = CPU(), - filename = "./inpainted_ecco4_fields.nc", - mask = ecco4_center_mask(architecture)) - -Retrieve the ECCO field corresponding to `variable_name` inpainted to fill all the -missing values in the original dataset. - -Arguments: -========== - -- `variable_name`: the variable name corresponding to the Dataset. - -Keyword Arguments: -================== - -- `architecture`: either `CPU()` or `GPU()`. - -- `filename`: the path where to retrieve the data from. If the file does not exist, - the data will be retrived from the ECCO dataset, inpainted, and - saved to `filename`. - -- `mask`: the mask used to inpaint the field (see `inpaint_mask!`). -""" -function inpainted_ecco4_field(metadata::ECCOMetadata; - architecture = CPU(), - inpainted_filename = nothing, - filename = file_name(metadata), - mask = ecco4_center_mask(architecture; filename), - maxiter = Inf, - kw...) - - if isnothing(inpainted_filename) - f = ecco4_field(metadata; architecture, filename, kw...) - - # Make sure all values are extended properly - @info "In-painting ecco $(metadata.name)" - inpaint_mask!(f, mask; maxiter) - - fill_halo_regions!(f) - - elseif !isfile(inpainted_filename) - f = ecco4_field(metadata; architecture, filename, kw...) - - # Make sure all values are extended properly - @info "In-painting ecco $(metadata.name) and saving it in $filename" - inpaint_mask!(f, mask; maxiter) - - fill_halo_regions!(f) - - ds = Dataset(inpainted_filename, "c") - defVar(ds, string(metadata.name), Array(interior(f)), ("lat", "lon", "z")) - - close(ds) - - else - ds = Dataset(inpainted_filename, "a") - - if haskey(ds, string(metadata.name)) - data = ds[metadata.name][:, :, :] - f = ecco4_field(metadata; architecture, filename, user_data = data, kw...) - fill_halo_regions!(f) - else - f = ecco4_field(metadata; architecture, kw...) - # Make sure all values are inpainted properly - @info "In-painting ecco $(metadata.name) and saving it in $filename" - inpaint_mask!(f, mask; maxiter) - fill_halo_regions!(f) - - defVar(ds, string(metadata.name), Array(interior(f)), ("lat", "lon", "z")) - end - - close(ds) - end - - return f -end - -inpainted_ecco4_field(variable_name::Symbol; kw...) = inpainted_ecco4_field(ECCOMetadata(variable_name); kw...) - -function set!(field::DistributedField, ecco4_metadata::ECCOMetadata; filename="./inpainted_ecco4_fields.nc", kw...) - # Fields initialized from ECCO - grid = field.grid - arch = architecture(grid) - child_arch = child_architecture(arch) - - f_ecco = if arch.local_rank == 0 # Make sure we read/write the file using only one core - mask = ecco4_center_mask(child_arch) - - inpainted_ecco4_field(ecco4_metadata; inpainted_filename = filename, mask, - architecture = child_arch, - kw...) - else - empty_ecco4_field(ecco4_metadata; architecture = child_arch) - end - - barrier!(arch) - - # Distribute ecco field to all workers - parent(f_ecco) .= all_reduce(+, parent(f_ecco), arch) - - f_grid = Field(field_location(ecco4_metadata), grid) - interpolate!(f_grid, f_ecco) - set!(field, f_grid) - - return field -end - -function set!(field::Field, ecco4_metadata::ECCOMetadata; filename="./inpainted_ecco4_fields.nc", kw...) - - # Fields initialized from ECCO - grid = field.grid - mask = ecco4_center_mask(architecture(grid)) - - f = inpainted_ecco4_field(ecco4_metadata; inpainted_filename = filename, mask, - architecture = architecture(grid), - kw...) - - f_grid = Field(field_location(ecco4_metadata), grid) - interpolate!(f_grid, f) - set!(field, f_grid) - - return field -end - -include("ecco4_field_time_series.jl") - -end # Module \ No newline at end of file diff --git a/src/DataWrangling/ecco4_field_time_series.jl b/src/DataWrangling/ecco4_field_time_series.jl deleted file mode 100644 index ffd5886d..00000000 --- a/src/DataWrangling/ecco4_field_time_series.jl +++ /dev/null @@ -1,125 +0,0 @@ -using Oceananigans.Fields: interpolate! -using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices - -using CUDA: @allowscalar - -using NCDatasets -using JLD2 -using Dates - -import Oceananigans.Fields: set! -import Oceananigans.OutputReaders: new_backend, update_field_time_series! - -struct ECCO4NetCDFBackend <: AbstractInMemoryBackend{Int} - start :: Int - length :: Int -end - -""" - ECCO4NetCDFBackend(length) - -Represents an ECCO4 FieldTimeSeries backed by ECCO4 native .nc files. -""" -ECCO4NetCDFBackend(length) = ECCO4NetCDFBackend(1, length) - -Base.length(backend::ECCO4NetCDFBackend) = backend.length -Base.summary(backend::ECCO4NetCDFBackend) = string("ECCO4NetCDFBackend(", backend.start, ", ", backend.length, ")") - -const ECCO4NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:ECCO4NetCDFBackend} - -new_backend(::ECCO4NetCDFBackend, start, length) = ECCO4NetCDFBackend(start, length) - -function set!(fts::ECCO4NetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts.name) - - backend = fts.backend - start = backend.start - - for t in start:start+length(backend)-1 - - # find the file associated with the time index - metadata = @inbounds path[t] - - arch = architecture(fts) - f = inpainted_ecco4_field(metadata; architecture = arch, maxiter = 5) - set!(fts[t], f) - end - - fill_halo_regions!(fts) - - return nothing -end - -""" - ecco4_times(metadata; start_time = metadata.dates[1]) - -Extracts the time values from the given metadata and calculates the time difference -from the start time. - -# Arguments -- `metadata`: The metadata containing the date information. -- `start_time`: The start time for calculating the time difference. Defaults to the first date in the metadata. - -# Returns -An array of time differences in seconds. -""" -function ecco4_times(metadata; start_time = metadata.dates[1]) - times = [] - for data in metadata - date = data.dates - time = date - start_time - time = Second(time).value - push!(times, time) - end - - return times -end - -""" - ECCO4_field_time_series(variable_name; - architecture = CPU(), - location = nothing, - url = nothing, - filename = nothing, - shortname = nothing, - backend = InMemory(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) - -Return a `FieldTimeSeries` containing oceanic reanalysis data for `variable_name`, -which describes one of the variables in the "ECCO4" dataset. -""" -function ECCO4_field_time_series(metadata::ECCOMetadata; - architecture = CPU(), - backend = ECCO4NetCDFBackend(2), - time_indexing = Cyclical()) - - # ECCO4 data is too chunky to allow other backends - if !(backend isa ECCO4NetCDFBackend) - msg = string("We cannot load the ECCO4 dataset with an $(backend) backend, only ECCO4NetCDFBackend is allowed!") - throw(ArgumentError(msg)) - end - - # Making sure all the required individual files are downloaded - download_dataset!(metadata) - - location = field_location(metadata) - ftmp = empty_ecco4_field(first(metadata); architecture) - shortname = short_name(metadata) - - ECCO4_native_grid = ftmp.grid - boundary_conditions = FieldBoundaryConditions(ECCO4_native_grid, location) - times = ecco4_times(metadata) - - fts = FieldTimeSeries{location...}(ECCO4_native_grid, times; - backend, - time_indexing, - boundary_conditions, - path = metadata, - name = shortname) - - # Let's set the data - set!(fts) - - return fts -end \ No newline at end of file diff --git a/src/DataWrangling/ecco_field_time_series.jl b/src/DataWrangling/ecco_field_time_series.jl new file mode 100644 index 00000000..a947f9d6 --- /dev/null +++ b/src/DataWrangling/ecco_field_time_series.jl @@ -0,0 +1,225 @@ +using Oceananigans.Units +using Oceananigans.Fields: interpolate! +using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices +using Oceananigans.Utils: Time + +using CUDA: @allowscalar + +using NCDatasets +using JLD2 +using Dates + +using ClimaOcean: stateindex + +import Oceananigans.Fields: set! +import Oceananigans.OutputReaders: new_backend, update_field_time_series! + +struct ECCONetCDFBackend <: AbstractInMemoryBackend{Int} + start :: Int + length :: Int +end + +""" + ECCONetCDFBackend(length) + +Represents an ECCO FieldTimeSeries backed by ECCO native .nc files. +""" +ECCONetCDFBackend(length) = ECCONetCDFBackend(1, length) + +Base.length(backend::ECCONetCDFBackend) = backend.length +Base.summary(backend::ECCONetCDFBackend) = string("ECCONetCDFBackend(", backend.start, ", ", backend.length, ")") + +const ECCONetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:ECCONetCDFBackend} + +new_backend(::ECCONetCDFBackend, start, length) = ECCONetCDFBackend(start, length) + +function set!(fts::ECCONetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts.name) + + backend = fts.backend + start = backend.start + + for t in start:start+length(backend)-1 + + # find the file associated with the time index + metadata = @inbounds path[t] + + arch = architecture(fts) + f = inpainted_ecco_field(metadata; architecture = arch, maxiter = 5) + set!(fts[t], f) + end + + fill_halo_regions!(fts) + + return nothing +end + +""" + ecco_times(metadata; start_time = metadata.dates[1]) + +Extracts the time values from the given metadata and calculates the time difference +from the start time. + +# Arguments +- `metadata`: The metadata containing the date information. +- `start_time`: The start time for calculating the time difference. Defaults to the first date in the metadata. + +# Returns +An array of time differences in seconds. +""" +function ecco_times(metadata; start_time = metadata.dates[1]) + times = [] + for data in metadata + date = data.dates + time = date - start_time + time = Second(time).value + push!(times, time) + end + + return times +end + +""" + ECCO_field_time_series(variable_name; + architecture = CPU(), + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + backend = InMemory(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + +Return a `FieldTimeSeries` containing oceanic reanalysis data for `variable_name`, +which describes one of the variables in the "ECCO" dataset. +""" +function ECCO_field_time_series(metadata::ECCOMetadata; + architecture = CPU(), + backend = ECCONetCDFBackend(2), + time_indexing = Cyclical()) + + # ECCO data is too chunky to allow other backends + if !(backend isa ECCONetCDFBackend) + msg = string("We cannot load the ECCO dataset with an $(backend) backend, only ECCONetCDFBackend is allowed!") + throw(ArgumentError(msg)) + end + + # Making sure all the required individual files are downloaded + download_dataset!(metadata) + + location = field_location(metadata) + ftmp = empty_ecco_field(first(metadata); architecture) + shortname = short_name(metadata) + + ECCO_native_grid = ftmp.grid + boundary_conditions = FieldBoundaryConditions(ECCO_native_grid, location) + times = ecco_times(metadata) + + fts = FieldTimeSeries{location...}(ECCO_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = metadata, + name = shortname) + + # Let's set the data + set!(fts) + + return fts +end + +@inline variable_name(i) = ifelse(i == 1, :T, ifelse(i == 2, :S, ifelse(i == 3, :u, :v))) + +oceananigans_fieldindex = Dict( + :temperature => 1, + :salinity => 2, + :u_velocity => 3, + :v_velocity => 4 +) + +""" + struct ECCORestoring{FTS, I, M, N} + +A struct representing the ECCO forcing function for a specific field. + +## Fields +- `ecco_fts`: The ECCO field time series data. +- `field_idx`: The index of the field. +- `mask`: The mask value. +- `λ`: The timescale. + +""" +struct ECCORestoring{FTS, I, M, N} + ecco_fts :: FTS + field_idx :: I + mask :: M + λ :: N +end + +@inline function (p::ECCORestoring)(i, j, k, grid, clock, fields) + + # Figure out all the inputs: variable name, time, location, and node + var_name = variable_name(p.field_idx) + time = Time(clock.time) + loc = location(p.ecco_fts) + X = node(i, j, k, grid, loc) + + # Extracting the ECCO field time series data + ecco_grid = p.ecco_fts.grid + ecco_data = p.ecco_fts.data + ecco_backend = p.ecco_fts.backend + ecco_time_indexing = p.ecco_fts.time_indexing + + # Extracting the field value at the current node + @inbounds var = getproperty(fields, var_name)[i, j, k] + + # Interpolating the ECCO field time series data + ecco_var = interpolate(X, time, ecco_data, loc, grid, ecco_grid, ecco_backend, ecco_time_indexing) + + # Extracting the mask value at the current node + mask = stateindex(p.mask, i, j, k, grid, clock.time, loc) + + return 1 / p.λ * mask * (ecco_var - var) +end + +""" + ECCO_restoring_forcing(metadata::ECCOMetadata; + architecture = CPU(), + backend = ECCONetCDFBackend(2), + time_indexing = Cyclical(), + mask = 1, + timescale = 5days) + +Create a restoring forcing term for ECCO field time series. + +## Arguments +- `metadata`: The metadata for the ECCO field time series. +- `architecture`: The architecture. +- `backend`: The backend. +- `time_indexing`: The time indexing. +- `mask`: The mask value. +- `timescale`: The timescale. + +## Returns +- The restoring forcing term. + +""" +function ECCO_restoring_forcing(metadata::ECCOMetadata; + architecture = CPU(), + backend = ECCONetCDFBackend(2), + time_indexing = Cyclical(), + mask = 1, + timescale = 5days) + + ecco_fts = ECCO_field_time_series(metadata; architecture, backend, time_indexing) + + variable_name = metadata.name + field_idx = oceananigans_fieldindex[variable_name] + ecco_restoring = ECCORestoring(ecco_fts, field_idx, mask, timescale) + + restoring_forcing = Forcing(ecco_restoring; + discrete_form=true, + parameters=(; ecco_fts, field_idx, mask, λ=timescale)) + + return restoring_forcing +end \ No newline at end of file diff --git a/src/DataWrangling/ecco4_metadata.jl b/src/DataWrangling/ecco_metadata.jl similarity index 53% rename from src/DataWrangling/ecco4_metadata.jl rename to src/DataWrangling/ecco_metadata.jl index 3589b0be..8b2e76a3 100644 --- a/src/DataWrangling/ecco4_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -4,29 +4,28 @@ import Dates: year, month, day import Oceananigans.Fields: set! import Base -# Metadata that holds all the ECCO4 information -struct ECCOMetadata{D} +struct ECCO2 end +struct ECCO4 end + +# Metadata that holds all the ECCO information +struct ECCOMetadata{D, V} name :: Symbol dates :: D + version :: V end -unprocessed_ecco4_file_prefix = Dict( - :temperature => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), - :salinity => ("OCEAN_TEMPERATURE_SALINITY_day_mean_", "_ECCO_V4r4_latlon_0p50deg.nc"), -) - # We always start from 1992 -ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1)) +ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), ECCO4()) # Treat Metadata as an array -Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i]) +Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i], metdata.version) Base.length(metadata::ECCOMetadata) = length(metadata.dates) Base.size(metadata::ECCOMetadata) = size(metadata.dates) Base.eltype(metadata::ECCOMetadata) = Base.eltype(metadata.dates) Base.axes(metadata::ECCOMetadata) = Base.axes(metadata.dates) -Base.first(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[1]) -Base.last(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[end]) -Base.iterate(metadata::ECCOMetadata, i=1) = (@inline; (i % UInt) - 1 < length(metadata) ? (@inbounds ECCOMetadata(metadata.name, metadata.dates[i]), i + 1) : nothing) +Base.first(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[1], metadata.version) +Base.last(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[end], metadata.version) +Base.iterate(metadata::ECCOMetadata, i=1) = (@inline; (i % UInt) - 1 < length(metadata) ? (@inbounds ECCOMetadata(metadata.name, metadata.dates[i], metadata.version), i + 1) : nothing) Base.axes(metadata::ECCOMetadata{<:AbstractCFDateTime}) = 1 Base.first(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata @@ -37,20 +36,24 @@ Base.iterate(::ECCOMetadata{<:AbstractCFDateTime}, ::Any) = nothing function date_string(metadata::ECCOMetadata{<:AbstractCFDateTime}) yearstr = string(Dates.year(metadata.dates)) monthstr = string(Dates.month(metadata.dates), pad=2) - daystr = string(Dates.day(metadata.dates), pad=2) - return "$(yearstr)-$(monthstr)-$(daystr)" + return yearstr, monthstr +end + +function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4}) + shortname = short_name(metadata) + year, month = date_string(metadata) + return shortname * "_" * year * "_" * month * ".nc" end -function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime}) - variable_name = metadata.name - prefix, postfix = unprocessed_ecco4_file_prefix[variable_name] - datestr = date_string(metadata) - return prefix * datestr * postfix +function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO2}) + shortname = short_name(metadata) + year, month = date_string(metadata) + return shortname * "1440x720x50." * year * month * ".nc" end # Convenience functions -short_name(data::ECCOMetadata) = ecco4_short_names[data.name] -field_location(data::ECCOMetadata) = ecco4_location[data.name] +short_name(data::ECCOMetadata) = ecco_short_names[data.name] +field_location(data::ECCOMetadata) = ecco_location[data.name] variable_is_three_dimensional(data::ECCOMetadata) = data.name == :temperature || @@ -58,8 +61,7 @@ variable_is_three_dimensional(data::ECCOMetadata) = data.name == :u_velocity || data.name == :v_velocity - -ecco4_short_names = Dict( +ecco_short_names = Dict( :temperature => "THETA", :salinity => "SALT", :u_velocity => "UVEL", @@ -68,7 +70,7 @@ ecco4_short_names = Dict( :sea_ice_area_fraction => "SIarea" ) -ecco4_location = Dict( +ecco_location = Dict( :temperature => (Center, Center, Center), :salinity => (Center, Center, Center), :sea_ice_thickness => (Center, Center, Nothing), @@ -77,10 +79,8 @@ ecco4_location = Dict( :v_velocity => (Center, Face, Center), ) -ecco4_remote_folder = Dict( - :temperature => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", - :salinity => "ECCO_L4_TEMP_SALINITY_05DEG_DAILY_V4R4", -) +urls(::ECCOMetadata{<:Any, <:ECCO2}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" +urls(::ECCOMetadata{<:Any, <:ECCO4}) = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" """ download_dataset!(metadata::ECCOMetadata) @@ -92,25 +92,31 @@ downloaded for each date individually. # Arguments - `metadata::ECCOMetadata`: The metadata specifying the dataset to be downloaded. """ -function download_dataset!(metadata::ECCOMetadata) - - remote_folder = ecco4_remote_folder[metadata.name] - +function download_dataset!(metadata::ECCOMetadata; + username = get(ENV, "ECCO_USER", nothing), + password = get(ENV, "ECCO_PASSWORD", nothing), + url = urls(metadata)) + + isnothing(username) && throw(ArgumentError("Please provide a username in the ECCO_USER environment variable!")) + isnothing(password) && throw(ArgumentError("Please provide a password in the ECCO_PASSWORD environment variable!")) + for data in metadata - datestr = date_string(data) - filename = file_name(data) - - if !isfile(filename) - cmd = `podaac-data-downloader -c $(remote_folder) -d ./ --start-date $(datestr)T00:00:00Z --end-date $(datestr)T00:00:00Z -e .nc` - @info "downloading $(filename) from $(remote_folder)" - try - run(cmd) - catch error - @info "Note: to download ECCO4 data please install podaac-data-downloader using \\ - `pip install podaac`. Provide a username and password to the python environment. \\ - For details about the installation refer to " - throw(ArgumentError("The error is $error")) + filename = file_name(data) + shortname = short_name(data) + + if !isfile(filename) + + # Version specific dowloand file + if data.version isa ECCO2 + fileurl = joinpath(url, shortname, filename) + elseif data.version isa ECCO4 + year = string(Dates.year(data.dates)) + fileurl = joinpath(url, shortname, year, filename) end + + cmd = `wget --http-user=$(username) --http-passwd=$(password) $(fileurl)` + + run(cmd) end end diff --git a/src/DataWrangling/inpaint_mask.jl b/src/DataWrangling/inpaint_mask.jl index 60f8f53c..330911ac 100644 --- a/src/DataWrangling/inpaint_mask.jl +++ b/src/DataWrangling/inpaint_mask.jl @@ -127,7 +127,7 @@ Arguments - `max_iter`: Maximum iterations for inpainting. Non-Inf values mean that NaN's can occur within the mask. """ -function inpaint_mask!(field, mask; maxiter = Inf) +function inpaint_mask!(field, mask; maxiter = 10) continue_downwards!(field, mask) propagate_horizontally!(field, mask; maxiter) return field diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 6d611451..3721af2f 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -6,33 +6,19 @@ using Adapt export Radiation, OceanSeaIceSurfaceFluxes -using ..OceanSeaIceModels: SKOFTS, default_gravitational_acceleration +using ..OceanSeaIceModels: default_gravitational_acceleration import ..OceanSeaIceModels: surface_velocities, surface_tracers +using ClimaOcean: stateindex + ##### ##### Utilities ##### -@inline stateindex(a::Number, i, j, k, grid, time) = a -@inline stateindex(a::SKOFTS, i, j, k, grid, time) = @inbounds a[i, j, k, time] -@inline stateindex(a::AbstractArray, i, j, k, grid, time) = @inbounds a[i, j, k] @inline Δϕt²(i, j, k, grid, ϕ1, ϕ2, time) = (stateindex(ϕ1, i, j, k, grid, time) - stateindex(ϕ2, i, j, k, grid, time))^2 -@inline function stateindex(a::Tuple, i, j, k, grid, time) - N = length(a) - ntuple(Val(N)) do n - stateindex(a[n], i, j, k, grid, time) - end -end - -@inline function stateindex(a::NamedTuple, i, j, k, grid, time) - vals = stateindex(values(a), i, j, k, grid, 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} diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index b7ff23ea..b4140745 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -15,14 +15,11 @@ using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries using ClimaSeaIce: melting_temperature +using ClimaOcean: stateindex + using KernelAbstractions: @kernel, @index using KernelAbstractions.Extras.LoopInfo: @unroll -const SomeKindOfFieldTimeSeries = Union{FieldTimeSeries, - GPUAdaptedFieldTimeSeries} - -const SKOFTS = SomeKindOfFieldTimeSeries - function surface_velocities end function surface_tracers end function downwelling_radiation end diff --git a/test/runtests.jl b/test/runtests.jl index 3a88eed0..46a453f4 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -9,8 +9,8 @@ if test_group == :jra55 || test_group == :all include("test_jra55.jl") end -if test_group == :ecco4 || test_group == :all - include("test_ecco4.jl") +if test_group == :ecco || test_group == :all + include("test_ecco.jl") end # Tests that we can download JRA55 utilities diff --git a/test/test_ecco.jl b/test/test_ecco.jl new file mode 100644 index 00000000..ce28bc14 --- /dev/null +++ b/test/test_ecco.jl @@ -0,0 +1,51 @@ +include("runtests_setup.jl") + +using ClimaOcean +using ClimaOcean.ECCO +using Oceananigans.Grids: topology + +@testset "ECCO fields utilities" begin + for arch in test_architectures + A = typeof(arch) + @info "Testing ecco_field on $A..." + + temperature_filename = ECCO.ecco_file_names[:temperature] + ecco_temperature = ECCO.ecco_field(:temperature; architecture=arch) + + @test isfile(temperature_filename) + rm(temperature_filename) + + @test ecco_temperature isa Field + @test ecco_temperature.grid isa LatitudeLongitudeGrid + @test topology(ecco_temperature.grid) == (Periodic, Bounded, Bounded) + + Nx, Ny, Nz = size(ecco_temperature) + @test Nx == 1440 + @test Ny == 720 + @test Nz == 50 + + ice_thickness_filename = ECCO.ecco_file_names[:sea_ice_thickness] + ecco_ice_thickness = ECCO.ecco_field(:sea_ice_thickness; architecture=arch) + + @test isfile(ice_thickness_filename) + rm(ice_thickness_filename) + + @test ecco_ice_thickness isa Field + @test ecco_ice_thickness.grid isa LatitudeLongitudeGrid + @test topology(ecco_ice_thickness.grid) == (Periodic, Bounded, Flat) + + Nx, Ny, Nz = size(ecco_ice_thickness) + @test Nx == 1440 + @test Ny == 720 + @test Nz == 1 + end +end + +@testset "setting a field with ECCO" begin + for arch in test_architectures + grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (-5, 5), z = (-200, 0)) + field = CenterField(grid) + set!(field, ECCOMetadata(:temperature)) + set!(field, ECCOMetadata(:salinity)) + end +end diff --git a/test/test_ecco4.jl b/test/test_ecco4.jl deleted file mode 100644 index 54bcd1f9..00000000 --- a/test/test_ecco4.jl +++ /dev/null @@ -1,51 +0,0 @@ -include("runtests_setup.jl") - -using ClimaOcean -using ClimaOcean.ECCO4 -using Oceananigans.Grids: topology - -@testset "ECCO4 fields utilities" begin - for arch in test_architectures - A = typeof(arch) - @info "Testing ecco4_field on $A..." - - temperature_filename = ECCO4.ecco4_file_names[:temperature] - ecco4_temperature = ECCO4.ecco4_field(:temperature; architecture=arch) - - @test isfile(temperature_filename) - rm(temperature_filename) - - @test ecco4_temperature isa Field - @test ecco4_temperature.grid isa LatitudeLongitudeGrid - @test topology(ecco4_temperature.grid) == (Periodic, Bounded, Bounded) - - Nx, Ny, Nz = size(ecco4_temperature) - @test Nx == 1440 - @test Ny == 720 - @test Nz == 50 - - ice_thickness_filename = ECCO4.ecco4_file_names[:sea_ice_thickness] - ecco4_ice_thickness = ECCO4.ecco4_field(:sea_ice_thickness; architecture=arch) - - @test isfile(ice_thickness_filename) - rm(ice_thickness_filename) - - @test ecco4_ice_thickness isa Field - @test ecco4_ice_thickness.grid isa LatitudeLongitudeGrid - @test topology(ecco4_ice_thickness.grid) == (Periodic, Bounded, Flat) - - Nx, Ny, Nz = size(ecco4_ice_thickness) - @test Nx == 1440 - @test Ny == 720 - @test Nz == 1 - end -end - -@testset "setting a field with ECCO4" begin - for arch in test_architectures - grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (-5, 5), z = (-200, 0)) - field = CenterField(grid) - set!(field, ECCOMetadata(:temperature)) - set!(field, ECCOMetadata(:salinity)) - end -end From 95d5dc16e04a31e98fc7c8fe7d790d1eccc3a367 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 01:14:39 -0400 Subject: [PATCH 423/716] changes --- src/DataWrangling/ECCO.jl | 5 ----- src/DataWrangling/ecco_metadata.jl | 12 +++++++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index 7825bcb5..7b2c44e9 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -17,11 +17,6 @@ using Dates include("ecco_metadata.jl") -import Base - -Base.size(data::ECCOMetadata{<:Any, <:ECCO2}) = (1440, 720, 50, length(data.dates)) -Base.size(data::ECCOMetadata{<:Any, <:ECCO4}) = (720, 360, 50, length(data.dates)) - # Vertical coordinate const ECCO_z = [ -6128.75, diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index 8b2e76a3..9cf0aba2 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -17,12 +17,10 @@ end # We always start from 1992 ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), ECCO4()) -# Treat Metadata as an array +# Treat ECCOMetadata as an array Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i], metdata.version) Base.length(metadata::ECCOMetadata) = length(metadata.dates) -Base.size(metadata::ECCOMetadata) = size(metadata.dates) Base.eltype(metadata::ECCOMetadata) = Base.eltype(metadata.dates) -Base.axes(metadata::ECCOMetadata) = Base.axes(metadata.dates) Base.first(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[1], metadata.version) Base.last(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[end], metadata.version) Base.iterate(metadata::ECCOMetadata, i=1) = (@inline; (i % UInt) - 1 < length(metadata) ? (@inbounds ECCOMetadata(metadata.name, metadata.dates[i], metadata.version), i + 1) : nothing) @@ -33,6 +31,9 @@ Base.last(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata Base.iterate(metadata::ECCOMetadata{<:AbstractCFDateTime}) = (metadata, nothing) Base.iterate(::ECCOMetadata{<:AbstractCFDateTime}, ::Any) = nothing +Base.size(data::ECCOMetadata{<:Any, <:ECCO2}) = (1440, 720, 50, length(data.dates)) +Base.size(data::ECCOMetadata{<:Any, <:ECCO4}) = (720, 360, 50, length(data.dates)) + function date_string(metadata::ECCOMetadata{<:AbstractCFDateTime}) yearstr = string(Dates.year(metadata.dates)) monthstr = string(Dates.month(metadata.dates), pad=2) @@ -48,7 +49,8 @@ end function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO2}) shortname = short_name(metadata) year, month = date_string(metadata) - return shortname * "1440x720x50." * year * month * ".nc" + postfix = variable_is_three_dimensional(metadata) ? ".1440x720x50." : ".1440x720." + return shortname * postfix * year * month * ".nc" end # Convenience functions @@ -106,7 +108,7 @@ function download_dataset!(metadata::ECCOMetadata; if !isfile(filename) - # Version specific dowloand file + # Version specific download file url if data.version isa ECCO2 fileurl = joinpath(url, shortname, filename) elseif data.version isa ECCO4 From 199256d4d25572038eb54f6fb5aa529adadad640 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 07:28:28 -0400 Subject: [PATCH 424/716] test stuff --- src/DataWrangling/ecco_field_time_series.jl | 17 +++++---- src/DataWrangling/ecco_metadata.jl | 38 ++++++++++++--------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/DataWrangling/ecco_field_time_series.jl b/src/DataWrangling/ecco_field_time_series.jl index a947f9d6..ca36eb28 100644 --- a/src/DataWrangling/ecco_field_time_series.jl +++ b/src/DataWrangling/ecco_field_time_series.jl @@ -156,6 +156,12 @@ struct ECCORestoring{FTS, I, M, N} λ :: N end +Adapt.adapt_structure(to, p::ECCORestoring) = + ECCORestoring(Adapt.adapt(to, p.ecco_fts), + Adapt.adapt(to, p.field_idx), + Adapt.adapt(to, p.mask), + Adapt.adapt(to, p.λ)) + @inline function (p::ECCORestoring)(i, j, k, grid, clock, fields) # Figure out all the inputs: variable name, time, location, and node @@ -202,14 +208,13 @@ Create a restoring forcing term for ECCO field time series. ## Returns - The restoring forcing term. - """ function ECCO_restoring_forcing(metadata::ECCOMetadata; - architecture = CPU(), - backend = ECCONetCDFBackend(2), - time_indexing = Cyclical(), - mask = 1, - timescale = 5days) + architecture = CPU(), + backend = ECCONetCDFBackend(2), + time_indexing = Cyclical(), + mask = 1, + timescale = 5days) ecco_fts = ECCO_field_time_series(metadata; architecture, backend, time_indexing) diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index 9cf0aba2..edc1ef7b 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -4,8 +4,9 @@ import Dates: year, month, day import Oceananigans.Fields: set! import Base -struct ECCO2 end -struct ECCO4 end +struct ECCO2Monthly end +struct ECCO2Daily end +struct ECCO4Monthly end # Metadata that holds all the ECCO information struct ECCOMetadata{D, V} @@ -34,23 +35,25 @@ Base.iterate(::ECCOMetadata{<:AbstractCFDateTime}, ::Any) = nothing Base.size(data::ECCOMetadata{<:Any, <:ECCO2}) = (1440, 720, 50, length(data.dates)) Base.size(data::ECCOMetadata{<:Any, <:ECCO4}) = (720, 360, 50, length(data.dates)) -function date_string(metadata::ECCOMetadata{<:AbstractCFDateTime}) +function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) + shortname = short_name(metadata) yearstr = string(Dates.year(metadata.dates)) monthstr = string(Dates.month(metadata.dates), pad=2) - return yearstr, monthstr -end - -function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4}) - shortname = short_name(metadata) - year, month = date_string(metadata) - return shortname * "_" * year * "_" * month * ".nc" + return shortname * "_" * yearstr * "_" * monthstr * ".nc" end -function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO2}) +function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime}) shortname = short_name(metadata) - year, month = date_string(metadata) + yearstr = string(Dates.year(metadata.dates)) + monthstr = string(Dates.month(metadata.dates), pad=2) postfix = variable_is_three_dimensional(metadata) ? ".1440x720x50." : ".1440x720." - return shortname * postfix * year * month * ".nc" + + if metadata.version isa ECCO2Monthly + return shortname * postfix * yearstr * monthstr * ".nc" + elseif metadata.version isa ECCO2Daily + daystr = string(Dates.day(metadata.dates), pad=2) + return shortname * postfix * yearstr * monthstr * daystr * ".nc" + end end # Convenience functions @@ -81,8 +84,9 @@ ecco_location = Dict( :v_velocity => (Center, Face, Center), ) -urls(::ECCOMetadata{<:Any, <:ECCO2}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" -urls(::ECCOMetadata{<:Any, <:ECCO4}) = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" +urls(::ECCOMetadata{<:Any, <:ECCO2Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" +urls(::ECCOMetadata{<:Any, <:ECCO2Daily}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/daily/" +urls(::ECCOMetadata{<:Any, <:ECCO4Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" """ download_dataset!(metadata::ECCOMetadata) @@ -109,9 +113,9 @@ function download_dataset!(metadata::ECCOMetadata; if !isfile(filename) # Version specific download file url - if data.version isa ECCO2 + if data.version isa ECCO2Monthly || data.version isa ECCO2Daily fileurl = joinpath(url, shortname, filename) - elseif data.version isa ECCO4 + elseif data.version isa ECCO4Monthly year = string(Dates.year(data.dates)) fileurl = joinpath(url, shortname, year, filename) end From 5dd4dfa883ab7828796c07b6f681a6b66cf7a44d Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 07:34:34 -0400 Subject: [PATCH 425/716] bugfix --- src/DataWrangling/ecco_metadata.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index edc1ef7b..00764c41 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -16,7 +16,7 @@ struct ECCOMetadata{D, V} end # We always start from 1992 -ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), ECCO4()) +ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), ECCO4Monthly()) # Treat ECCOMetadata as an array Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i], metdata.version) @@ -32,8 +32,9 @@ Base.last(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata Base.iterate(metadata::ECCOMetadata{<:AbstractCFDateTime}) = (metadata, nothing) Base.iterate(::ECCOMetadata{<:AbstractCFDateTime}, ::Any) = nothing -Base.size(data::ECCOMetadata{<:Any, <:ECCO2}) = (1440, 720, 50, length(data.dates)) -Base.size(data::ECCOMetadata{<:Any, <:ECCO4}) = (720, 360, 50, length(data.dates)) +Base.size(data::ECCOMetadata{<:Any, <:ECCO2Daily}) = (1440, 720, 50, length(data.dates)) +Base.size(data::ECCOMetadata{<:Any, <:ECCO2Monthly}) = (1440, 720, 50, length(data.dates)) +Base.size(data::ECCOMetadata{<:Any, <:ECCO4Monthly}) = (720, 360, 50, length(data.dates)) function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) shortname = short_name(metadata) @@ -47,7 +48,7 @@ function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime}) yearstr = string(Dates.year(metadata.dates)) monthstr = string(Dates.month(metadata.dates), pad=2) postfix = variable_is_three_dimensional(metadata) ? ".1440x720x50." : ".1440x720." - + if metadata.version isa ECCO2Monthly return shortname * postfix * yearstr * monthstr * ".nc" elseif metadata.version isa ECCO2Daily From 5f2d29f2f53a3e082ca447db39684bb6b6a2fc2e Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 07:38:50 -0400 Subject: [PATCH 426/716] import instead of use --- src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 3721af2f..7fd4d1eb 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -11,7 +11,7 @@ using ..OceanSeaIceModels: default_gravitational_acceleration import ..OceanSeaIceModels: surface_velocities, surface_tracers -using ClimaOcean: stateindex +import ClimaOcean: stateindex ##### ##### Utilities From 2f3814db8196a9b4bc96c243bfa7686cc1115a7a Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 07:40:32 -0400 Subject: [PATCH 427/716] using Adapt --- src/DataWrangling/ECCO.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index 7b2c44e9..dbe1af4c 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -15,6 +15,8 @@ using NCDatasets using Downloads: download using Dates +using Adapt + include("ecco_metadata.jl") # Vertical coordinate From f8bb025e73e7e10cdc4fb006282212fe210bb2da Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 12:14:30 -0400 Subject: [PATCH 428/716] let's try it out! --- .../comparison_to_coare.jl | 25 +++--- ...immersed_grid.jl => ecco_immersed_grid.jl} | 1 + .../prototype_omip_simulation.jl | 12 ++- src/DataWrangling/ECCO.jl | 22 +++--- src/DataWrangling/JRA55.jl | 16 ++-- src/DataWrangling/ecco_metadata.jl | 47 +++++++++-- ...field_time_series.jl => ecco_restoring.jl} | 77 +++++++------------ .../similarity_theory_turbulent_fluxes.jl | 6 +- src/OceanSimulations/OceanSimulations.jl | 2 + 9 files changed, 111 insertions(+), 97 deletions(-) rename prototype_omip_simulation/{ecco4_immersed_grid.jl => ecco_immersed_grid.jl} (91%) rename src/DataWrangling/{ecco_field_time_series.jl => ecco_restoring.jl} (68%) diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index f162d184..7292dcd1 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -6,28 +6,21 @@ using Oceananigans.Operators using ClimaOcean.DataWrangling using ClimaOcean.OceanSimulations using Oceananigans.Units -using ClimaOcean.DataWrangling: JRA55_prescribed_atmosphere +using ClimaOcean.DataWrangling.ECCO: inpainted_ecco_field +using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere using ClimaOcean.OceanSeaIceModels: Radiation # Upload ECCO fields -# T = DataWrangling.inpainted_ecco_field(:temperature) -# S = DataWrangling.inpainted_ecco_field(:salinity) -# u = DataWrangling.inpainted_ecco_field(:u_velocity) -# v = DataWrangling.inpainted_ecco_field(:v_velocity) - -# include("ecco_immersed_grid.jl") -# grid = ecco_immersed_grid() +T = inpainted_ecco_field(:temperature; maxiter = Inf) +S = inpainted_ecco_field(:salinity; maxiter = Inf) +u = inpainted_ecco_field(:u_velocity; maxiter = Inf) +v = inpainted_ecco_field(:v_velocity; maxiter = Inf) +include("ecco_immersed_grid.jl") +grid = ecco_immersed_grid() # Let's leave out the radiation for the moment (too simple to test) -atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory()) #, grid = grid.underlying_grid) - -grid = atmosphere.fields.velocities.u.grid - -T = CenterField(grid) -S = CenterField(grid) -u = XFaceField(grid) -v = YFaceField(grid) +atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory(), grid = grid.underlying_grid) ocean = ocean_simulation(grid; momentum_advection = nothing, tracer_advection = nothing) diff --git a/prototype_omip_simulation/ecco4_immersed_grid.jl b/prototype_omip_simulation/ecco_immersed_grid.jl similarity index 91% rename from prototype_omip_simulation/ecco4_immersed_grid.jl rename to prototype_omip_simulation/ecco_immersed_grid.jl index 76eb6753..6e500aeb 100644 --- a/prototype_omip_simulation/ecco4_immersed_grid.jl +++ b/prototype_omip_simulation/ecco_immersed_grid.jl @@ -1,4 +1,5 @@ using Oceananigans.Grids: architecture, location, node, with_halo +using ClimaOcean.DataWrangling.ECCO: ecco_center_mask function ecco_immersed_grid() mask = ecco_center_mask() diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index cc9da97e..31ebfad8 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -6,7 +6,6 @@ using OrthogonalSphericalShellGrids using Oceananigans using Oceananigans: architecture using ClimaOcean -using ClimaOcean.ECCO using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units @@ -15,7 +14,9 @@ using ClimaOcean.OceanSeaIceModels using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 +using ClimaOcean.ECCO using ClimaOcean.JRA55: NetCDFBackend, JRA55_prescribed_atmosphere +using ClimaOcean.ECCO: ECCO_restoring_forcing using ClimaOcean.Bathymetry include("tripolar_specific_methods.jl") @@ -60,6 +61,15 @@ vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretiz closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) +##### +##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic +##### + +@inline mask(λ, φ, z, t) = φ > 75 | φ < 75 + +FT = ECCO_restoring_forcing + + ocean = ocean_simulation(grid; free_surface, closure) model = ocean.model diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index dbe1af4c..402648d5 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -173,13 +173,13 @@ end """ ecco_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) -A boolean field where `false` represents a missing value in the ECCO :temperature dataset. +A boolean field where `false` represents a missing value in the ECCO dataset. """ function ecco_center_mask(architecture = CPU(); - minimum_value = Float32(-1e5), - maximum_value = Float32(1e5), - metadata = ECCOMetadata(:temperature), - filename = file_name(metadata)) + minimum_value = Float32(-1e5), + maximum_value = Float32(1e5), + metadata = ECCOMetadata(:temperature), + filename = file_name(metadata)) field = ecco_field(metadata; architecture, filename) mask = CenterField(field.grid, Bool) @@ -210,16 +210,18 @@ Keyword Arguments: - `architecture`: either `CPU()` or `GPU()`. - `filename`: the path where to retrieve the data from. If the file does not exist, - the data will be retrived from the ECCO dataset, inpainted, and - saved to `filename`. + the data will be downloaded from the ECCO dataset. - `mask`: the mask used to inpaint the field (see `inpaint_mask!`). + +- `maxiter`: the maximum number of iterations to inpaint the field (see `inpaint_mask!`). + """ function inpainted_ecco_field(metadata::ECCOMetadata; architecture = CPU(), filename = file_name(metadata), - mask = ecco_center_mask(architecture; filename), - maxiter = Inf, + mask = ecco_center_mask(architecture), + maxiter = 10, kw...) f = ecco_field(metadata; architecture, filename, kw...) @@ -280,6 +282,6 @@ function set!(field::Field, ecco_metadata::ECCOMetadata; kw...) return field end -include("ecco_field_time_series.jl") +include("ecco_restoring.jl") end # Module \ No newline at end of file diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index acafa58c..e5944cb2 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -187,16 +187,14 @@ function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) end # Convert dates to range until Oceananigans supports dates natively -function jra55_times(native_times, start_time=DateTimeProlepticGregorian(1900, 01, 01)) - Nt = length(native_times) - Δt = native_times[2] - native_times[1] # assume all times are equispaced - Δt = Second(Δt).value +function jra55_times(native_times, start_time=native_times[1]) - 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 + times = [] + for native_time in native_times + time = native_time - start_time + time = Second(time).value + push!(times, time) + end return times end diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index 00764c41..f4f5ba71 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -8,17 +8,20 @@ struct ECCO2Monthly end struct ECCO2Daily end struct ECCO4Monthly end -# Metadata that holds all the ECCO information +# Metadata holding the ECCO dataset information: +# - `name`: The name of the dataset. +# - `dates`: The dates of the dataset, in a `AbstractCFDateTime` format. +# - `version`: The version of the dataset, could be ECCO2Monthly, ECCO2Daily, or ECCO4Monthly. struct ECCOMetadata{D, V} name :: Symbol dates :: D version :: V end -# We always start from 1992 +# The default is the ECCO4Monthly dataset at 1992-01-01. ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), ECCO4Monthly()) -# Treat ECCOMetadata as an array +# Treat ECCOMetadata as an array to allow iteration over the dates. Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i], metdata.version) Base.length(metadata::ECCOMetadata) = length(metadata.dates) Base.eltype(metadata::ECCOMetadata) = Base.eltype(metadata.dates) @@ -36,6 +39,16 @@ Base.size(data::ECCOMetadata{<:Any, <:ECCO2Daily}) = (1440, 720, 50, length(da Base.size(data::ECCOMetadata{<:Any, <:ECCO2Monthly}) = (1440, 720, 50, length(data.dates)) Base.size(data::ECCOMetadata{<:Any, <:ECCO4Monthly}) = (720, 360, 50, length(data.dates)) +Base.size(::ECCOMetadata{<:AbstractCFDateTime, <:ECCO2Daily}) = (1440, 720, 50, 1) +Base.size(::ECCOMetadata{<:AbstractCFDateTime, <:ECCO2Monthly}) = (1440, 720, 50, 1) +Base.size(::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) = (720, 360, 50, 1) + +# The whole range of dates in the different dataset versions +all_ecco_dates(::ECCO4Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) +all_ecco_dates(::ECCO2Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) +all_ecco_dates(::ECCO2Daily) = DateTimeProlepticGregorian(1992, 1, 4) : Day(1) : DateTimeProlepticGregorian(2023, 12, 31) + +# File name generation specific to each Dataset version function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) shortname = short_name(metadata) yearstr = string(Dates.year(metadata.dates)) @@ -58,7 +71,10 @@ function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime}) end # Convenience functions -short_name(data::ECCOMetadata) = ecco_short_names[data.name] +short_name(data::ECCOMetadata{<:Any, <:ECCO2Daily}) = ecco2_short_names[data.name] +short_name(data::ECCOMetadata{<:Any, <:ECCO2Monthly}) = ecco2_short_names[data.name] +short_name(data::ECCOMetadata{<:Any, <:ECCO4Monthly}) = ecco4_short_names[data.name] + field_location(data::ECCOMetadata) = ecco_location[data.name] variable_is_three_dimensional(data::ECCOMetadata) = @@ -67,7 +83,16 @@ variable_is_three_dimensional(data::ECCOMetadata) = data.name == :u_velocity || data.name == :v_velocity -ecco_short_names = Dict( +ecco4_short_names = Dict( + :temperature => "THETA", + :salinity => "SALT", + :u_velocity => "EVEL", + :v_velocity => "NVEL", + :sea_ice_thickness => "SIheff", + :sea_ice_area_fraction => "SIarea" +) + +ecco2_short_names = Dict( :temperature => "THETA", :salinity => "SALT", :u_velocity => "UVEL", @@ -85,6 +110,7 @@ ecco_location = Dict( :v_velocity => (Center, Face, Center), ) +# URLs for the ECCO datasets specific to each version urls(::ECCOMetadata{<:Any, <:ECCO2Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" urls(::ECCOMetadata{<:Any, <:ECCO2Daily}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/daily/" urls(::ECCOMetadata{<:Any, <:ECCO4Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" @@ -94,17 +120,22 @@ urls(::ECCOMetadata{<:Any, <:ECCO4Monthly}) = "https://ecco.jpl.nasa.gov/drive/f Download the dataset specified by the given metadata. If the metadata contains a single date, the dataset is downloaded directly. If the metadata contains multiple dates, the dataset is -downloaded for each date individually. +downloaded for each date individually. +The data download requires a username and password to be provided in the ECCO_USERNAME and ECCO_PASSWORD +environment variables. This can be done by exporting the environment variables in the shell before running the script, +or by launching julia with + +ECCO_USERNAME=myuser ECCO_PASSWORD=mypasswrd julia # Arguments - `metadata::ECCOMetadata`: The metadata specifying the dataset to be downloaded. """ function download_dataset!(metadata::ECCOMetadata; - username = get(ENV, "ECCO_USER", nothing), + username = get(ENV, "ECCO_USERNAME", nothing), password = get(ENV, "ECCO_PASSWORD", nothing), url = urls(metadata)) - isnothing(username) && throw(ArgumentError("Please provide a username in the ECCO_USER environment variable!")) + isnothing(username) && throw(ArgumentError("Please provide a username in the ECCO_USERNAME environment variable!")) isnothing(password) && throw(ArgumentError("Please provide a password in the ECCO_PASSWORD environment variable!")) for data in metadata diff --git a/src/DataWrangling/ecco_field_time_series.jl b/src/DataWrangling/ecco_restoring.jl similarity index 68% rename from src/DataWrangling/ecco_field_time_series.jl rename to src/DataWrangling/ecco_restoring.jl index ca36eb28..64f0b2ab 100644 --- a/src/DataWrangling/ecco_field_time_series.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -23,6 +23,7 @@ end ECCONetCDFBackend(length) Represents an ECCO FieldTimeSeries backed by ECCO native .nc files. +Each time instance is stored in an individual file. """ ECCONetCDFBackend(length) = ECCONetCDFBackend(1, length) @@ -66,7 +67,7 @@ from the start time. # Returns An array of time differences in seconds. """ -function ecco_times(metadata; start_time = metadata.dates[1]) +function ecco_times(metadata; start_time = first(metadata).dates) times = [] for data in metadata date = data.dates @@ -79,56 +80,30 @@ function ecco_times(metadata; start_time = metadata.dates[1]) end """ - ECCO_field_time_series(variable_name; + ECCO_field_time_series(metadata::ECCOMetadata; architecture = CPU(), - location = nothing, - url = nothing, - filename = nothing, - shortname = nothing, - backend = InMemory(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) - -Return a `FieldTimeSeries` containing oceanic reanalysis data for `variable_name`, -which describes one of the variables in the "ECCO" dataset. -""" -function ECCO_field_time_series(metadata::ECCOMetadata; - architecture = CPU(), - backend = ECCONetCDFBackend(2), - time_indexing = Cyclical()) - - # ECCO data is too chunky to allow other backends - if !(backend isa ECCONetCDFBackend) - msg = string("We cannot load the ECCO dataset with an $(backend) backend, only ECCONetCDFBackend is allowed!") - throw(ArgumentError(msg)) - end + time_indices_in_memory = 2, + time_indexing = Cyclical()) - # Making sure all the required individual files are downloaded - download_dataset!(metadata) +Create a field time series object for ECCO data. - location = field_location(metadata) - ftmp = empty_ecco_field(first(metadata); architecture) - shortname = short_name(metadata) +Args: +- metadata: An ECCOMetadata object containing information about the ECCO dataset. +- architecture: The architecture to use for computations (default: CPU()). +- time_indices_in_memory: The number of time indices to keep in memory (default: 2). +- time_indexing: The time indexing scheme to use (default: Cyclical()). - ECCO_native_grid = ftmp.grid - boundary_conditions = FieldBoundaryConditions(ECCO_native_grid, location) - times = ecco_times(metadata) - - fts = FieldTimeSeries{location...}(ECCO_native_grid, times; - backend, - time_indexing, - boundary_conditions, - path = metadata, - name = shortname) - - # Let's set the data - set!(fts) - - return fts -end +Returns: +- fts: A FieldTimeSeries object representing the ECCO field time series. + +Example: +``` +metadata = ECCOMetadata(...) +fts = ECCO_field_time_series(metadata) +``` +""" -@inline variable_name(i) = ifelse(i == 1, :T, ifelse(i == 2, :S, ifelse(i == 3, :u, :v))) +@inline variable_name_from_index(i) = ifelse(i == 1, :T, ifelse(i == 2, :S, ifelse(i == 3, :u, :v))) oceananigans_fieldindex = Dict( :temperature => 1, @@ -165,12 +140,12 @@ Adapt.adapt_structure(to, p::ECCORestoring) = @inline function (p::ECCORestoring)(i, j, k, grid, clock, fields) # Figure out all the inputs: variable name, time, location, and node - var_name = variable_name(p.field_idx) + var_name = variable_name_from_index(p.field_idx) time = Time(clock.time) loc = location(p.ecco_fts) X = node(i, j, k, grid, loc) - # Extracting the ECCO field time series data + # Extracting the ECCO field time series data and parameters ecco_grid = p.ecco_fts.grid ecco_data = p.ecco_fts.data ecco_backend = p.ecco_fts.backend @@ -179,7 +154,7 @@ Adapt.adapt_structure(to, p::ECCORestoring) = # Extracting the field value at the current node @inbounds var = getproperty(fields, var_name)[i, j, k] - # Interpolating the ECCO field time series data + # Interpolating the ECCO field time series data ont the current node and time ecco_var = interpolate(X, time, ecco_data, loc, grid, ecco_grid, ecco_backend, ecco_time_indexing) # Extracting the mask value at the current node @@ -211,12 +186,12 @@ Create a restoring forcing term for ECCO field time series. """ function ECCO_restoring_forcing(metadata::ECCOMetadata; architecture = CPU(), - backend = ECCONetCDFBackend(2), + time_indices_in_memory = 2, time_indexing = Cyclical(), mask = 1, timescale = 5days) - ecco_fts = ECCO_field_time_series(metadata; architecture, backend, time_indexing) + ecco_fts = ECCO_field_time_series(metadata; architecture, time_indices_in_memory, time_indexing) variable_name = metadata.name field_idx = oceananigans_fieldindex[variable_name] diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 2b14d122..4150875b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -251,6 +251,8 @@ end Δq = differences.q h = differences.h + FT = eltype(h) + g = gravitational_acceleration ϰ = von_karman_constant @@ -259,8 +261,8 @@ end β = similarity_theory.gustiness_parameter zᵢ = atmos_boundary_layer_height - hᵢ = convert(eltype(h), 10) # Reference Initial height == 10 meters - ℓuᵢ = convert(eltype(h), 1e-4) # Initial roughness length == 1e-4 meters + hᵢ = convert(FT, 10) # Reference Initial height == 10 meters + ℓuᵢ = convert(FT, 1e-4) # Initial roughness length == 1e-4 meters # assuming the initial gustiness is `0.5` ms⁻¹ uτ = sqrt(Δu^2 + Δv^2 + convert(FT, 0.25)) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 0545ae4f..ad80770f 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -2,6 +2,7 @@ module OceanSimulations export load_balanced_regional_grid, ocean_simulation +using Oceananigans using Oceananigans.Units using Oceananigans.Advection: TracerAdvection using Oceananigans.Coriolis: ActiveCellEnstrophyConserving @@ -61,6 +62,7 @@ function ocean_simulation(grid; Δt = 5minutes, rotation_rate = Ω_Earth, gravitational_acceleration = g_Earth, drag_coefficient = 0.003, + forcing = NamedTuple(), momentum_advection = default_momentum_advection(), tracer_advection = default_tracer_advection(), verbose = false) From 4a7a594f1a2f4497cb6bfa4fe3f9b0695a9c0b4b Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 12:17:14 -0400 Subject: [PATCH 429/716] bugfix --- src/DataWrangling/ecco_restoring.jl | 5 +++++ .../CrossRealmFluxes/stability_functions.jl | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 64f0b2ab..b6eb28dd 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -184,6 +184,11 @@ Create a restoring forcing term for ECCO field time series. ## Returns - The restoring forcing term. """ +function ECCO_restoring_forcing(variable_name::Symbol, version=ECCO4Monthly(); kw...) + metadata = ECCOMetadata(variable_name, all_ecco_dates(version), version) + return ECCO_restoring_forcing(metadata; kw...) +end + function ECCO_restoring_forcing(metadata::ECCOMetadata; architecture = CPU(), time_indices_in_memory = 2, diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index 8fe9351f..8769f68d 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -33,7 +33,7 @@ function default_stability_functions(FT = Float64) end @inline function (ψ::InitialMomentumStabilityFunction)(ζ) - FT = elype(ζ) + FT = eltype(ζ) # Parameters p₁ = convert(FT, 0.35) @@ -57,7 +57,7 @@ end end @inline function (ψ::MomentumStabilityFunction)(ζ) - FT = elype(ζ) + FT = eltype(ζ) # Parameters p₁ = convert(FT, 0.35) @@ -83,7 +83,7 @@ end end @inline function (ψ::ScalarStabilityFunction)(ζ) - FT = elype(ζ) + FT = eltype(ζ) # Parameters p₁ = convert(FT, 0.35) From 1d7522f54d8627b1804104395f60a5faead8fb23 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 12:21:53 -0400 Subject: [PATCH 430/716] some bugfixes --- .../similarity_theory_turbulent_fluxes.jl | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 4150875b..022b846c 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -29,7 +29,7 @@ import SurfaceFluxes.Parameters: ##### Bulk turbulent fluxes based on similarity theory ##### -struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, F} <: AbstractSurfaceFluxesParameters +struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, I, F} <: AbstractSurfaceFluxesParameters gravitational_acceleration :: FT von_karman_constant :: FT turbulent_prandtl_number :: FT @@ -43,7 +43,7 @@ struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, F} <: Abstract bulk_velocity :: V tolerance :: FT maxiter :: Int - iteration :: Int + iteration :: I fields :: F end @@ -133,7 +133,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; bulk_velocity, convert(FT, tolerance), maxiter, - 0, + Ref(0), fields) end @@ -191,11 +191,11 @@ end # The inital velocity scale assumes that # the gustiness velocity `uᴳ` is equal to 0.5 ms⁻¹. # That will be refined later on. - uτ = sqrt(Δu^2 + Δv^2 + convert(FT, 0.25)) + uτ = sqrt(Δu^2 + Δv^2 + convert(eltype(Δh), 0.25)) while iterating(Σ★ - Σ₀, similarity_theory) Σ₀ = Σ★ - similarity_theory.iteration += 1 + similarity_theory.iteration[] += 1 Σ★, uτ, = refine_characteristic_scales(Σ★, uτ, similarity_theory, surface_state, @@ -210,6 +210,8 @@ end θ★ = Σ★.temperature q★ = Σ★.water_vapor + similarity_theory.iteration[] = 0 + # `u★² ≡ sqrt(τx² + τy²)` # We remove the gustiness by dividing by `uτ` τx = - u★^2 * Δu / uτ From 754e8b9d34aeb779572c88a384c39c3123df3456 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 12:22:11 -0400 Subject: [PATCH 431/716] some other changes --- .../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 022b846c..a82b5693 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -235,7 +235,7 @@ end # Iterating condition for the characteristic scales solvers @inline function iterating(Σ★, solver) - solver.iteration >= solver.maxiter && return false + solver.iteration[] >= solver.maxiter && return false norm(Σ★) <= solver.tolerance && return false return true end From 067677c752ecf0b3ced43060c6114680b55d5645 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 16:23:49 -0400 Subject: [PATCH 432/716] correction --- .../comparison_to_coare.jl | 6 +- .../ecco_immersed_grid.jl | 6 +- src/DataWrangling/ECCO.jl | 61 +++++++++++++------ src/DataWrangling/ecco_metadata.jl | 4 +- 4 files changed, 50 insertions(+), 27 deletions(-) diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index 7292dcd1..4a1eed22 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -6,9 +6,11 @@ using Oceananigans.Operators using ClimaOcean.DataWrangling using ClimaOcean.OceanSimulations using Oceananigans.Units -using ClimaOcean.DataWrangling.ECCO: inpainted_ecco_field +using ClimaOcean.DataWrangling.ECCO +using ClimaOcean.DataWrangling.ECCO: inpainted_ecco_field, ECCO2Daily, ECCO4Monthly using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere using ClimaOcean.OceanSeaIceModels: Radiation +using CFTime # Upload ECCO fields T = inpainted_ecco_field(:temperature; maxiter = Inf) @@ -17,7 +19,7 @@ u = inpainted_ecco_field(:u_velocity; maxiter = Inf) v = inpainted_ecco_field(:v_velocity; maxiter = Inf) include("ecco_immersed_grid.jl") -grid = ecco_immersed_grid() +grid = ecco_immersed_grid(metadata) # Let's leave out the radiation for the moment (too simple to test) atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory(), grid = grid.underlying_grid) diff --git a/prototype_omip_simulation/ecco_immersed_grid.jl b/prototype_omip_simulation/ecco_immersed_grid.jl index 6e500aeb..0ad2408c 100644 --- a/prototype_omip_simulation/ecco_immersed_grid.jl +++ b/prototype_omip_simulation/ecco_immersed_grid.jl @@ -1,8 +1,8 @@ using Oceananigans.Grids: architecture, location, node, with_halo -using ClimaOcean.DataWrangling.ECCO: ecco_center_mask +using ClimaOcean.DataWrangling.ECCO: ecco_mask -function ecco_immersed_grid() - mask = ecco_center_mask() +function ecco_immersed_grid(metadata) + mask = ecco_mask(; metadata) grid = with_halo((3, 3, 3), mask.grid) Nx, Ny, Nz = size(grid) diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index 402648d5..7a0f6dd3 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -1,6 +1,6 @@ module ECCO -export ECCOMetadata, ecco_field, ecco_center_mask, adjusted_ecco_tracers, initialize! +export ECCOMetadata, ecco_field, ecco_mask, adjusted_ecco_tracers, initialize! using ClimaOcean.DataWrangling: inpaint_mask! using ClimaOcean.InitialConditions: three_dimensional_regrid!, interpolate! @@ -158,6 +158,14 @@ function ecco_field(metadata::ECCOMetadata; else convert.(FT, data) end + + # ECCO4 data is on a -180, 180 longitude grid as opposed to ECCO2 data that + # is on a 0, 360 longitude grid. To make the data consistent, we shift ECCO4 + # data by 180 degrees in longitude + if metadata.version isa ECCO4Monthly + Nx = size(data, 1) + data = circshift(data, (Nx ÷ 2, 0, 0)) + end set!(field, data) fill_halo_regions!(field) @@ -165,27 +173,38 @@ function ecco_field(metadata::ECCOMetadata; return field end -@kernel function _set_ecco_mask!(mask, Tᵢ, minimum_value, maximum_value) +@kernel function _set_ecco2_mask!(mask, Tᵢ, minimum_value, maximum_value) i, j, k = @index(Global, NTuple) @inbounds mask[i, j, k] = (Tᵢ[i, j, k] < minimum_value) | (Tᵢ[i, j, k] > maximum_value) end +@kernel function _set_ecco4_mask!(mask, Tᵢ, args...) + i, j, k = @index(Global, NTuple) + @inbounds mask[i, j, k] = (Tᵢ[i, j, k] == 0) +end + +@inline mask_kernel(version) = _set_ecco2_mask! +@inline mask_kernel(::ECCO4Monthly) = _set_ecco4_mask! + """ - ecco_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) + ecco_mask(architecture = CPU(); minimum_value = Float32(-1e5)) -A boolean field where `false` represents a missing value in the ECCO dataset. +A boolean field where `true` represents a missing value in the ECCO dataset. """ -function ecco_center_mask(architecture = CPU(); - minimum_value = Float32(-1e5), - maximum_value = Float32(1e5), - metadata = ECCOMetadata(:temperature), - filename = file_name(metadata)) +function ecco_mask(metadata, architecture = CPU(); + minimum_value = Float32(-1e5), + maximum_value = Float32(1e5), + filename = file_name(metadata)) field = ecco_field(metadata; architecture, filename) - mask = CenterField(field.grid, Bool) + mask = Field{location(field)...}(field.grid, Bool) + + # ECCO4 has zeros in place of the missing values, while + # ECCO2 expresses missing values with values < -1e5 + _set_mask! = mask_kernel(metadata.version) - # Set the mask with ones where T is defined - launch!(architecture, field.grid, :xyz, _set_ecco_mask!, mask, field, minimum_value, maximum_value) + # Set the mask with zeros where field is defined + launch!(architecture, field.grid, :xyz, _set_mask!, mask, field, minimum_value, maximum_value) return mask end @@ -194,7 +213,7 @@ end inpainted_ecco_field(variable_name; architecture = CPU(), filename = "./inpainted_ecco_fields.nc", - mask = ecco_center_mask(architecture)) + mask = ecco_mask(architecture)) Retrieve the ECCO field corresponding to `variable_name` inpainted to fill all the missing values in the original dataset. @@ -220,12 +239,14 @@ Keyword Arguments: function inpainted_ecco_field(metadata::ECCOMetadata; architecture = CPU(), filename = file_name(metadata), - mask = ecco_center_mask(architecture), - maxiter = 10, + mask = ecco_mask(metadata, architecture), + maxiter = 20, kw...) f = ecco_field(metadata; architecture, filename, kw...) - + + @show maxiter + # Make sure all values are extended properly @info "In-painting ecco $(metadata.name)" inpaint_mask!(f, mask; maxiter) @@ -244,11 +265,11 @@ function set!(field::DistributedField, ecco_metadata::ECCOMetadata; kw...) child_arch = child_architecture(arch) f_ecco = if arch.local_rank == 0 # Make sure we read/write the file using only one core - mask = ecco_center_mask(child_arch) + mask = ecco_mask(ecco_metadata, child_arch) inpainted_ecco_field(ecco_metadata; mask, - architecture = child_arch, - kw...) + architecture = child_arch, + kw...) else empty_ecco_field(ecco_metadata; architecture = child_arch) end @@ -269,7 +290,7 @@ function set!(field::Field, ecco_metadata::ECCOMetadata; kw...) # Fields initialized from ECCO grid = field.grid - mask = ecco_center_mask(architecture(grid)) + mask = ecco_mask(ecco_metadata, architecture(grid)) f = inpainted_ecco_field(ecco_metadata; mask, architecture = architecture(grid), diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index f4f5ba71..7634a252 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -19,7 +19,7 @@ struct ECCOMetadata{D, V} end # The default is the ECCO4Monthly dataset at 1992-01-01. -ECCOMetadata(name::Symbol) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), ECCO4Monthly()) +ECCOMetadata(name::Symbol; version = ECCO4Monthly()) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), version) # Treat ECCOMetadata as an array to allow iteration over the dates. Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i], metdata.version) @@ -46,7 +46,7 @@ Base.size(::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) = (720, 360, 50 # The whole range of dates in the different dataset versions all_ecco_dates(::ECCO4Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) all_ecco_dates(::ECCO2Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) -all_ecco_dates(::ECCO2Daily) = DateTimeProlepticGregorian(1992, 1, 4) : Day(1) : DateTimeProlepticGregorian(2023, 12, 31) +all_ecco_dates(::ECCO2Daily) = DateTimeProlepticGregorian(1992, 1, 4) : Day(1) : DateTimeProlepticGregorian(2023, 12, 31) # File name generation specific to each Dataset version function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) From d09ec57d258d46d99d9b0df824d8d1eca2ce7111 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 16:25:20 -0400 Subject: [PATCH 433/716] remove maxiter --- src/DataWrangling/ECCO.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index 7a0f6dd3..eae5be1d 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -244,8 +244,6 @@ function inpainted_ecco_field(metadata::ECCOMetadata; kw...) f = ecco_field(metadata; architecture, filename, kw...) - - @show maxiter # Make sure all values are extended properly @info "In-painting ecco $(metadata.name)" From ec63733c75da96ff47105bdd0f5f72099831fc86 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 16:42:57 -0400 Subject: [PATCH 434/716] ok now this should work? --- src/DataWrangling/ecco_metadata.jl | 2 +- src/DataWrangling/ecco_restoring.jl | 37 +++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index 7634a252..bd210a59 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -22,7 +22,7 @@ end ECCOMetadata(name::Symbol; version = ECCO4Monthly()) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), version) # Treat ECCOMetadata as an array to allow iteration over the dates. -Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i], metdata.version) +Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i], metadata.version) Base.length(metadata::ECCOMetadata) = length(metadata.dates) Base.eltype(metadata::ECCOMetadata) = Base.eltype(metadata.dates) Base.first(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[1], metadata.version) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index b6eb28dd..1c7c47af 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -102,6 +102,40 @@ metadata = ECCOMetadata(...) fts = ECCO_field_time_series(metadata) ``` """ +function ECCO_field_time_series(metadata::ECCOMetadata; + architecture = CPU(), + time_indices_in_memory = 2, + time_indexing = Cyclical()) + + # ECCO data is too chunky to allow other backends + backend = ECCONetCDFBackend(time_indices_in_memory) + + # Making sure all the required individual files are downloaded + download_dataset!(metadata) + + location = field_location(metadata) + ftmp = empty_ecco_field(first(metadata); architecture) + shortname = short_name(metadata) + + ECCO_native_grid = ftmp.grid + boundary_conditions = FieldBoundaryConditions(ECCO_native_grid, location) + times = ecco_times(metadata) + + fts = FieldTimeSeries{location...}(ECCO_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = metadata, + name = shortname) + + # Let's set the data + set!(fts) + + return fts +end + +ECCO_field_time_series(variable_name::Symbol, version=ECCO4Monthly(); kw...) = + ECCO_field_time_series(ECCOMetadata(variable_name, all_ecco_dates(version), version); kw...) @inline variable_name_from_index(i) = ifelse(i == 1, :T, ifelse(i == 2, :S, ifelse(i == 3, :u, :v))) @@ -203,8 +237,7 @@ function ECCO_restoring_forcing(metadata::ECCOMetadata; ecco_restoring = ECCORestoring(ecco_fts, field_idx, mask, timescale) restoring_forcing = Forcing(ecco_restoring; - discrete_form=true, - parameters=(; ecco_fts, field_idx, mask, λ=timescale)) + discrete_form=true) return restoring_forcing end \ No newline at end of file From b53305b01057159fd26a9d70e416f70379851597 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 16:44:26 -0400 Subject: [PATCH 435/716] try this out --- prototype_omip_simulation/prototype_omip_simulation.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 31ebfad8..f78c9ccd 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -65,12 +65,14 @@ closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) ##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic ##### -@inline mask(λ, φ, z, t) = φ > 75 | φ < 75 +@inline mask(λ, φ, z, t) = Int(φ > 75 | φ < -75) -FT = ECCO_restoring_forcing +FT = ECCO_restoring_forcing(:temperature; mask, architecture = arch) +FS = ECCO_restoring_forcing(:salinity; mask, architecture = arch) +forcing = (; T = FT, S = FS) -ocean = ocean_simulation(grid; free_surface, closure) +ocean = ocean_simulation(grid; free_surface, forcing, closure) model = ocean.model set!(model, From 5cfb33660838e183726336854cdca3be82a5dfa7 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 7 May 2024 23:04:05 -0400 Subject: [PATCH 436/716] can start the first simulation --- src/DataWrangling/ecco_restoring.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 1c7c47af..ab045586 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -1,5 +1,6 @@ using Oceananigans.Units -using Oceananigans.Fields: interpolate! +using Oceananigans.Grids: node +using Oceananigans.Fields: interpolate!, interpolate, instantiated_location using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices using Oceananigans.Utils: Time @@ -76,6 +77,8 @@ function ecco_times(metadata; start_time = first(metadata).dates) push!(times, time) end + times = tuple(times...) + return times end @@ -176,10 +179,11 @@ Adapt.adapt_structure(to, p::ECCORestoring) = # Figure out all the inputs: variable name, time, location, and node var_name = variable_name_from_index(p.field_idx) time = Time(clock.time) - loc = location(p.ecco_fts) - X = node(i, j, k, grid, loc) + loc = instantiated_location(p.ecco_fts) + X = node(i, j, k, grid, loc...) # Extracting the ECCO field time series data and parameters + ecco_times = p.ecco_fts.times ecco_grid = p.ecco_fts.grid ecco_data = p.ecco_fts.data ecco_backend = p.ecco_fts.backend @@ -189,7 +193,7 @@ Adapt.adapt_structure(to, p::ECCORestoring) = @inbounds var = getproperty(fields, var_name)[i, j, k] # Interpolating the ECCO field time series data ont the current node and time - ecco_var = interpolate(X, time, ecco_data, loc, grid, ecco_grid, ecco_backend, ecco_time_indexing) + ecco_var = interpolate(X, time, ecco_data, loc, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) # Extracting the mask value at the current node mask = stateindex(p.mask, i, j, k, grid, clock.time, loc) From df21dc87a312c928bc9586e0054c8f8e8c947c24 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Wed, 8 May 2024 08:43:52 -0400 Subject: [PATCH 437/716] typo --- prototype_omip_simulation/prototype_omip_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index f78c9ccd..746a2d0c 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -15,7 +15,7 @@ using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 using ClimaOcean.ECCO -using ClimaOcean.JRA55: NetCDFBackend, JRA55_prescribed_atmosphere +using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using ClimaOcean.ECCO: ECCO_restoring_forcing using ClimaOcean.Bathymetry @@ -83,7 +83,7 @@ set!(model, ##### The atmosphere ##### -backend = NetCDFBackend(4) +backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation(arch) From 72ba24d9e783fc474cfea425cd90fc28daedae3c Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Wed, 8 May 2024 08:44:42 -0400 Subject: [PATCH 438/716] add a timescale --- prototype_omip_simulation/prototype_omip_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 746a2d0c..69636513 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -67,8 +67,8 @@ closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) @inline mask(λ, φ, z, t) = Int(φ > 75 | φ < -75) -FT = ECCO_restoring_forcing(:temperature; mask, architecture = arch) -FS = ECCO_restoring_forcing(:salinity; mask, architecture = arch) +FT = ECCO_restoring_forcing(:temperature; mask, architecture = arch, timescale = 20days) +FS = ECCO_restoring_forcing(:salinity; mask, architecture = arch, timescale = 20days) forcing = (; T = FT, S = FS) From d19913fffb45c19a6fafa8c66eb3351033afb552 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 9 May 2024 11:12:30 -0400 Subject: [PATCH 439/716] clearing some bugs --- .../correct_oceananigans.jl | 61 +++++++++++++++++++ .../similarity_theory_turbulent_fluxes.jl | 21 +++---- 2 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 prototype_omip_simulation/correct_oceananigans.jl diff --git a/prototype_omip_simulation/correct_oceananigans.jl b/prototype_omip_simulation/correct_oceananigans.jl new file mode 100644 index 00000000..3c3dab76 --- /dev/null +++ b/prototype_omip_simulation/correct_oceananigans.jl @@ -0,0 +1,61 @@ +#### +#### This file contains all the bug-fixes that still didn't get merged in Oceananigans.jl +#### + +using Oceananigans.BuoyancyModels: ∂z_b +using Oceananigans.Operators +using Oceananigans.Grids: peripheral_node, inactive_node +using Oceananigans.TurbulenceClosures: top_buoyancy_flux, getclosure, taper + +import Oceananigans.TurbulenceClosures: _compute_ri_based_diffusivities! + +@inline function _compute_ri_based_diffusivities!(i, j, k, diffusivities, grid, closure, + velocities, tracers, buoyancy, tracer_bcs, clock) + + # Ensure this works with "ensembles" of closures, in addition to ordinary single closures + closure_ij = getclosure(i, j, closure) + + ν₀ = closure_ij.ν₀ + κ₀ = closure_ij.κ₀ + κᶜᵃ = closure_ij.κᶜᵃ + Cᵃᵛ = closure_ij.Cᵃᵛ + Ri₀ = closure_ij.Ri₀ + Riᵟ = closure_ij.Riᵟ + tapering = closure_ij.Ri_dependent_tapering + + # Convection and entrainment + N² = ∂z_b(i, j, k, grid, buoyancy, tracers) + + # Conditions + convecting = N² < 0 # applies regardless of Qᵇ + + # Convective adjustment diffusivity + κᶜᵃ = ifelse(convecting, κᶜᵃ, zero(grid)) + + # Shear mixing diffusivity and viscosity + Ri = ℑxyᶜᶜᵃ(i, j, k, grid, ℑxyᶠᶠᵃ, diffusivities.Ri) + τ = taper(tapering, Ri, Ri₀, Riᵟ) + + κᶜ★ = κ₀ * τ + κᵘ★ = ν₀ * τ + + # Previous diffusivities + κᶜ = diffusivities.κᶜ + κᵘ = diffusivities.κᵘ + + # New diffusivities + κᶜ⁺ = κᶜ★ + κᶜᵃ + κᵘ⁺ = κᵘ★ + + # Set to zero on periphery and NaN within inactive region + on_periphery = peripheral_node(i, j, k, grid, Center(), Center(), Face()) + within_inactive = inactive_node(i, j, k, grid, Center(), Center(), Face()) + κᶜ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᶜ⁺)) + κᵘ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᵘ⁺)) + + # Update by averaging in time + @inbounds κᶜ[i, j, k] = (Cᵃᵛ * κᶜ[i, j, k] + κᶜ⁺) / (1 + Cᵃᵛ) + @inbounds κᵘ[i, j, k] = (Cᵃᵛ * κᵘ[i, j, k] + κᵘ⁺) / (1 + Cᵃᵛ) + + return nothing +end \ No newline at end of file diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index a82b5693..d0c380e3 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -29,7 +29,7 @@ import SurfaceFluxes.Parameters: ##### Bulk turbulent fluxes based on similarity theory ##### -struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, I, F} <: AbstractSurfaceFluxesParameters +struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, F} <: AbstractSurfaceFluxesParameters gravitational_acceleration :: FT von_karman_constant :: FT turbulent_prandtl_number :: FT @@ -43,7 +43,6 @@ struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, I, F} <: Abstr bulk_velocity :: V tolerance :: FT maxiter :: Int - iteration :: I fields :: F end @@ -69,7 +68,6 @@ Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt( adapt(to, fluxes.bulk_velocity), fluxes.tolerance, fluxes.maxiter, - fluxes.iteration, adapt(to, fluxes.fields)) Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" @@ -133,7 +131,6 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; bulk_velocity, convert(FT, tolerance), maxiter, - Ref(0), fields) end @@ -193,9 +190,11 @@ end # That will be refined later on. uτ = sqrt(Δu^2 + Δv^2 + convert(eltype(Δh), 0.25)) - while iterating(Σ★ - Σ₀, similarity_theory) + # Initialize the solver + iteration = 0 + + while iterating(Σ★ - Σ₀, iteration, similarity_theory) Σ₀ = Σ★ - similarity_theory.iteration[] += 1 Σ★, uτ, = refine_characteristic_scales(Σ★, uτ, similarity_theory, surface_state, @@ -204,14 +203,13 @@ end thermodynamics_parameters, gravitational_acceleration, von_karman_constant) + iteration += 1 end u★ = Σ★.momentum θ★ = Σ★.temperature q★ = Σ★.water_vapor - similarity_theory.iteration[] = 0 - # `u★² ≡ sqrt(τx² + τy²)` # We remove the gustiness by dividing by `uτ` τx = - u★^2 * Δu / uτ @@ -234,10 +232,9 @@ end end # Iterating condition for the characteristic scales solvers -@inline function iterating(Σ★, solver) - solver.iteration[] >= solver.maxiter && return false - norm(Σ★) <= solver.tolerance && return false - return true +@inline function iterating(Σ★, iteration, solver) + iteration_complete = (iteration < solver.maxiter) & (norm(Σ★) <= solver.tolerance) + return iteration_complete end @inline function initial_guess(differences, From 4fa8bc4e7bc8e08beeb161615ea4ee68c099f192 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 9 May 2024 11:12:50 -0400 Subject: [PATCH 440/716] some change --- .../correct_oceananigans.jl | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 prototype_omip_simulation/correct_oceananigans.jl diff --git a/prototype_omip_simulation/correct_oceananigans.jl b/prototype_omip_simulation/correct_oceananigans.jl deleted file mode 100644 index 3c3dab76..00000000 --- a/prototype_omip_simulation/correct_oceananigans.jl +++ /dev/null @@ -1,61 +0,0 @@ -#### -#### This file contains all the bug-fixes that still didn't get merged in Oceananigans.jl -#### - -using Oceananigans.BuoyancyModels: ∂z_b -using Oceananigans.Operators -using Oceananigans.Grids: peripheral_node, inactive_node -using Oceananigans.TurbulenceClosures: top_buoyancy_flux, getclosure, taper - -import Oceananigans.TurbulenceClosures: _compute_ri_based_diffusivities! - -@inline function _compute_ri_based_diffusivities!(i, j, k, diffusivities, grid, closure, - velocities, tracers, buoyancy, tracer_bcs, clock) - - # Ensure this works with "ensembles" of closures, in addition to ordinary single closures - closure_ij = getclosure(i, j, closure) - - ν₀ = closure_ij.ν₀ - κ₀ = closure_ij.κ₀ - κᶜᵃ = closure_ij.κᶜᵃ - Cᵃᵛ = closure_ij.Cᵃᵛ - Ri₀ = closure_ij.Ri₀ - Riᵟ = closure_ij.Riᵟ - tapering = closure_ij.Ri_dependent_tapering - - # Convection and entrainment - N² = ∂z_b(i, j, k, grid, buoyancy, tracers) - - # Conditions - convecting = N² < 0 # applies regardless of Qᵇ - - # Convective adjustment diffusivity - κᶜᵃ = ifelse(convecting, κᶜᵃ, zero(grid)) - - # Shear mixing diffusivity and viscosity - Ri = ℑxyᶜᶜᵃ(i, j, k, grid, ℑxyᶠᶠᵃ, diffusivities.Ri) - τ = taper(tapering, Ri, Ri₀, Riᵟ) - - κᶜ★ = κ₀ * τ - κᵘ★ = ν₀ * τ - - # Previous diffusivities - κᶜ = diffusivities.κᶜ - κᵘ = diffusivities.κᵘ - - # New diffusivities - κᶜ⁺ = κᶜ★ + κᶜᵃ - κᵘ⁺ = κᵘ★ - - # Set to zero on periphery and NaN within inactive region - on_periphery = peripheral_node(i, j, k, grid, Center(), Center(), Face()) - within_inactive = inactive_node(i, j, k, grid, Center(), Center(), Face()) - κᶜ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᶜ⁺)) - κᵘ⁺ = ifelse(on_periphery, zero(grid), ifelse(within_inactive, NaN, κᵘ⁺)) - - # Update by averaging in time - @inbounds κᶜ[i, j, k] = (Cᵃᵛ * κᶜ[i, j, k] + κᶜ⁺) / (1 + Cᵃᵛ) - @inbounds κᵘ[i, j, k] = (Cᵃᵛ * κᵘ[i, j, k] + κᵘ⁺) / (1 + Cᵃᵛ) - - return nothing -end \ No newline at end of file From 90e8123ac3c1985ea25c3d05b1511eea5dadfffb Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 9 May 2024 11:18:13 -0400 Subject: [PATCH 441/716] bugfixes here and there --- .../similarity_theory_turbulent_fluxes.jl | 29 ++++++++++--------- .../CrossRealmFluxes/stability_functions.jl | 6 ++-- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 83d5bbb8..249e11f4 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -43,7 +43,6 @@ struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, F} <: Abstract bulk_velocity :: V tolerance :: FT maxiter :: Int - iteration :: Int fields :: F end @@ -69,7 +68,6 @@ Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt( adapt(to, fluxes.bulk_velocity), fluxes.tolerance, fluxes.maxiter, - fluxes.iteration, adapt(to, fluxes.fields)) Base.summary(::SimilarityTheoryTurbulentFluxes{FT}) where FT = "SimilarityTheoryTurbulentFluxes{$FT}" @@ -133,7 +131,6 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; bulk_velocity, convert(FT, tolerance), maxiter, - 0, fields) end @@ -191,9 +188,12 @@ end # The inital velocity scale assumes that # the gustiness velocity `uᴳ` is equal to 0.5 ms⁻¹. # That will be refined later on. - uτ = sqrt(Δu^2 + Δv^2 + convert(FT, 0.25)) + uτ = sqrt(Δu^2 + Δv^2 + convert(eltype(Δh), 0.25)) + + # Initialize the solver + iteration = 0 - while iterating(Σ★ - Σ₀, similarity_theory) + while iterating(Σ★ - Σ₀, iteration, similarity_theory) Σ₀ = Σ★ similarity_theory.iteration += 1 Σ★, uτ, = refine_characteristic_scales(Σ★, uτ, @@ -204,6 +204,7 @@ end thermodynamics_parameters, gravitational_acceleration, von_karman_constant) + iteration += 1 end u★ = Σ★.momentum @@ -232,10 +233,10 @@ end end # Iterating condition for the characteristic scales solvers -@inline function iterating(Σ★, solver) - solver.iteration >= solver.maxiter && return false - norm(Σ★) <= solver.tolerance && return false - return true +@inline function iterating(Σ★, iteration, solver) + converged = norm(Σ★) <= solver.tolerance + reached_maxiter = iteration >= solver.maxiter + return converged | reached_maxiter end @inline function initial_guess(differences, @@ -251,6 +252,8 @@ end Δq = differences.q h = differences.h + FT = eltype(h) + g = gravitational_acceleration ϰ = von_karman_constant @@ -259,8 +262,8 @@ end β = similarity_theory.gustiness_parameter zᵢ = atmos_boundary_layer_height - hᵢ = convert(eltype(h), 10) # Reference Initial height == 10 meters - ℓuᵢ = convert(eltype(h), 1e-4) # Initial roughness length == 1e-4 meters + hᵢ = convert(FT, 10) # Reference Initial height == 10 meters + ℓuᵢ = convert(FT, 1e-4) # Initial roughness length == 1e-4 meters # assuming the initial gustiness is `0.5` ms⁻¹ uτ = sqrt(Δu^2 + Δv^2 + convert(FT, 0.25)) @@ -295,8 +298,8 @@ end Riᶜ = - h / zᵢ / convert(FT, 0.004) / β^3 # - h / zi / 0.004 / β^3 # Calculating the first stability coefficient and the MO length - # TODO: explain this formulation of the stability function. Is it empirical? - # Found in COARE3.6 + # TODO: explain this formulation of the stability function. + # Is it empirical? Found in COARE3.6 ζ10 = ifelse(Ri < 0, χc * Ri / (1 + Ri / Riᶜ), χc * Ri * (1 + 27 / 9 * Ri / χc)) L10 = h / ζ10 diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index 8fe9351f..8769f68d 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -33,7 +33,7 @@ function default_stability_functions(FT = Float64) end @inline function (ψ::InitialMomentumStabilityFunction)(ζ) - FT = elype(ζ) + FT = eltype(ζ) # Parameters p₁ = convert(FT, 0.35) @@ -57,7 +57,7 @@ end end @inline function (ψ::MomentumStabilityFunction)(ζ) - FT = elype(ζ) + FT = eltype(ζ) # Parameters p₁ = convert(FT, 0.35) @@ -83,7 +83,7 @@ end end @inline function (ψ::ScalarStabilityFunction)(ζ) - FT = elype(ζ) + FT = eltype(ζ) # Parameters p₁ = convert(FT, 0.35) From 532887972c481ca5ac871110e4b596fda707247f Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 9 May 2024 12:57:38 -0400 Subject: [PATCH 442/716] add links --- .../CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 249e11f4..3fa2f25a 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -295,11 +295,14 @@ end # TODO: find out what 0.004 refers to b★ = buoyancy_scale(Δθ, Δq, 𝒬ₒ, ℂₐ, g) Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) + + # https://github.com/NOAA-PSL/COARE-algorithm/blob/5b144cf6376a98b42200196d57ae40d791494abe/Matlab/COARE3.6/coare36vn_zrf_et.m#L372 Riᶜ = - h / zᵢ / convert(FT, 0.004) / β^3 # - h / zi / 0.004 / β^3 # Calculating the first stability coefficient and the MO length # TODO: explain this formulation of the stability function. # Is it empirical? Found in COARE3.6 + # https://github.com/NOAA-PSL/COARE-algorithm/blob/5b144cf6376a98b42200196d57ae40d791494abe/Matlab/COARE3.6/coare36vn_zrf_et.m#L373 ζ10 = ifelse(Ri < 0, χc * Ri / (1 + Ri / Riᶜ), χc * Ri * (1 + 27 / 9 * Ri / χc)) L10 = h / ζ10 From a59d17b9a92f6ee5029df8fe66331dcc4a658111 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 9 May 2024 12:58:56 -0400 Subject: [PATCH 443/716] correct line reference --- .../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 3fa2f25a..1c6bdb87 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -296,13 +296,13 @@ end b★ = buoyancy_scale(Δθ, Δq, 𝒬ₒ, ℂₐ, g) Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) - # https://github.com/NOAA-PSL/COARE-algorithm/blob/5b144cf6376a98b42200196d57ae40d791494abe/Matlab/COARE3.6/coare36vn_zrf_et.m#L372 + # https://github.com/NOAA-PSL/COARE-algorithm/blob/5b144cf6376a98b42200196d57ae40d791494abe/Matlab/COARE3.6/coare36vn_zrf_et.m#L373 Riᶜ = - h / zᵢ / convert(FT, 0.004) / β^3 # - h / zi / 0.004 / β^3 # Calculating the first stability coefficient and the MO length # TODO: explain this formulation of the stability function. # Is it empirical? Found in COARE3.6 - # https://github.com/NOAA-PSL/COARE-algorithm/blob/5b144cf6376a98b42200196d57ae40d791494abe/Matlab/COARE3.6/coare36vn_zrf_et.m#L373 + # https://github.com/NOAA-PSL/COARE-algorithm/blob/5b144cf6376a98b42200196d57ae40d791494abe/Matlab/COARE3.6/coare36vn_zrf_et.m#L375 ζ10 = ifelse(Ri < 0, χc * Ri / (1 + Ri / Riᶜ), χc * Ri * (1 + 27 / 9 * Ri / χc)) L10 = h / ζ10 From 34c3a6d64a23b50838e129e9be53867672f437e3 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 9 May 2024 12:59:53 -0400 Subject: [PATCH 444/716] correct reference --- .../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 1c6bdb87..9f616c7f 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -286,8 +286,8 @@ end χq = ϰ / log(h / ℓθ₀) χc = ϰ * χq / χu - # Similarity functions from Businger et al. (1971) - ψu = InitialMomentumStabilityFunction() + # Similarity functions from Edson et al. (2013) + ψu = InitialMomentumStabilityFunction() ψθ = similarity_theory.stability_functions.temperature ψq = similarity_theory.stability_functions.water_vapor From d9be32cd56a675df82d72aff04b28e5c21889369 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 9 May 2024 13:00:27 -0400 Subject: [PATCH 445/716] correct comment --- .../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 9f616c7f..187dbae6 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -292,10 +292,10 @@ end ψq = similarity_theory.stability_functions.water_vapor # Bulk Flux Richardson number - # TODO: find out what 0.004 refers to b★ = buoyancy_scale(Δθ, Δq, 𝒬ₒ, ℂₐ, g) Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) + # Critical Richardson number, TODO: find out what 0.004 refers to # https://github.com/NOAA-PSL/COARE-algorithm/blob/5b144cf6376a98b42200196d57ae40d791494abe/Matlab/COARE3.6/coare36vn_zrf_et.m#L373 Riᶜ = - h / zᵢ / convert(FT, 0.004) / β^3 # - h / zi / 0.004 / β^3 From 5d8f0ee89cc553814aefe403ca2e80f335f9ab97 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 13 May 2024 09:40:46 -0400 Subject: [PATCH 446/716] update forcing fts --- src/OceanSeaIceModels/ocean_only_model.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 7d290a3f..46bb0196 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -28,6 +28,15 @@ end function update_state!(coupled_model::NoSeaIceModel, callbacks=[]; compute_tendencies=false) time = Time(coupled_model.clock.time) update_model_field_time_series!(coupled_model.atmosphere, time) + + ocean_model = coupled_model.ocean.model + + # Do we really have to do this? + if !isempty(ocean_model.forcing) + field_time_series = extract_field_time_series(ocean_model.forcing) + update_field_time_series!(field_time_series, time) + end + compute_atmosphere_ocean_fluxes!(coupled_model) return nothing end From e6d020e9a14a4a71dd08c6e0fe2e200163f5f7d3 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 14 May 2024 10:16:40 -0400 Subject: [PATCH 447/716] Some documentation of the radiation --- .../CrossRealmFluxes/CrossRealmFluxes.jl | 2 +- .../CrossRealmFluxes/radiation.jl | 80 ++++++++++++++----- ...ependent_albedo.jl => tabulated_albedo.jl} | 38 +++++++-- 3 files changed, 92 insertions(+), 28 deletions(-) rename src/OceanSeaIceModels/CrossRealmFluxes/{latitude_dependent_albedo.jl => tabulated_albedo.jl} (87%) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 6d611451..dd30a57c 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -61,7 +61,7 @@ function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) end include("radiation.jl") -include("latitude_dependent_albedo.jl") +include("tabulated_albedo.jl") include("roughness_lengths.jl") include("stability_functions.jl") include("seawater_saturation_specific_humidity.jl") diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index e74a698c..4ecac4cc 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -1,3 +1,5 @@ +using Oceananigans.Grids: φnode + @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) @@ -12,10 +14,35 @@ Adapt.adapt_structure(to, r :: Radiation) = Adapt.adapt(to, r.reflection), Adapt.adapt(to, r.stefan_boltzmann_constant)) +""" + Radiation(arch = CPU(), FT=Float64; + ocean_emissivity = 0.97, + sea_ice_emissivity = 1.0, + ocean_albedo = LatitudeDependentAlbedo(FT), + sea_ice_albedo = 0.7, + stefan_boltzmann_constant = 5.67e-8) + +Constructs a `Radiation` object that represents the radiation properties of the ocean and sea ice. + +# Arguments +=========== + +- `arch`: The architecture of the system (default: `CPU()`). +- `FT`: The floating-point type to use (default: `Float64`). + +# Keyword Arguments +=================== + +- `ocean_emissivity`: The emissivity of the ocean surface (default: `0.97`). +- `sea_ice_emissivity`: The emissivity of the sea ice surface (default: `1.0`). +- `ocean_albedo`: The albedo of the ocean surface (default: `LatitudeDependentAlbedo(FT)`). +- `sea_ice_albedo`: The albedo of the sea ice surface (default: `0.7`). +- `stefan_boltzmann_constant`: The Stefan-Boltzmann constant (default: `5.67e-8`). +""" function Radiation(arch = CPU(), FT=Float64; ocean_emissivity = 0.97, sea_ice_emissivity = 1.0, - ocean_albedo = TabulatedAlbedo(arch, FT), + ocean_albedo = LatitudeDependentAlbedo(FT), sea_ice_albedo = 0.7, stefan_boltzmann_constant = 5.67e-8) @@ -40,6 +67,38 @@ struct LatitudeDependentAlbedo{FT} diffuse :: FT end +""" + LatitudeDependentAlbedo([FT::DataType=Float64]; diffuse = 0.069, direct = 0.011) + +Constructs a `LatitudeDependentAlbedo` object. The albedo of the ocean surface is assumed to be a function of the latitude, +obeying the following formula (Large and Yeager, 2009): + + α(φ) = α.diffuse - α.direct * cos(2φ) + +where `φ` is the latitude, `α_diffuse` is the diffuse albedo, and `α_direct` is the direct albedo. + +# Arguments +=========== + +- `FT::DataType`: The data type of the albedo values. Default is `Float64`. + +# Keyword Arguments +=================== +- `diffuse`: The diffuse albedo value. Default is `0.069`. +- `direct`: The direct albedo value. Default is `0.011`. +""" +function LatitudeDependentAlbedo(FT::DataType=Float64; + diffuse = 0.069, + direct = 0.011) + + return LatitudeDependentAlbedo(convert(FT, direct), + convert(FT, diffuse)) +end + +Adapt.adapt_structure(to, α::LatitudeDependentAlbedo) = + LatitudeDependentAlbedo(Adapt.adapt(to, α.direct), + Adapt.adapt(to, α.diffuse)) + @inline function stateindex(α::LatitudeDependentAlbedo, i, j, k, grid, time) φ = φnode(i, j, k, grid, Center(), Center(), Center()) α_diffuse = α.diffuse @@ -48,25 +107,6 @@ end return α_diffuse - direct_correction end -# To allow the use with KernelFunctionOperation -@inline function net_downwelling_radiation(i, j, k, grid, time, - atmos_radiation, - atmos_grid, - atmos_times, - atmos_backend, - atmos_time_indexing, - radiative_properties) - - X = node(i, j, 1, grid, c, c, f) - - atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) - - Qs = interp_atmos_time_series(atmos_radiation.shortwave, X, time, atmos_args...) - Qℓ = interp_atmos_time_series(atmos_radiation.longwave, X, time, atmos_args...) - - return net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiative_properties) -end - struct SurfaceProperties{O, I} ocean :: O sea_ice :: I diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl similarity index 87% rename from src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl rename to src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index 9d18d4f5..c5434185 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/latitude_dependent_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -43,6 +43,35 @@ const α_payne = [ 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0 0.453 0.398 0.342 0.301 0.266 0.226 0.205 0.180 0.157 0.140 0.125 0.109 0.095 0.083 0.074 0.065 0.061 0.057 0.052 0.048 0.044 0.040 0.038 0.033 0.032 0.031 0.030 0.029 0.028 0.027 0.027 0.026 0.026 0.026 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.02 0.425 0.370 0.325 0.290 0.255 0.220 0.200 0.178 0.157 0.140 0.122 0.108 0.095 0.083 0.074 0.065 0.061 0.056 0.052 0.048 0.044 0.040 0.038 0.033 0.032 0.031 0.030 0.029 0.028 0.027 0.026 0.026 0.026 0.026 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.025 0.02] +""" + TabulatedAlbedo(arch = CPU(), FT = Float64; + S₀ = convert(FT, 1365), + α_table = α_payne, + φ_values = (0:2:90) ./ 180 * π, + 𝓉_values = 0:0.05:1) + +Constructs a `TabulatedAlbedo` object that interpolated the albedo from a value table `α_table` that +is function of latitude `φ` and atmospheric transimissivity `𝓉`. + +Note: `TabulatedAlbedo` assumes that the latitude and the transissivity in the table are uniformly spaced. + +The transmissivity of the atmosphere is calculated as the ratio of the downwelling solar radiation to the +maximum possible downwelling solar radiation for a transparent atmosphere, function of hour of the day, latitude, +and day in the year. + +# Arguments +============ + +- `arch`: The architecture to use (default: `CPU()`). +- `FT`: The floating-point type to use (default: `Float64`). + +# Keyword Arguments +=================== +- `S₀`: The solar constant (default: `convert(FT, 1365)`). +- `α_table`: The table of albedo values (default: `α_payne`). +- `φ_values`: The latitude values for the table (default: `(0:2:90) ./ 180 * π`). +- `𝓉_values`: The transmissivity values for the table (default: `0:0.05:1`). +""" function TabulatedAlbedo(arch = CPU(), FT = Float64; S₀ = convert(FT, 1365), α_table = α_payne, @@ -57,11 +86,6 @@ function TabulatedAlbedo(arch = CPU(), FT = Float64; return TabulatedAlbedo(α_table, φ_values, 𝓉_values, S₀) end -@inline ϕ₁(ξ, η) = (1 - ξ) * (1 - η) -@inline ϕ₂(ξ, η) = (1 - ξ) * η -@inline ϕ₃(ξ, η) = ξ * (1 - η) -@inline ϕ₄(ξ, η) = ξ * η - @inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}) α = radiation.reflection.ocean @@ -95,13 +119,13 @@ end 𝓉 = ifelse(Qmax > 0, min(1, Qs / Qmax), 0) # finding the i-index in the table (depending on transmissivity) - # assuming the transmissivity is tabulated with constant values + # we assume that the transmissivity is tabulated with a constant spacing 𝓉₁ = @inbounds α.𝓉_values[1] Δ𝓉 = @inbounds α.𝓉_values[2] - 𝓉₁ i⁻, i⁺, ξ = interpolator((𝓉 - 𝓉₁) / Δ𝓉) # finding the j-index in the table (depending on latitude) - # assuming the transmissivity is tabulated with constant values + # we assume that the transmissivity is tabulated with a constant spacing φ₁ = @inbounds α.φ_values[1] Δφ = @inbounds α.φ_values[2] - φ₁ j⁻, j⁺, η = interpolator((abs(φ) - φ₁) / Δφ) From 356d97361dace32cde810caddaf45d014fdffacc Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Wed, 15 May 2024 22:24:51 -0400 Subject: [PATCH 448/716] pretty massive bug in the iterative solver. Now onto checking the radiative fluxes --- prototype_omip_simulation/Manifest.toml | 14 +++--- prototype_omip_simulation/Project.toml | 1 + .../comparison_to_coare.jl | 34 +++++++++++-- .../prototype_omip_simulation.jl | 11 ++-- .../ocean_sea_ice_surface_fluxes.jl | 1 + .../CrossRealmFluxes/radiation.jl | 8 +-- .../CrossRealmFluxes/roughness_lengths.jl | 50 ++++++++++++++++--- .../similarity_theory_turbulent_fluxes.jl | 10 ++-- .../CrossRealmFluxes/tabulated_albedo.jl | 5 ++ src/OceanSimulations/OceanSimulations.jl | 1 + 10 files changed, 104 insertions(+), 31 deletions(-) diff --git a/prototype_omip_simulation/Manifest.toml b/prototype_omip_simulation/Manifest.toml index 43145043..2c4f18be 100644 --- a/prototype_omip_simulation/Manifest.toml +++ b/prototype_omip_simulation/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.2" +julia_version = "1.10.3" manifest_format = "2.0" -project_hash = "2b8dc0157e67ed69c1dbe71ccf1e8d7dd3d38b48" +project_hash = "ad94f0873a50599743724c16c7dfb94779a2964d" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" @@ -192,10 +192,10 @@ weakdeps = ["SparseArrays"] ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.ClimaOcean]] -deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "FFMPEG", "ImageMorphology", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "FFMPEG", "ImageMorphology", "JLD2", "JSON3", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] path = ".." uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -version = "0.1.0" +version = "0.2.0" [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] @@ -269,7 +269,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.0+0" +version = "1.1.1+0" [[deps.CompositionsBase]] git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" @@ -1108,8 +1108,8 @@ uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.6.3" [[deps.OrthogonalSphericalShellGrids]] -deps = ["CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays"] -git-tree-sha1 = "9f55479bbaa571762ac02f7664125d342022d5d1" +deps = ["CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays", "Printf"] +git-tree-sha1 = "ad2ad883a638e387818d0e2b270c67fd4dcea89f" repo-rev = "main" repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl" uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" diff --git a/prototype_omip_simulation/Project.toml b/prototype_omip_simulation/Project.toml index 2fa2bf04..a12db012 100644 --- a/prototype_omip_simulation/Project.toml +++ b/prototype_omip_simulation/Project.toml @@ -4,5 +4,6 @@ ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" OrthogonalSphericalShellGrids = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" +SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" SurfaceFluxes = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index 97ab36e2..a5a0d4fb 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -73,23 +73,47 @@ Ta = Array(interior(atmosphere.tracers.T[1], :, :, 1)) qa = Array(interior(atmosphere.tracers.q[1], :, :, 1)) ra = Array(interior(atmosphere.tracers.r[1], :, :, 1)) pa = Array(interior(atmosphere.pressure[1], :, :, 1)) +Rs = Array(interior(atmosphere.downwelling_radiation.shortwave[1], :, :, 1)) +Rl = Array(interior(atmosphere.downwelling_radiation.longwave[1], :, :, 1)) write(matfile, "ua", ua) write(matfile, "va", va) write(matfile, "Ta", Ta) write(matfile, "qa", qa) write(matfile, "ra", ra) write(matfile, "pa", pa) +write(matfile, "Rs", Rs) +write(matfile, "Rl", Rl) + +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: net_downwelling_radiation + +@inline net_downwelling_radiation(i::Int, j::Int, k::Int, grid, time, Qs::Field, Ql::Field, args...) = + net_downwelling_radiation(i, j, grid, time, Qs[i, j, k], Ql[i, j, k], args...) + +Rad = KernelFunctionOperation{Center, Center, Center}(net_downwelling_radiation, + grid, + Time(0), + atmosphere.downwelling_radiation.shortwave[1], + atmosphere.downwelling_radiation.longwave[1], + coupled_model.fluxes.radiation) + +Rin = compute!(Field(Rad)) +Rin = Array(interior(Rin, :, :, 1)) +Rou = 0.97 * 5.67e-8 .* (Array(interior(ocean.model.tracers.T, :, :, 50)) .+ 273.15) .^ 4 # Turbulent fluxes -Ql = Array(interior(coupled_model.fluxes.turbulent.fields.latent_heat, :, :, 1)) -Qs = Array(interior(coupled_model.fluxes.turbulent.fields.sensible_heat, :, :, 1)) -Mv = Array(interior(coupled_model.fluxes.turbulent.fields.water_vapor, :, :, 1)) -tx = Array(interior(coupled_model.fluxes.turbulent.fields.x_momentum, :, :, 1)) -ty = Array(interior(coupled_model.fluxes.turbulent.fields.y_momentum, :, :, 1)) +Ql = Array(interior(coupled_model.fluxes.turbulent.fields.latent_heat, :, :, 1)) +Qs = Array(interior(coupled_model.fluxes.turbulent.fields.sensible_heat, :, :, 1)) +Mv = Array(interior(coupled_model.fluxes.turbulent.fields.water_vapor, :, :, 1)) +tx = Array(interior(coupled_model.fluxes.turbulent.fields.x_momentum, :, :, 1)) +ty = Array(interior(coupled_model.fluxes.turbulent.fields.y_momentum, :, :, 1)) +Tf = Array(interior(ocean.model.tracers.T.boundary_conditions.top.condition, :, :, 1)) write(matfile, "Ql", Ql) write(matfile, "Qs", Qs) write(matfile, "Mv", Mv) write(matfile, "tx", tx) write(matfile, "ty", ty) +write(matfile, "Tf", Tf) +write(matfile, "Ri", Rin) +write(matfile, "Ro", Rou) close(matfile) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 7dad4d01..e38c4238 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -33,9 +33,14 @@ Nx = 2160 Ny = 1100 Nz = length(z_faces) - 1 -arch = GPU() #Distributed(GPU(), partition = Partition(2)) +arch = CPU() #Distributed(GPU(), partition = Partition(2)) -grid = TripolarGrid(arch; size = (Nx, Ny, Nz), halo = (7, 7, 7), z = z_faces) +grid = TripolarGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = z_faces, + north_poles_latitude = 60, + first_pole_longitude = 75) bottom_height = retrieve_bathymetry(grid, bathymetry_file; minimum_depth = 10, @@ -43,7 +48,7 @@ bottom_height = retrieve_bathymetry(grid, bathymetry_file; interpolation_passes = 20, connected_regions_allowed = 0) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) #; active_cells_map = true) ##### ##### The Ocean component diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index d1cb1f22..ec7239a7 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -393,6 +393,7 @@ end # Compute heat fluxes, bulk flux first Qd = net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation_properties) Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, Tₒ) + ΣQ = Qd + Qu + Qc + Qv # Convert from a mass flux to a volume flux (aka velocity) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index 4ecac4cc..e0998b51 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -15,10 +15,10 @@ Adapt.adapt_structure(to, r :: Radiation) = Adapt.adapt(to, r.stefan_boltzmann_constant)) """ - Radiation(arch = CPU(), FT=Float64; + Radiation([arch = CPU(), FT=Float64]; ocean_emissivity = 0.97, sea_ice_emissivity = 1.0, - ocean_albedo = LatitudeDependentAlbedo(FT), + ocean_albedo = TabulatedAlbedo(arch, FT), sea_ice_albedo = 0.7, stefan_boltzmann_constant = 5.67e-8) @@ -42,7 +42,7 @@ Constructs a `Radiation` object that represents the radiation properties of the function Radiation(arch = CPU(), FT=Float64; ocean_emissivity = 0.97, sea_ice_emissivity = 1.0, - ocean_albedo = LatitudeDependentAlbedo(FT), + ocean_albedo = TabulatedAlbedo(arch, FT), sea_ice_albedo = 0.7, stefan_boltzmann_constant = 5.67e-8) @@ -75,7 +75,7 @@ obeying the following formula (Large and Yeager, 2009): α(φ) = α.diffuse - α.direct * cos(2φ) -where `φ` is the latitude, `α_diffuse` is the diffuse albedo, and `α_direct` is the direct albedo. +where `φ` is the latitude, `α.diffuse` is the diffuse albedo, and `α_.irect` is the direct albedo. # Arguments =========== diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index aa2a4a81..5d748476 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -12,22 +12,56 @@ struct ScalarRoughnessLength{FT, V, R} maximum_roughness_length :: FT end +""" + ScalarRoughnessLength([FT=Float64]; + air_kinematic_viscosity = temperature_dependent_viscosity, + reynolds_number_scaling_function = empirical_scaling_function, + maximum_roughness_length = 1.6e-4) + +Constructs a `ScalarRoughnessLength` object that represents the scalar roughness length +that regulates the exchange of heat and water vapor between the ocean and the atmosphere. + +Keyword Arguments +================== + +- `air_kinematic_viscosity::Function`: The function to compute the air kinematic viscosity. +- `reynolds_number_scaling_function::Function`: The function to compute the Reynolds number scaling factor. +- `maximum_roughness_length::Float`: The maximum roughness length value. Defaults to `1.6e-4`. +""" function ScalarRoughnessLength(FT=Float64; - air_kinematic_viscosity = temperature_dependent_viscosity, - reynolds_number_scaling_function = empirical_scaling_function, - maximum_roughness_length = 1.6e-4) # Values from COARE3.6 + air_kinematic_viscosity = temperature_dependent_viscosity, + reynolds_number_scaling_function = empirical_scaling_function, + maximum_roughness_length = 1.6e-4) # Values from COARE3.6 return ScalarRoughnessLength(air_kinematic_viscosity, reynolds_number_scaling_function, convert(FT, maximum_roughness_length)) end +""" + MomentumRoughnessLength([FT=Float64]; + air_kinematic_viscosity = temperature_dependent_viscosity, + reynolds_number_scaling_function = empirical_scaling_function, + maximum_roughness_length = 1.6e-4) + +Constructs a `MomentumRoughnessLength` object that represents the momentum roughness length that +regulates the exchange of momentum, heat, and water vapor between the ocean and the atmosphere. + +Keyword Arguments +================== + +- `gravitational_acceleration::Float`: The gravitational acceleration. Default is `default_gravitational_acceleration`. +- `maximum_roughness_length::Float`: The maximum roughness length. Default is `1.0`. +- `air_kinematic_viscosity::Float`: The air kinematic viscosity. Default is `temperature_dependent_viscosity`. +- `_wave_parameter::Float`: The wave parameter. Default is `0.011`. +- `laminar_parameter::Float`: The laminar parameter. Default is `0.11`. +""" function MomentumRoughnessLength(FT=Float64; - gravitational_acceleration = default_gravitational_acceleration, - maximum_roughness_length = 1.0, # An estimate? - air_kinematic_viscosity = temperature_dependent_viscosity, - _wave_parameter = 0.011, - laminar_parameter = 0.11) + gravitational_acceleration = default_gravitational_acceleration, + maximum_roughness_length = 1.0, # An estimate? + air_kinematic_viscosity = temperature_dependent_viscosity, + _wave_parameter = 0.011, + laminar_parameter = 0.11) return MomentumRoughnessLength(convert(FT, gravitational_acceleration), air_kinematic_viscosity, diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 187dbae6..c03ccd74 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -53,7 +53,7 @@ const STTF = SimilarityTheoryTurbulentFluxes @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() +@inline universal_func_type(::STTF{<:Any, <:Any, <:BusingerParams}) = BusingerType() Adapt.adapt_structure(to, fluxes::STTF) = SimilarityTheoryTurbulentFluxes(adapt(to, fluxes.gravitational_acceleration), adapt(to, fluxes.von_karman_constant), @@ -114,7 +114,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; roughness_lengths = default_roughness_lengths(FT), bulk_coefficients = bulk_coefficients, bulk_velocity = RelativeVelocity(), - tolerance = 1e-8, + tolerance = 1e-12, maxiter = 100, fields = nothing) @@ -195,7 +195,6 @@ end while iterating(Σ★ - Σ₀, iteration, similarity_theory) Σ₀ = Σ★ - similarity_theory.iteration += 1 Σ★, uτ, = refine_characteristic_scales(Σ★, uτ, similarity_theory, surface_state, @@ -211,6 +210,9 @@ end θ★ = Σ★.temperature q★ = Σ★.water_vapor + θ★ = θ★ / similarity_theory.turbulent_prandtl_number + q★ = q★ / similarity_theory.turbulent_prandtl_number + # `u★² ≡ sqrt(τx² + τy²)` # We remove the gustiness by dividing by `uτ` τx = - u★^2 * Δu / uτ @@ -236,7 +238,7 @@ end @inline function iterating(Σ★, iteration, solver) converged = norm(Σ★) <= solver.tolerance reached_maxiter = iteration >= solver.maxiter - return converged | reached_maxiter + return !(converged | reached_maxiter) end @inline function initial_guess(differences, diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index c5434185..d171ce16 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -86,6 +86,11 @@ function TabulatedAlbedo(arch = CPU(), FT = Float64; return TabulatedAlbedo(α_table, φ_values, 𝓉_values, S₀) end +@inline ϕ₁(ξ, η) = (1 - ξ) * (1 - η) +@inline ϕ₂(ξ, η) = (1 - ξ) * η +@inline ϕ₃(ξ, η) = ξ * (1 - η) +@inline ϕ₄(ξ, η) = ξ * η + @inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}) α = radiation.reflection.ocean diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index 0545ae4f..f1d7ff63 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -2,6 +2,7 @@ module OceanSimulations export load_balanced_regional_grid, ocean_simulation +using Oceananigans using Oceananigans.Units using Oceananigans.Advection: TracerAdvection using Oceananigans.Coriolis: ActiveCellEnstrophyConserving From c2531eb50624950d56c2a425d367c7bdff8d6de2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 15 May 2024 22:29:35 -0400 Subject: [PATCH 449/716] changes --- src/DataWrangling/ECCO.jl | 4 ++-- src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl | 11 ++++++++++- .../similarity_theory_turbulent_fluxes.jl | 4 ++-- src/OceanSeaIceModels/minimum_temperature_sea_ice.jl | 4 +++- src/OceanSeaIceModels/ocean_only_model.jl | 2 ++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index eae5be1d..984d0e0f 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -240,7 +240,7 @@ function inpainted_ecco_field(metadata::ECCOMetadata; architecture = CPU(), filename = file_name(metadata), mask = ecco_mask(metadata, architecture), - maxiter = 20, + maxiter = Inf, kw...) f = ecco_field(metadata; architecture, filename, kw...) @@ -303,4 +303,4 @@ end include("ecco_restoring.jl") -end # Module \ No newline at end of file +end # Module diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl index e74a698c..e5e3ac7f 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/radiation.jl @@ -1,3 +1,5 @@ +using Oceananigans.Grids: φnode + @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) @@ -15,7 +17,7 @@ Adapt.adapt_structure(to, r :: Radiation) = function Radiation(arch = CPU(), FT=Float64; ocean_emissivity = 0.97, sea_ice_emissivity = 1.0, - ocean_albedo = TabulatedAlbedo(arch, FT), + ocean_albedo = LatitudeDependentAlbedo(FT), sea_ice_albedo = 0.7, stefan_boltzmann_constant = 5.67e-8) @@ -40,6 +42,13 @@ struct LatitudeDependentAlbedo{FT} diffuse :: FT end +LatitudeDependentAlbedo(FT::DataType=Float64; diffuse = 0.069, direct = 0.011) = + LatitudeDependentAlbedo(convert(FT, direct), + convert(FT, diffuse)) + +Adapt.adapt_structure(to, α::LatitudeDependentAlbedo) = LatitudeDependentAlbedo(Adapt.adapt(to, α.direct), + Adapt.adapt(to, α.diffuse)) + @inline function stateindex(α::LatitudeDependentAlbedo, i, j, k, grid, time) φ = φnode(i, j, k, grid, Center(), Center(), Center()) α_diffuse = α.diffuse diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index d0c380e3..e796bbcf 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -112,7 +112,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), roughness_lengths = default_roughness_lengths(FT), - bulk_coefficients = bulk_coefficients, + bulk_coefficients = simplified_bulk_coefficients, bulk_velocity = RelativeVelocity(), tolerance = 1e-8, maxiter = 100, @@ -150,7 +150,7 @@ end @inline simplified_bulk_coefficients(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) # + ψ(ℓ / L) # The complete bulk coefficient -@inline bulk_coefficients(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) + ψ(ℓ / L) +# @inline bulk_coefficients(ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) + ψ(ℓ / L) ##### ##### Fixed-point iteration for roughness length diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl index 3a3c8894..3fa90615 100644 --- a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -55,7 +55,9 @@ end cooling_sea_ice = sea_ice & (Jᵀ[i, j, 1] > 0) # Don't allow the ocean to cool below the minimum temperature! (make sure it heats up though!) - Jᵀ[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), Jᵀ[i, j, 1]) + # On the other hand, assume all heating fluxes are due to solar radiation and + # multiply by a fictitious albedo + Jᵀ[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), 0.3 * Jᵀ[i, j, 1]) # If we are in a "sea ice" region we remove all fluxes Jˢ[i, j, 1] = ifelse(sea_ice, zero(grid), Jˢ[i, j, 1]) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 46bb0196..42c46bc2 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -1,3 +1,5 @@ +using Oceananigans.OutputReaders: extract_field_time_series, update_field_time_series! + const OceanOnlyModel = OceanSeaIceModel{Nothing} const OceanSimplifiedSeaIceModel = OceanSeaIceModel{<:MinimumTemperatureSeaIce} From bf8e5e58f535fdc7cdf790b8c36d70c5f6be341b Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Wed, 15 May 2024 23:00:42 -0400 Subject: [PATCH 450/716] remove warped grid --- prototype_omip_simulation/tripolar_specific_methods.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index 85c08c7d..45c14c30 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -19,10 +19,9 @@ using Oceananigans.Grids: cpu_face_constructor_x, topology, λnode, φnode -using OrthogonalSphericalShellGrids: TRG, WRG +using OrthogonalSphericalShellGrids: TRG const TField = Field{<:Any, <:Any, <:Any, <:Any, <:TRG} -const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) @@ -30,7 +29,7 @@ const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, convert_to_native_frame # Here we assume that the tripolar grid is locally orthogonal -@inline function convert_to_latlong_frame(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) +@inline function convert_to_latlong_frame(i, j, grid::TRG, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) @@ -39,7 +38,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) end -@inline function convert_to_native_frame(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) +@inline function convert_to_native_frame(i, j, grid::TRG, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i, j+1, 1, grid, Face(), Center(), Center()) From e773839daf0932e31b6513d2d698ac35e09ed9b8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 15 May 2024 23:15:18 -0400 Subject: [PATCH 451/716] new toml files --- prototype_omip_simulation/Manifest.toml | 36 ++++++++++++++++++++----- prototype_omip_simulation/Project.toml | 4 +++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/prototype_omip_simulation/Manifest.toml b/prototype_omip_simulation/Manifest.toml index 2c4f18be..8ae769d4 100644 --- a/prototype_omip_simulation/Manifest.toml +++ b/prototype_omip_simulation/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.3" +julia_version = "1.10.1" manifest_format = "2.0" -project_hash = "ad94f0873a50599743724c16c7dfb94779a2964d" +project_hash = "1cab777b23bf99dac075dcd3cc1d9faf7933f586" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" @@ -192,7 +192,7 @@ weakdeps = ["SparseArrays"] ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.ClimaOcean]] -deps = ["Adapt", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "FFMPEG", "ImageMorphology", "JLD2", "JSON3", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +deps = ["Adapt", "CFTime", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "FFMPEG", "ImageMorphology", "JLD2", "JSON3", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "Revise", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] path = ".." uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" version = "0.2.0" @@ -211,6 +211,12 @@ git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" version = "0.1.12" +[[deps.CodeTracking]] +deps = ["InteractiveUtils", "UUIDs"] +git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386" +uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" +version = "1.3.5" + [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" @@ -269,7 +275,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.1+0" +version = "1.1.0+0" [[deps.CompositionsBase]] git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" @@ -698,6 +704,12 @@ git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" version = "1.13.2" +[[deps.JuliaInterpreter]] +deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] +git-tree-sha1 = "e9648d90370e2d0317f9518c9c6e0841db54a90b" +uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" +version = "0.9.31" + [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" @@ -706,9 +718,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" +git-tree-sha1 = "db02395e4c374030c53dc28f3c1d33dec35f7272" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.18" +version = "0.9.19" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -887,6 +899,12 @@ weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] SpecialFunctionsExt = "SpecialFunctions" +[[deps.LoweredCodeUtils]] +deps = ["JuliaInterpreter"] +git-tree-sha1 = "31e27f0b0bf0df3e3e951bfcc43fe8c730a219f6" +uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" +version = "2.4.5" + [[deps.Lz4_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" @@ -1282,6 +1300,12 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" +[[deps.Revise]] +deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"] +git-tree-sha1 = "12aa2d7593df490c407a3bbd8b86b8b515017f3e" +uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" +version = "3.5.14" + [[deps.RootSolvers]] deps = ["ForwardDiff"] git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" diff --git a/prototype_omip_simulation/Project.toml b/prototype_omip_simulation/Project.toml index a12db012..e8e6b41f 100644 --- a/prototype_omip_simulation/Project.toml +++ b/prototype_omip_simulation/Project.toml @@ -1,7 +1,11 @@ [deps] +Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +CFTime = "179af706-886a-5703-950a-314cd64e0468" ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" OrthogonalSphericalShellGrids = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" From e804a4c879432692a0180457f291b13c5898613a Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 15 May 2024 23:15:40 -0400 Subject: [PATCH 452/716] add tripolar methods --- prototype_omip_simulation/tripolar_specific_methods.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index 85c08c7d..45c14c30 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -19,10 +19,9 @@ using Oceananigans.Grids: cpu_face_constructor_x, topology, λnode, φnode -using OrthogonalSphericalShellGrids: TRG, WRG +using OrthogonalSphericalShellGrids: TRG const TField = Field{<:Any, <:Any, <:Any, <:Any, <:TRG} -const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) @@ -30,7 +29,7 @@ const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, convert_to_native_frame # Here we assume that the tripolar grid is locally orthogonal -@inline function convert_to_latlong_frame(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) +@inline function convert_to_latlong_frame(i, j, grid::TRG, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) @@ -39,7 +38,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) end -@inline function convert_to_native_frame(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) +@inline function convert_to_native_frame(i, j, grid::TRG, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i, j+1, 1, grid, Face(), Center(), Center()) From 53e000e560c2c7efc0ffa73a2d724c3956d3cdcb Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 16 May 2024 07:48:40 -0400 Subject: [PATCH 453/716] removing some useless code --- .../ocean_sea_ice_surface_fluxes.jl | 8 +- .../similarity_theory_turbulent_fluxes.jl | 108 +++--------------- .../CrossRealmFluxes/stability_functions.jl | 97 +++++++++------- 3 files changed, 75 insertions(+), 138 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index ec7239a7..139e43b5 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -196,7 +196,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_time_indexing, atmosphere.measurement_height, # height at which the state is known atmosphere.boundary_layer_height, - atmosphere.thermodynamics_parameters) + atmosphere.thermodynamics_parameters) launch!(arch, grid, kernel_parameters, _assemble_atmosphere_ocean_fluxes!, centered_velocity_fluxes, @@ -320,11 +320,14 @@ limit_fluxes_over_sea_ice!(args...) = nothing g = default_gravitational_acceleration ϰ = similarity_theory.von_karman_constant + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) + maxiter = ifelse(inactive, 1, similarity_theory.maxiter) + turbulent_fluxes = compute_similarity_theory_fluxes(similarity_theory, dynamic_ocean_state, dynamic_atmos_state, atmosphere_boundary_layer_height, - ℂₐ, g, ϰ) + ℂₐ, g, ϰ, maxiter) kᴺ = size(grid, 3) # index of the top ocean cell @@ -333,7 +336,6 @@ limit_fluxes_over_sea_ice!(args...) = nothing τˣ, τʸ = convert_to_native_frame(i, j, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) - inactive = inactive_node(i, j, kᴺ, grid, c, c, c) @inbounds begin # +0: cooling, -0: heating diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index c03ccd74..1f918ba1 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -96,10 +96,10 @@ end const PATP = PrescribedAtmosphereThermodynamicsParameters -""" only the atmosphere velocity is used in flux calculations """ +""" The exchange fluxes depend on the atmosphere velocity but not the ocean velocity """ struct WindVelocity end -""" the atmosphere - ocean velocity difference is used in flux calculations """ +""" The exchange fluxes depend on the relative velocity between the atmosphere and the ocean """ struct RelativeVelocity end function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; @@ -114,7 +114,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; roughness_lengths = default_roughness_lengths(FT), bulk_coefficients = bulk_coefficients, bulk_velocity = RelativeVelocity(), - tolerance = 1e-12, + tolerance = 1e-8, maxiter = 100, fields = nothing) @@ -162,7 +162,8 @@ end atmos_boundary_layer_height, thermodynamics_parameters, gravitational_acceleration, - von_karman_constant) + von_karman_constant, + maxiter) # Prescribed difference between two states ℂₐ = thermodynamics_parameters @@ -174,16 +175,13 @@ end differences = (; u=Δu, v=Δv, θ=Δθ, q=Δq, h=Δh) - Σ₀ = SimilarityScales(0, 0, 0) + u★ = convert(eltype(Δh), 1e-4) # Initial guess for the characteristic scales u★, θ★, q★. - Σ★ = initial_guess(differences, - similarity_theory, - atmos_boundary_layer_height, - gravitational_acceleration, - von_karman_constant, - ℂₐ, - surface_state.ts) + # Does not really matter if we are sophisticated or not, it converges + # in about 10 iterations no matter what... + Σ₀ = SimilarityScales(1, 1, 1) + Σ★ = SimilarityScales(u★, u★, u★) # The inital velocity scale assumes that # the gustiness velocity `uᴳ` is equal to 0.5 ms⁻¹. @@ -193,7 +191,7 @@ end # Initialize the solver iteration = 0 - while iterating(Σ★ - Σ₀, iteration, similarity_theory) + while iterating(Σ★ - Σ₀, iteration, maxiter, similarity_theory) Σ₀ = Σ★ Σ★, uτ, = refine_characteristic_scales(Σ★, uτ, similarity_theory, @@ -235,86 +233,12 @@ end end # Iterating condition for the characteristic scales solvers -@inline function iterating(Σ★, iteration, solver) +@inline function iterating(Σ★, iteration, maxiter, solver) converged = norm(Σ★) <= solver.tolerance - reached_maxiter = iteration >= solver.maxiter + reached_maxiter = iteration >= maxiter return !(converged | reached_maxiter) end -@inline function initial_guess(differences, - similarity_theory, - atmos_boundary_layer_height, - gravitational_acceleration, - von_karman_constant, - ℂₐ, 𝒬ₒ) - - Δu = differences.u - Δv = differences.v - Δθ = differences.θ - Δq = differences.q - h = differences.h - - FT = eltype(h) - - g = gravitational_acceleration - ϰ = von_karman_constant - - # Extract roughness lengths - ℓu = similarity_theory.roughness_lengths.momentum - β = similarity_theory.gustiness_parameter - zᵢ = atmos_boundary_layer_height - - hᵢ = convert(FT, 10) # Reference Initial height == 10 meters - ℓuᵢ = convert(FT, 1e-4) # Initial roughness length == 1e-4 meters - - # assuming the initial gustiness is `0.5` ms⁻¹ - uτ = sqrt(Δu^2 + Δv^2 + convert(FT, 0.25)) - - # u10 at the reference ten meter height, assuming the initial roughness length is `1e-4` m - u10 = uτ / log(h / ℓuᵢ) * convert(FT, 11.5129) # log(10 / 1e-4) == 11.5129 - u★ = convert(FT, 0.035) * u10 - - ℓu₀ = roughness_length(ℓu, u★, 𝒬ₒ, ℂₐ) - - # Initial neutral coefficients at 10 meter height - χuₙ = (ϰ / log(hᵢ / ℓu₀))^2 - χcₙ = convert(FT, 0.00115) / sqrt(χuₙ) - - # Initial scalar roughness length - ℓθ₀ = hᵢ / exp(ϰ / χcₙ) - - # Neutral transfer coefficients at height `h` - χu = (ϰ / log(h / ℓu₀))^2 - χq = ϰ / log(h / ℓθ₀) - χc = ϰ * χq / χu - - # Similarity functions from Edson et al. (2013) - ψu = InitialMomentumStabilityFunction() - ψθ = similarity_theory.stability_functions.temperature - ψq = similarity_theory.stability_functions.water_vapor - - # Bulk Flux Richardson number - b★ = buoyancy_scale(Δθ, Δq, 𝒬ₒ, ℂₐ, g) - Ri = - ifelse(b★ == 0, zero(b★), h / b★ / uτ^2) - - # Critical Richardson number, TODO: find out what 0.004 refers to - # https://github.com/NOAA-PSL/COARE-algorithm/blob/5b144cf6376a98b42200196d57ae40d791494abe/Matlab/COARE3.6/coare36vn_zrf_et.m#L373 - Riᶜ = - h / zᵢ / convert(FT, 0.004) / β^3 # - h / zi / 0.004 / β^3 - - # Calculating the first stability coefficient and the MO length - # TODO: explain this formulation of the stability function. - # Is it empirical? Found in COARE3.6 - # https://github.com/NOAA-PSL/COARE-algorithm/blob/5b144cf6376a98b42200196d57ae40d791494abe/Matlab/COARE3.6/coare36vn_zrf_et.m#L375 - ζ10 = ifelse(Ri < 0, χc * Ri / (1 + Ri / Riᶜ), χc * Ri * (1 + 27 / 9 * Ri / χc)) - L10 = h / ζ10 - - u★ = uτ * ϰ / similarity_theory.bulk_coefficients(ψu, h, ℓu₀, L10) - θ★ = Δθ * ϰ / similarity_theory.bulk_coefficients(ψθ, h, ℓθ₀, L10) - q★ = Δq * ϰ / similarity_theory.bulk_coefficients(ψq, h, ℓθ₀, L10) - - return SimilarityScales(u★, θ★, q★) -end - # The M-O characteristic length is calculated as # L★ = - u★² / (κ ⋅ b★) # where b★ is the characteristic buoyancy scale calculated from: @@ -330,8 +254,8 @@ end return b★ end -@inline characteristic_velocities(𝒰₁, 𝒰₀, ::WindVelocity) = @inbounds 𝒰₁.u[1] - 𝒰₀.u[1], 𝒰₁.u[2] - 𝒰₀.u[2] -@inline characteristic_velocities(𝒰₁, 𝒰₀, ::RelativeVelocity) = @inbounds 𝒰₁.u[1], 𝒰₁.u[2] +@inline characteristic_velocities(𝒰₁, 𝒰₀, ::RelativeVelocity) = @inbounds 𝒰₁.u[1] - 𝒰₀.u[1], 𝒰₁.u[2] - 𝒰₀.u[2] +@inline characteristic_velocities(𝒰₁, 𝒰₀, ::WindVelocity) = @inbounds 𝒰₁.u[1], 𝒰₁.u[2] @inline function state_differences(ℂ, 𝒰₁, 𝒰₀, g, bulk_velocity) z₁ = 𝒰₁.z @@ -425,4 +349,4 @@ end uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) return SimilarityScales(u★, θ★, q★), uτ -end +end \ No newline at end of file diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index 8769f68d..3f9d974a 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -12,57 +12,69 @@ struct SimilarityScales{U, T, Q} end -(a::SimilarityScales, b::SimilarityScales) = SimilarityScales(a.momentum - b.momentum, - a.temperature - b.temperature, - a.water_vapor - b.water_vapor) + a.temperature - b.temperature, + a.water_vapor - b.water_vapor) Statistics.norm(a::SimilarityScales) = norm(a.momentum) + norm(a.temperature) + norm(a.water_vapor) -# Implementation of stability functions that follow Edson et al (2013) -# We can swap them out easily if we define new types `NewStability` with a method `(f::NewStability)(ζ)` -struct MomentumStabilityFunction end -struct ScalarStabilityFunction end -struct InitialMomentumStabilityFunction end - function default_stability_functions(FT = Float64) # Edson et al. (2013) - ψu = MomentumStabilityFunction() - ψc = ScalarStabilityFunction() + ψu = MomentumStabilityFunction(FT) + ψc = ScalarStabilityFunction(FT) return SimilarityScales(ψu, ψc, ψc) end -@inline function (ψ::InitialMomentumStabilityFunction)(ζ) - FT = eltype(ζ) - - # Parameters - p₁ = convert(FT, 0.35) +# Implementation of stability functions that follow Edson et al (2013) +# We can swap them out easily if we define new types `NewStability` with a method `(f::NewStability)(ζ)` +struct MomentumStabilityFunction{FT} + p₁ :: FT + p₂ :: FT + p₃ :: FT + p₄ :: FT +end - ζ⁻ = min(zero(ζ), ζ) - ζ⁺ = max(zero(ζ), ζ) - dζ = min(50, p₁ * ζ⁺) +struct ScalarStabilityFunction{FT} + p₁ :: FT + p₂ :: FT + p₃ :: FT + p₄ :: FT + p₅ :: FT +end - ψ_stable = - ζ⁺ - 3 / 4 * (ζ⁺ - 5 / p₁) * exp(-dζ) - 3 / 4 * 5 / p₁ - - fₘ = sqrt(sqrt(1 - 18 * ζ⁻)) - ψ_unstable_1 = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2; +function MomentumStabilityFunction(FT = Float64; + p₁ = convert(FT, 0.35), + p₂ = convert(FT, 0.7), + p₃ = convert(FT, 15), + p₄ = convert(FT, 10.15)) - fₘ = cbrt(1 - 10 * ζ⁻) - ψ_unstable_2 = 3 / 2 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3)) + π / sqrt(3) - - f⁻ = ζ⁻^2 / (1 + ζ⁻^2) - ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 + return MomentumStabilityFunction{FT}(convert(FT, p₁), + convert(FT, p₂), + convert(FT, p₃), + convert(FT, p₄)) +end - return ifelse(ζ < 0, ψ_unstable, ψ_stable) +function ScalarStabilityFunction(FT = Float64; + p₁ = convert(FT, 0.35), + p₂ = convert(FT, 14.28), + p₃ = convert(FT, 8.525), + p₄ = convert(FT, 15), + p₅ = convert(FT, 34.15)) + + return ScalarStabilityFunction{FT}(convert(FT, p₁), + convert(FT, p₂), + convert(FT, p₃), + convert(FT, p₄), + convert(FT, p₅)) end @inline function (ψ::MomentumStabilityFunction)(ζ) - FT = eltype(ζ) - # Parameters - p₁ = convert(FT, 0.35) - p₂ = convert(FT, 0.7) - p₃ = convert(FT, 10.15) + p₁ = ψ.p₁ + p₂ = ψ.p₂ + p₃ = ψ.p₃ + p₄ = ψ.p₄ ζ⁻ = min(zero(ζ), ζ) ζ⁺ = max(zero(ζ), ζ) @@ -70,10 +82,10 @@ end ψ_stable = - p₂ * ζ⁺ - 3 / 4 * (ζ⁺ - 5 / p₁) * exp(-dζ) - 3 / 4 * 5 / p₁ - fₘ = sqrt(sqrt(1 - 15 * ζ⁻)) + fₘ = sqrt(sqrt(1 - p₃ * ζ⁻)) ψ_unstable_1 = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2; - fₘ = cbrt(1 - p₃ * ζ⁻) + fₘ = cbrt(1 - p₄ * ζ⁻) ψ_unstable_2 = 1.5 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3))+ π / sqrt(3) f⁻ = ζ⁻^2 / (1 + ζ⁻^2) @@ -83,13 +95,12 @@ end end @inline function (ψ::ScalarStabilityFunction)(ζ) - FT = eltype(ζ) - # Parameters - p₁ = convert(FT, 0.35) - p₂ = convert(FT, 14.28) - p₃ = convert(FT, 8.525) - p₄ = convert(FT, 34.15) + p₁ = ψ.p₁ + p₂ = ψ.p₂ + p₃ = ψ.p₃ + p₄ = ψ.p₄ + p₅ = ψ.p₅ ζ⁻ = min(zero(ζ), ζ) ζ⁺ = max(zero(ζ), ζ) @@ -97,10 +108,10 @@ end ψ_stable = - (4 * ζ⁺ / 3)^(3 / 2) - 2 / 3 * (ζ⁺ - p₂) * exp(-dζ) - p₃ - fₕ = sqrt(1 - 15 * ζ⁻) + fₕ = sqrt(1 - p₄ * ζ⁻) ψ_unstable_1 = 2 * log((1 + fₕ) / 2) - fₕ = cbrt(1 - p₄ * ζ⁻) + fₕ = cbrt(1 - p₅ * ζ⁻) ψ_unstable_2 = 1.5 * log((1 + fₕ + fₕ^2) / 3) - sqrt(3) * atan((1 + 2fₕ) / sqrt(3))+ π / sqrt(3) f⁻ = ζ⁻^2 / (1 + ζ⁻^2) From bccf5dafa0e2daa7e0caa3dc4391cbeed5047d49 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 16 May 2024 07:54:34 -0400 Subject: [PATCH 454/716] remove the WarpedGrid from the omip --- prototype_omip_simulation/tripolar_specific_methods.jl | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index 85c08c7d..a9f59d46 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -19,10 +19,7 @@ using Oceananigans.Grids: cpu_face_constructor_x, topology, λnode, φnode -using OrthogonalSphericalShellGrids: TRG, WRG - -const TField = Field{<:Any, <:Any, <:Any, <:Any, <:TRG} -const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} +using OrthogonalSphericalShellGrids: TRG @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) @@ -30,7 +27,7 @@ const WField = Field{<:Any, <:Any, <:Any, <:Any, <:WRG} import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, convert_to_native_frame # Here we assume that the tripolar grid is locally orthogonal -@inline function convert_to_latlong_frame(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) +@inline function convert_to_latlong_frame(i, j, grid::TRG, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) @@ -39,7 +36,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) end -@inline function convert_to_native_frame(i, j, grid::Union{<:TRG, <:WRG}, uₒ, vₒ) +@inline function convert_to_native_frame(i, j, grid::TRG, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i, j+1, 1, grid, Face(), Center(), Center()) From d9cc663edb05bea805d45b6203c362a0aca3f03e Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 16 May 2024 07:58:52 -0400 Subject: [PATCH 455/716] typo of function name --- prototype_omip_simulation/tripolar_specific_methods.jl | 4 ++-- .../CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index a9f59d46..76a436a6 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -24,10 +24,10 @@ using OrthogonalSphericalShellGrids: TRG @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) -import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlong_frame, convert_to_native_frame +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, convert_to_native_frame # Here we assume that the tripolar grid is locally orthogonal -@inline function convert_to_latlong_frame(i, j, grid::TRG, uₒ, vₒ) +@inline function convert_to_latlon_frame(i, j, grid::TRG, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 139e43b5..751205d5 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -231,7 +231,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) end # Fallback -@inline convert_to_latlon_grid(i, j, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_latlon_frame(i, j, grid, uₒ, vₒ) = uₒ, vₒ @inline convert_to_native_frame(i, j, grid, uₒ, vₒ) = uₒ, vₒ # Fallback! @@ -269,7 +269,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert the native grid velocities to a zonal - meridional # frame of reference (assuming the frame of reference is # latitude - longitude here, we might want to change it) - uₒ, vₒ = convert_to_latlon_grid(i, j, grid, uₒ, vₒ) + uₒ, vₒ = convert_to_latlon_frame(i, j, grid, uₒ, vₒ) @inbounds begin # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) @@ -336,7 +336,6 @@ limit_fluxes_over_sea_ice!(args...) = nothing τˣ, τʸ = convert_to_native_frame(i, j, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) - @inbounds begin # +0: cooling, -0: heating Qv[i, j, 1] = ifelse(inactive, 0, turbulent_fluxes.latent_heat) From a81808d1ae0d1183eacbd2939591d47281ccd588 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 16 May 2024 08:58:32 -0400 Subject: [PATCH 456/716] correct omip --- .../prototype_omip_simulation.jl | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index c494f059..fc8cf3fc 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -11,15 +11,19 @@ using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 using ClimaOcean.ECCO using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere -using ClimaOcean.ECCO: ECCO_restoring_forcing +using ClimaOcean.ECCO: ECCO_restoring_forcing, ECCO4Monthly, ECCO2Daily, ECCOMetadata using ClimaOcean.Bathymetry +using CFTime +using Dates + include("tripolar_specific_methods.jl") +include("xin_kai_vertical_diffusivity.jl") ##### ##### Global Ocean at 1/6th of a degree @@ -28,19 +32,19 @@ include("tripolar_specific_methods.jl") bathymetry_file = nothing # "bathymetry_tmp.jld2" # 60 vertical levels -z_faces = exponential_z_faces(Nz=60, depth=6500) +z_faces = exponential_z_faces(Nz=60, depth=6000) Nx = 2160 Ny = 1100 Nz = length(z_faces) - 1 -arch = CPU() #Distributed(GPU(), partition = Partition(2)) +arch = GPU() #Distributed(GPU(), partition = Partition(2)) grid = TripolarGrid(arch; size = (Nx, Ny, Nz), halo = (7, 7, 7), z = z_faces, - north_poles_latitude = 60, + north_poles_latitude = 55, first_pole_longitude = 75) bottom_height = retrieve_bathymetry(grid, bathymetry_file; @@ -49,7 +53,7 @@ bottom_height = retrieve_bathymetry(grid, bathymetry_file; interpolation_passes = 20, connected_regions_allowed = 0) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) #; active_cells_map = true) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) ##### ##### The Ocean component @@ -61,10 +65,10 @@ const h = Nz / 4.5 @inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) @inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) -free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt = 20minutes) +free_surface = SplitExplicitFreeSurface(grid; substeps = 75) vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = νz) -closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) +closure = XinKaiVerticalDiffusivity() # (RiBasedVerticalDiffusivity(), vertical_diffusivity) # ##### ##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic @@ -72,17 +76,24 @@ closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) @inline mask(λ, φ, z, t) = Int(φ > 75 | φ < -75) -FT = ECCO_restoring_forcing(:temperature; mask, architecture = arch, timescale = 20days) -FS = ECCO_restoring_forcing(:salinity; mask, architecture = arch, timescale = 20days) +dates = DateTimeProlepticGregorian(1992, 1, 4) : Month(1) : DateTimeProlepticGregorian(2017, 12, 1) + +temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) +salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) + +FT = ECCO_restoring_forcing(temperature; mask, architecture = arch, timescale = 20days) +FS = ECCO_restoring_forcing(salinity; mask, architecture = arch, timescale = 20days) forcing = (; T = FT, S = FS) -ocean = ocean_simulation(grid; free_surface, forcing, closure) +ocean = ocean_simulation(grid; free_surface, closure, forcing) model = ocean.model +initial_date = dates[1] + set!(model, - T = ECCOMetadata(:temperature), - S = ECCOMetadata(:salinity)) + T = ECCOMetadata(:temperature, initial_date, ECCO2Daily()), + S = ECCOMetadata(:salinity, initial_date, ECCO2Daily())) ##### ##### The atmosphere @@ -94,7 +105,9 @@ radiation = Radiation(arch) sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +similarity_theory = SimilarityTheoryTurbulentFluxes(grid; bulk_coefficients = simplified_bulk_coefficients) + +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, similarity_theory, radiation) wall_time = [time_ns()] @@ -159,7 +172,7 @@ coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) run!(coupled_simulation) -wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 540, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 800, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations From fc5b1f4680d5edb1689b11dfefce98359921eb2f Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Thu, 16 May 2024 12:46:18 -0400 Subject: [PATCH 457/716] some changes --- prototype_omip_simulation/prototype_omip_simulation.jl | 10 +++++----- prototype_omip_simulation/tripolar_specific_methods.jl | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index fc8cf3fc..1caefb7c 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -11,7 +11,7 @@ using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes, simplified_bulk_coefficients using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 using ClimaOcean.ECCO @@ -23,7 +23,7 @@ using CFTime using Dates include("tripolar_specific_methods.jl") -include("xin_kai_vertical_diffusivity.jl") +# include("xin_kai_vertical_diffusivity.jl") ##### ##### Global Ocean at 1/6th of a degree @@ -38,7 +38,7 @@ Nx = 2160 Ny = 1100 Nz = length(z_faces) - 1 -arch = GPU() #Distributed(GPU(), partition = Partition(2)) +arch = CPU() #Distributed(GPU(), partition = Partition(2)) grid = TripolarGrid(arch; size = (Nx, Ny, Nz), @@ -68,7 +68,7 @@ const h = Nz / 4.5 free_surface = SplitExplicitFreeSurface(grid; substeps = 75) vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = νz) -closure = XinKaiVerticalDiffusivity() # (RiBasedVerticalDiffusivity(), vertical_diffusivity) # +closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) # ##### ##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic @@ -76,7 +76,7 @@ closure = XinKaiVerticalDiffusivity() # (RiBasedVerticalDiffusivity(), vertical_ @inline mask(λ, φ, z, t) = Int(φ > 75 | φ < -75) -dates = DateTimeProlepticGregorian(1992, 1, 4) : Month(1) : DateTimeProlepticGregorian(2017, 12, 1) +dates = DateTimeProlepticGregorian(1992, 1, 4) : Month(1) : DateTimeProlepticGregorian(1992, 4, 1) temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index 0fcf6a69..f1fc4748 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -20,12 +20,11 @@ using Oceananigans.Grids: cpu_face_constructor_x, λnode, φnode using OrthogonalSphericalShellGrids: TRG +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, convert_to_native_frame @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) -import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, convert_to_native_frame - # Here we assume that the tripolar grid is locally orthogonal @inline function convert_to_latlong_frame(i, j, grid::TRG, uₒ, vₒ) φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) From 662b60c331a7f27e1b6e95be2afe2d00bb189f3a Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Sun, 19 May 2024 18:49:59 -0400 Subject: [PATCH 458/716] do not require username and password if file is there --- src/DataWrangling/ecco_metadata.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index bd210a59..edee0041 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -135,15 +135,15 @@ function download_dataset!(metadata::ECCOMetadata; password = get(ENV, "ECCO_PASSWORD", nothing), url = urls(metadata)) - isnothing(username) && throw(ArgumentError("Please provide a username in the ECCO_USERNAME environment variable!")) - isnothing(password) && throw(ArgumentError("Please provide a password in the ECCO_PASSWORD environment variable!")) - for data in metadata filename = file_name(data) shortname = short_name(data) if !isfile(filename) + isnothing(username) && throw(ArgumentError("Please provide a username in the ECCO_USERNAME environment variable!")) + isnothing(password) && throw(ArgumentError("Please provide a password in the ECCO_PASSWORD environment variable!")) + # Version specific download file url if data.version isa ECCO2Monthly || data.version isa ECCO2Daily fileurl = joinpath(url, shortname, filename) From e1486de85a500a56ac7a982b24b1584d41cab555 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 20 May 2024 16:41:53 -0400 Subject: [PATCH 459/716] remove symbols from ECCO restoring --- src/DataWrangling/ecco_restoring.jl | 51 +++++++++++++---------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index ab045586..ec053cb6 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -140,14 +140,11 @@ end ECCO_field_time_series(variable_name::Symbol, version=ECCO4Monthly(); kw...) = ECCO_field_time_series(ECCOMetadata(variable_name, all_ecco_dates(version), version); kw...) -@inline variable_name_from_index(i) = ifelse(i == 1, :T, ifelse(i == 2, :S, ifelse(i == 3, :u, :v))) - -oceananigans_fieldindex = Dict( - :temperature => 1, - :salinity => 2, - :u_velocity => 3, - :v_velocity => 4 -) +oceananigans_fieldname = Dict( + :temperature => :T, + :salinity => :S, + :u_velocity => :u, + :v_velocity => :v) """ struct ECCORestoring{FTS, I, M, N} @@ -161,9 +158,8 @@ A struct representing the ECCO forcing function for a specific field. - `λ`: The timescale. """ -struct ECCORestoring{FTS, I, M, N} +struct ECCORestoring{FTS, M, N} ecco_fts :: FTS - field_idx :: I mask :: M λ :: N end @@ -174,29 +170,27 @@ Adapt.adapt_structure(to, p::ECCORestoring) = Adapt.adapt(to, p.mask), Adapt.adapt(to, p.λ)) -@inline function (p::ECCORestoring)(i, j, k, grid, clock, fields) +@inline function (p::ECCORestoring)(x, y, z, t, var) - # Figure out all the inputs: variable name, time, location, and node - var_name = variable_name_from_index(p.field_idx) - time = Time(clock.time) + # Figure out all the inputs: time, location, and node + time = Time(t) loc = instantiated_location(p.ecco_fts) - X = node(i, j, k, grid, loc...) + X = (x, y, z) # Extracting the ECCO field time series data and parameters - ecco_times = p.ecco_fts.times - ecco_grid = p.ecco_fts.grid - ecco_data = p.ecco_fts.data - ecco_backend = p.ecco_fts.backend - ecco_time_indexing = p.ecco_fts.time_indexing - - # Extracting the field value at the current node - @inbounds var = getproperty(fields, var_name)[i, j, k] - + ecco_times = p.ecco_times + ecco_grid = p.ecco_grid + ecco_data = p.ecco_data + ecco_backend = p.ecco_backend + ecco_time_indexing = p.ecco_time_indexing + # Interpolating the ECCO field time series data ont the current node and time ecco_var = interpolate(X, time, ecco_data, loc, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) # Extracting the mask value at the current node - mask = stateindex(p.mask, i, j, k, grid, clock.time, loc) + # TODO: make this work with numbers, arrays, or functions + # (something like the reverse of `stateindex`) + mask = p.mask(X...) return 1 / p.λ * mask * (ecco_var - var) end @@ -237,11 +231,10 @@ function ECCO_restoring_forcing(metadata::ECCOMetadata; ecco_fts = ECCO_field_time_series(metadata; architecture, time_indices_in_memory, time_indexing) variable_name = metadata.name - field_idx = oceananigans_fieldindex[variable_name] - ecco_restoring = ECCORestoring(ecco_fts, field_idx, mask, timescale) + field_name = oceananigans_fieldname[variable_name] + ecco_restoring = ECCORestoring(ecco_fts, mask, timescale) - restoring_forcing = Forcing(ecco_restoring; - discrete_form=true) + restoring_forcing = Forcing(ecco_restoring; field_dependencies = field_name) return restoring_forcing end \ No newline at end of file From 1dd0dfe4893b5a6892750309f912170d013f491d Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 20 May 2024 16:49:18 -0400 Subject: [PATCH 460/716] add to gitignore --- .gitignore | 1 + src/DataWrangling/ecco_restoring.jl | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 353c5651..1abcd719 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ docs/src/literated/ # environment. # Manifest.toml +*.mat *.nc *.jld2 *.mp4 diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index ec053cb6..8badabc1 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -223,7 +223,7 @@ end function ECCO_restoring_forcing(metadata::ECCOMetadata; architecture = CPU(), - time_indices_in_memory = 2, + time_indices_in_memory = 2, # Not more than this if we want to use GPU! time_indexing = Cyclical(), mask = 1, timescale = 5days) @@ -234,6 +234,7 @@ function ECCO_restoring_forcing(metadata::ECCOMetadata; field_name = oceananigans_fieldname[variable_name] ecco_restoring = ECCORestoring(ecco_fts, mask, timescale) + # Defining the forcing that depends on the restoring field. restoring_forcing = Forcing(ecco_restoring; field_dependencies = field_name) return restoring_forcing From a3ee1c2d62849dee00d840eff02353b2bc61bc75 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 20 May 2024 16:55:50 -0400 Subject: [PATCH 461/716] couple of bugfixes --- src/DataWrangling/ecco_restoring.jl | 10 +++++----- src/OceanSimulations/OceanSimulations.jl | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 8badabc1..24168143 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -178,11 +178,11 @@ Adapt.adapt_structure(to, p::ECCORestoring) = X = (x, y, z) # Extracting the ECCO field time series data and parameters - ecco_times = p.ecco_times - ecco_grid = p.ecco_grid - ecco_data = p.ecco_data - ecco_backend = p.ecco_backend - ecco_time_indexing = p.ecco_time_indexing + ecco_times = p.ecco_fts.times + ecco_grid = p.ecco_fts.grid + ecco_data = p.ecco_fts.data + ecco_backend = p.ecco_fts.backend + ecco_time_indexing = p.ecco_fts.time_indexing # Interpolating the ECCO field time series data ont the current node and time ecco_var = interpolate(X, time, ecco_data, loc, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index ad80770f..9570f654 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -84,7 +84,7 @@ function ocean_simulation(grid; Δt = 5minutes, Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) - forcing = (; u = Fu, v = Fv) + forcing = merge(forcing, (; u = Fu, v = Fv)) # Use the TEOS10 equation of state teos10 = TEOS10EquationOfState(; reference_density) From eba3163970e59db4a2fddce76c64e1ecfd6b409c Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 20 May 2024 17:47:08 -0400 Subject: [PATCH 462/716] couple of bugfixes --- src/DataWrangling/ecco_restoring.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 24168143..b4d46bbc 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -46,7 +46,7 @@ function set!(fts::ECCONetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts. metadata = @inbounds path[t] arch = architecture(fts) - f = inpainted_ecco_field(metadata; architecture = arch, maxiter = 5) + f = inpainted_ecco_field(metadata; architecture = arch) set!(fts[t], f) end @@ -166,7 +166,6 @@ end Adapt.adapt_structure(to, p::ECCORestoring) = ECCORestoring(Adapt.adapt(to, p.ecco_fts), - Adapt.adapt(to, p.field_idx), Adapt.adapt(to, p.mask), Adapt.adapt(to, p.λ)) From 8d2ffdc7b63dff831127ca59cf47fac3c10b4e65 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 20 May 2024 20:15:36 -0400 Subject: [PATCH 463/716] maybe saving the location it works? --- src/DataWrangling/ecco_restoring.jl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index b4d46bbc..22f455b1 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -1,6 +1,6 @@ using Oceananigans.Units using Oceananigans.Grids: node -using Oceananigans.Fields: interpolate!, interpolate, instantiated_location +using Oceananigans.Fields: interpolate!, interpolate, location using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices using Oceananigans.Utils: Time @@ -158,23 +158,25 @@ A struct representing the ECCO forcing function for a specific field. - `λ`: The timescale. """ -struct ECCORestoring{FTS, M, N} +struct ECCORestoring{FTS, L, M, N} ecco_fts :: FTS + location :: L mask :: M λ :: N end Adapt.adapt_structure(to, p::ECCORestoring) = ECCORestoring(Adapt.adapt(to, p.ecco_fts), + Adapt.adapt(to, p.location), Adapt.adapt(to, p.mask), Adapt.adapt(to, p.λ)) @inline function (p::ECCORestoring)(x, y, z, t, var) # Figure out all the inputs: time, location, and node - time = Time(t) - loc = instantiated_location(p.ecco_fts) - X = (x, y, z) + time = Time(t) + loc = p.location + X = (x, y, z) # Extracting the ECCO field time series data and parameters ecco_times = p.ecco_fts.times @@ -229,10 +231,12 @@ function ECCO_restoring_forcing(metadata::ECCOMetadata; ecco_fts = ECCO_field_time_series(metadata; architecture, time_indices_in_memory, time_indexing) + LX, LY, LZ = location(ecco_fts) + loc = (LX(), LY(), LZ()) variable_name = metadata.name field_name = oceananigans_fieldname[variable_name] - ecco_restoring = ECCORestoring(ecco_fts, mask, timescale) - + + ecco_restoring = ECCORestoring(ecco_fts, loc, mask, timescale) # Defining the forcing that depends on the restoring field. restoring_forcing = Forcing(ecco_restoring; field_dependencies = field_name) From 90a17be4129895ad2680e1953ecd8713df67a2af Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 20 May 2024 20:41:51 -0400 Subject: [PATCH 464/716] not sure it will work but it might --- src/DataWrangling/ecco_restoring.jl | 60 ++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 22f455b1..27813102 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -158,24 +158,38 @@ A struct representing the ECCO forcing function for a specific field. - `λ`: The timescale. """ -struct ECCORestoring{FTS, L, M, N} - ecco_fts :: FTS - location :: L - mask :: M - λ :: N +struct ECCORestoring{FTS, M, N} + ecco_fts :: FTS + mask :: M + λ :: N +end + +struct ECCOGPURestoring{D, L, T, G, B, I, M, N} + ecco_data :: D + location :: L + ecco_times :: T + ecco_grid :: G + ecco_backend :: B + ecco_time_indexing :: I + mask :: M + λ :: N end Adapt.adapt_structure(to, p::ECCORestoring) = - ECCORestoring(Adapt.adapt(to, p.ecco_fts), - Adapt.adapt(to, p.location), - Adapt.adapt(to, p.mask), - Adapt.adapt(to, p.λ)) + ECCOGPURestoring(Adapt.adapt(to, p.ecco_fts.data), + Adapt.adapt(to, instantiated_location(p.ecco_fts)), + Adapt.adapt(to, p.ecco_fts.times), + Adapt.adapt(to, p.ecco_fts.grid), + Adapt.adapt(to, p.ecco_fts.backend), + Adapt.adapt(to, p.ecco_fts.time_indexing), + Adapt.adapt(to, p.mask), + Adapt.adapt(to, p.λ)) @inline function (p::ECCORestoring)(x, y, z, t, var) # Figure out all the inputs: time, location, and node time = Time(t) - loc = p.location + loc = instantiated_location(p.ecco_fts) X = (x, y, z) # Extracting the ECCO field time series data and parameters @@ -196,6 +210,32 @@ Adapt.adapt_structure(to, p::ECCORestoring) = return 1 / p.λ * mask * (ecco_var - var) end +@inline function (p::ECCOGPURestoring)(x, y, z, t, var) + + # Figure out all the inputs: time, location, and node + time = Time(t) + loc = p.location + X = (x, y, z) + + # Extracting the ECCO field time series data and parameters + ecco_times = p.ecco_times + ecco_grid = p.ecco_grid + ecco_data = p.ecco_data + ecco_backend = p.ecco_backend + ecco_time_indexing = p.ecco_time_indexing + + # Interpolating the ECCO field time series data ont the current node and time + ecco_var = interpolate(X, time, ecco_data, loc, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) + + # Extracting the mask value at the current node + # TODO: make this work with numbers, arrays, or functions + # (something like the reverse of `stateindex`) + mask = p.mask(X...) + + return 1 / p.λ * mask * (ecco_var - var) +end + + """ ECCO_restoring_forcing(metadata::ECCOMetadata; architecture = CPU(), From c513af2233201dfef7ee9e062fb803731724bb21 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 20 May 2024 20:55:41 -0400 Subject: [PATCH 465/716] bugfix --- src/DataWrangling/ecco_restoring.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 27813102..37cbe365 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -271,12 +271,10 @@ function ECCO_restoring_forcing(metadata::ECCOMetadata; ecco_fts = ECCO_field_time_series(metadata; architecture, time_indices_in_memory, time_indexing) - LX, LY, LZ = location(ecco_fts) - loc = (LX(), LY(), LZ()) variable_name = metadata.name field_name = oceananigans_fieldname[variable_name] - ecco_restoring = ECCORestoring(ecco_fts, loc, mask, timescale) + ecco_restoring = ECCORestoring(ecco_fts, mask, timescale) # Defining the forcing that depends on the restoring field. restoring_forcing = Forcing(ecco_restoring; field_dependencies = field_name) From e82c45bb5e8d59acaca90e178025ac65357534a3 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 20 May 2024 21:10:20 -0400 Subject: [PATCH 466/716] do not restrict oceananigans --- Project.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Project.toml b/Project.toml index 2329cae6..955fe6ca 100644 --- a/Project.toml +++ b/Project.toml @@ -37,7 +37,6 @@ Downloads = "1.6" JLD2 = "0.4" KernelAbstractions = "0.9" NCDatasets = "0.12, 0.13, 0.14" -Oceananigans = "0.90.10" SeawaterPolynomials = "0.3.4" Statistics = "1.9" julia = "1.9" From 51a5778a75913895b9b0173950642bb64a4588c1 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Mon, 20 May 2024 21:15:28 -0400 Subject: [PATCH 467/716] bugfix --- src/DataWrangling/ecco_restoring.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 37cbe365..efd3de6d 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -1,6 +1,6 @@ using Oceananigans.Units using Oceananigans.Grids: node -using Oceananigans.Fields: interpolate!, interpolate, location +using Oceananigans.Fields: interpolate!, interpolate, location, instantiated_location using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices using Oceananigans.Utils: Time From d06ea0bd2bf11256775159315f2e24a16dbdb9e4 Mon Sep 17 00:00:00 2001 From: simone silvestri Date: Tue, 21 May 2024 12:18:41 -0400 Subject: [PATCH 468/716] changes --- prototype_omip_simulation/tripolar_specific_methods.jl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index f1fc4748..1fc06b7e 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -30,9 +30,11 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, c φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) φ₂ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) - θ = φ₂ - φ₁ + θ = φ₂ - φ₁ + d₁ = hack_cosd(θ) + d₂ = hack_sind(θ) - return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) + return uₒ * d₁ - vₒ * d₂, uₒ * d₂ + vₒ * d₁ end @inline function convert_to_native_frame(i, j, grid::TRG, uₒ, vₒ) @@ -40,6 +42,8 @@ end φ₂ = φnode(i, j+1, 1, grid, Face(), Center(), Center()) θ = φ₂ - φ₁ + d₁ = hack_cosd(θ) + d₂ = hack_sind(θ) - return uₒ * hack_cosd(θ) + vₒ * hack_sind(θ), uₒ * hack_sind(θ) + vₒ * hack_cosd(θ) + return uₒ * d₁ + vₒ * d₂, uₒ * d₂ - vₒ * d₁ end From d8f9d5fbd8b7c05a32a4da60eb61b3fa080f458b Mon Sep 17 00:00:00 2001 From: "Gregory L. Wagner" Date: Tue, 21 May 2024 16:44:19 -0600 Subject: [PATCH 469/716] Update pipeline.yml --- .buildkite/pipeline.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index bc136112..918d2786 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -38,3 +38,15 @@ steps: TEST_GROUP: "ecco2" commands: - "julia --project -e 'using Pkg; Pkg.test()'" + + - label: "documentation" + env: + CUDA_VISIBLE_DEVICES: "-1" + JULIA_DEBUG: "Documenter" + # TMPDIR: "$TARTARUS_HOME/tmp" + commands: + - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" + - "julia --color=yes --project=docs/ docs/make.jl" + + - wait: ~ + continue_on_failure: true From da361fef7d47dfacdabc6f78944ad01cc1674d4e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 6 Jun 2024 10:25:51 -0400 Subject: [PATCH 470/716] unify gpu and cpu ecco restorings --- src/DataWrangling/ecco_restoring.jl | 60 +++++------------------------ 1 file changed, 10 insertions(+), 50 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index efd3de6d..70245a86 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -158,32 +158,18 @@ A struct representing the ECCO forcing function for a specific field. - `λ`: The timescale. """ -struct ECCORestoring{FTS, M, N} - ecco_fts :: FTS - mask :: M - λ :: N -end - -struct ECCOGPURestoring{D, L, T, G, B, I, M, N} - ecco_data :: D - location :: L - ecco_times :: T - ecco_grid :: G - ecco_backend :: B - ecco_time_indexing :: I - mask :: M - λ :: N +struct ECCORestoring{FTS, G, M, N} + ecco_fts :: FTS + ecco_grid :: G + mask :: M + λ :: N end Adapt.adapt_structure(to, p::ECCORestoring) = - ECCOGPURestoring(Adapt.adapt(to, p.ecco_fts.data), - Adapt.adapt(to, instantiated_location(p.ecco_fts)), - Adapt.adapt(to, p.ecco_fts.times), - Adapt.adapt(to, p.ecco_fts.grid), - Adapt.adapt(to, p.ecco_fts.backend), - Adapt.adapt(to, p.ecco_fts.time_indexing), - Adapt.adapt(to, p.mask), - Adapt.adapt(to, p.λ)) + ECCORestoring(Adapt.adapt(to, p.ecco_fts), + Adapt.adapt(to, p.grid), + Adapt.adapt(to, p.mask), + Adapt.adapt(to, p.λ)) @inline function (p::ECCORestoring)(x, y, z, t, var) @@ -194,7 +180,7 @@ Adapt.adapt_structure(to, p::ECCORestoring) = # Extracting the ECCO field time series data and parameters ecco_times = p.ecco_fts.times - ecco_grid = p.ecco_fts.grid + ecco_grid = p.ecco_grid ecco_data = p.ecco_fts.data ecco_backend = p.ecco_fts.backend ecco_time_indexing = p.ecco_fts.time_indexing @@ -210,32 +196,6 @@ Adapt.adapt_structure(to, p::ECCORestoring) = return 1 / p.λ * mask * (ecco_var - var) end -@inline function (p::ECCOGPURestoring)(x, y, z, t, var) - - # Figure out all the inputs: time, location, and node - time = Time(t) - loc = p.location - X = (x, y, z) - - # Extracting the ECCO field time series data and parameters - ecco_times = p.ecco_times - ecco_grid = p.ecco_grid - ecco_data = p.ecco_data - ecco_backend = p.ecco_backend - ecco_time_indexing = p.ecco_time_indexing - - # Interpolating the ECCO field time series data ont the current node and time - ecco_var = interpolate(X, time, ecco_data, loc, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) - - # Extracting the mask value at the current node - # TODO: make this work with numbers, arrays, or functions - # (something like the reverse of `stateindex`) - mask = p.mask(X...) - - return 1 / p.λ * mask * (ecco_var - var) -end - - """ ECCO_restoring_forcing(metadata::ECCOMetadata; architecture = CPU(), From b2560eee79d5972cd99bd698b6acd54d011c979a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 6 Jun 2024 10:26:21 -0400 Subject: [PATCH 471/716] some bugfix --- src/DataWrangling/ecco_restoring.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 70245a86..4a637cce 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -229,12 +229,13 @@ function ECCO_restoring_forcing(metadata::ECCOMetadata; mask = 1, timescale = 5days) - ecco_fts = ECCO_field_time_series(metadata; architecture, time_indices_in_memory, time_indexing) + ecco_fts = ECCO_field_time_series(metadata; architecture, time_indices_in_memory, time_indexing) + ecco_grid = ecco_fts.grid variable_name = metadata.name field_name = oceananigans_fieldname[variable_name] - ecco_restoring = ECCORestoring(ecco_fts, mask, timescale) + ecco_restoring = ECCORestoring(ecco_fts, ecco_grid, mask, timescale) # Defining the forcing that depends on the restoring field. restoring_forcing = Forcing(ecco_restoring; field_dependencies = field_name) From 64e63a8bae28423546eca171387bd222242196b5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:13:09 -0400 Subject: [PATCH 472/716] some small changes --- src/DataWrangling/ECCO.jl | 2 ++ src/DataWrangling/ecco_restoring.jl | 4 +++- src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index 984d0e0f..38558078 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -1,6 +1,8 @@ module ECCO export ECCOMetadata, ecco_field, ecco_mask, adjusted_ecco_tracers, initialize! +export ECCO2Monthly, ECCO4Monthly, ECCO2Daily +export ECCO_restoring_forcing using ClimaOcean.DataWrangling: inpaint_mask! using ClimaOcean.InitialConditions: three_dimensional_regrid!, interpolate! diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 4a637cce..8acdb88c 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -222,11 +222,13 @@ function ECCO_restoring_forcing(variable_name::Symbol, version=ECCO4Monthly(); k return ECCO_restoring_forcing(metadata; kw...) end +@inline onefunction(args...) = 1 + function ECCO_restoring_forcing(metadata::ECCOMetadata; architecture = CPU(), time_indices_in_memory = 2, # Not more than this if we want to use GPU! time_indexing = Cyclical(), - mask = 1, + mask = onefunction, timescale = 5days) ecco_fts = ECCO_field_time_series(metadata; architecture, time_indices_in_memory, time_indexing) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index 3f9d974a..a00c2bef 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -112,7 +112,7 @@ end ψ_unstable_1 = 2 * log((1 + fₕ) / 2) fₕ = cbrt(1 - p₅ * ζ⁻) - ψ_unstable_2 = 1.5 * log((1 + fₕ + fₕ^2) / 3) - sqrt(3) * atan((1 + 2fₕ) / sqrt(3))+ π / sqrt(3) + ψ_unstable_2 = 3 / 2 * log((1 + fₕ + fₕ^2) / 3) - sqrt(3) * atan((1 + 2fₕ) / sqrt(3))+ π / sqrt(3) f⁻ = ζ⁻^2 / (1 + ζ⁻^2) ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 From ca269d834b554f059012a9660db03e31f9aeac02 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:50:19 -0400 Subject: [PATCH 473/716] a couple of improvements --- src/ClimaOcean.jl | 1 + src/DataWrangling/ecco_metadata.jl | 8 +- src/DataWrangling/ecco_restoring.jl | 104 ++++++++++-------- .../similarity_theory_turbulent_fluxes.jl | 16 +-- 4 files changed, 72 insertions(+), 57 deletions(-) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 24330b36..15aea16a 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -19,6 +19,7 @@ using Oceananigans.Operators: ℑxyᶠᶜᵃ, ℑxyᶜᶠᵃ using DataDeps using Oceananigans.OutputReaders: GPUAdaptedFieldTimeSeries, FieldTimeSeries +using Oceananigans.Grids: node const SomeKindOfFieldTimeSeries = Union{FieldTimeSeries, GPUAdaptedFieldTimeSeries} diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index edee0041..31fda1ca 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -18,6 +18,12 @@ struct ECCOMetadata{D, V} version :: V end +Base.show(io::IO, metadata::ECCOMetadata) = + print(io, "ECCOMetadata:", '\n', + "├── field: $(metadata.name)", '\n', + "├── dates: $(metadata.dates)", '\n', + "└── data version: $(metadata.version)") + # The default is the ECCO4Monthly dataset at 1992-01-01. ECCOMetadata(name::Symbol; version = ECCO4Monthly()) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), version) @@ -138,7 +144,7 @@ function download_dataset!(metadata::ECCOMetadata; for data in metadata filename = file_name(data) shortname = short_name(data) - + if !isfile(filename) isnothing(username) && throw(ArgumentError("Please provide a username in the ECCO_USERNAME environment variable!")) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 8acdb88c..0cc2f3af 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -15,6 +15,9 @@ using ClimaOcean: stateindex import Oceananigans.Fields: set! import Oceananigans.OutputReaders: new_backend, update_field_time_series! +@inline instantiate(T::DataType) = T() +@inline instantiate(T) = T + struct ECCONetCDFBackend <: AbstractInMemoryBackend{Int} start :: Int length :: Int @@ -83,27 +86,20 @@ function ecco_times(metadata; start_time = first(metadata).dates) end """ - ECCO_field_time_series(metadata::ECCOMetadata; - architecture = CPU(), - time_indices_in_memory = 2, - time_indexing = Cyclical()) + ECCO_field_time_series(metadata::ECCOMetadata; + architecture = CPU(), + time_indices_in_memory = 2, + time_indexing = Cyclical()) Create a field time series object for ECCO data. -Args: +# Arguments: - metadata: An ECCOMetadata object containing information about the ECCO dataset. + +# Keyword Arguments: - architecture: The architecture to use for computations (default: CPU()). - time_indices_in_memory: The number of time indices to keep in memory (default: 2). - time_indexing: The time indexing scheme to use (default: Cyclical()). - -Returns: -- fts: A FieldTimeSeries object representing the ECCO field time series. - -Example: -``` -metadata = ECCOMetadata(...) -fts = ECCO_field_time_series(metadata) -``` """ function ECCO_field_time_series(metadata::ECCOMetadata; architecture = CPU(), @@ -140,43 +136,58 @@ end ECCO_field_time_series(variable_name::Symbol, version=ECCO4Monthly(); kw...) = ECCO_field_time_series(ECCOMetadata(variable_name, all_ecco_dates(version), version); kw...) +# Variable names for restoreable data +struct Temperature end +struct Salinity end +struct UVelocity end +struct VVelocity end + oceananigans_fieldname = Dict( - :temperature => :T, - :salinity => :S, - :u_velocity => :u, - :v_velocity => :v) + :temperature => Temperature(), + :salinity => Salinity(), + :u_velocity => UVelocity(), + :v_velocity => VVelocity()) -""" - struct ECCORestoring{FTS, I, M, N} +@inline Base.getindex(fields, i, j, k, ::Temperature) = @inbounds fields.T[i, j, k] +@inline Base.getindex(fields, i, j, k, ::Salinity) = @inbounds fields.S[i, j, k] +@inline Base.getindex(fields, i, j, k, ::UVelocity) = @inbounds fields.u[i, j, k] +@inline Base.getindex(fields, i, j, k, ::VVelocity) = @inbounds fields.v[i, j, k] -A struct representing the ECCO forcing function for a specific field. +""" + struct ECCORestoring{FTS, G, M, V, N} <: Function -## Fields -- `ecco_fts`: The ECCO field time series data. -- `field_idx`: The index of the field. -- `mask`: The mask value. -- `λ`: The timescale. +A struct representing ECCO restoring. +# Fields +- `ecco_fts`: The ECCO FTS on the native ECCO grid. +- `ecco_grid`: The native ECCO grid to interpolate from. +- `mask`: A mask (could be a number, an array, a function or a field). +- `varname`: The variable name of the variable that needs restoring. +- `λ`: The restoring timescale. """ -struct ECCORestoring{FTS, G, M, N} +struct ECCORestoring{FTS, G, M, V, N} <: Function ecco_fts :: FTS ecco_grid :: G mask :: M + varname :: V λ :: N end - Adapt.adapt_structure(to, p::ECCORestoring) = ECCORestoring(Adapt.adapt(to, p.ecco_fts), - Adapt.adapt(to, p.grid), + Adapt.adapt(to, p.ecco_grid), Adapt.adapt(to, p.mask), + Adapt.adapt(to, p.varname), Adapt.adapt(to, p.λ)) -@inline function (p::ECCORestoring)(x, y, z, t, var) +@inline function (p::ECCORestoring)(i, j, k, grid, clock, fields) # Figure out all the inputs: time, location, and node - time = Time(t) - loc = instantiated_location(p.ecco_fts) - X = (x, y, z) + time = Time(clock.time) + loc = location(p.ecco_fts) + X = node(i, j, k, grid, instantiate.(loc)...) + + # Retrieve the variable to force + @inbounds var = fields[i, j, k, p.varname] # Extracting the ECCO field time series data and parameters ecco_times = p.ecco_fts.times @@ -185,13 +196,11 @@ Adapt.adapt_structure(to, p::ECCORestoring) = ecco_backend = p.ecco_fts.backend ecco_time_indexing = p.ecco_fts.time_indexing - # Interpolating the ECCO field time series data ont the current node and time - ecco_var = interpolate(X, time, ecco_data, loc, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) + # Interpolating the ECCO field time series data onto the current node and time + ecco_var = interpolate(X, time, ecco_data, instantiate.(loc), ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) # Extracting the mask value at the current node - # TODO: make this work with numbers, arrays, or functions - # (something like the reverse of `stateindex`) - mask = p.mask(X...) + mask = stateindex(p.mask, i, j, k, grid, time, loc) return 1 / p.λ * mask * (ecco_var - var) end @@ -206,40 +215,39 @@ end Create a restoring forcing term for ECCO field time series. -## Arguments +# Arguments: - `metadata`: The metadata for the ECCO field time series. + +# Keyword Arguments: - `architecture`: The architecture. - `backend`: The backend. - `time_indexing`: The time indexing. - `mask`: The mask value. - `timescale`: The timescale. - -## Returns -- The restoring forcing term. """ function ECCO_restoring_forcing(variable_name::Symbol, version=ECCO4Monthly(); kw...) metadata = ECCOMetadata(variable_name, all_ecco_dates(version), version) return ECCO_restoring_forcing(metadata; kw...) end -@inline onefunction(args...) = 1 - function ECCO_restoring_forcing(metadata::ECCOMetadata; architecture = CPU(), time_indices_in_memory = 2, # Not more than this if we want to use GPU! time_indexing = Cyclical(), - mask = onefunction, - timescale = 5days) + mask = 1, + timescale = 20days) ecco_fts = ECCO_field_time_series(metadata; architecture, time_indices_in_memory, time_indexing) ecco_grid = ecco_fts.grid + # Grab the correct Oceananigans field to restore variable_name = metadata.name field_name = oceananigans_fieldname[variable_name] - ecco_restoring = ECCORestoring(ecco_fts, ecco_grid, mask, timescale) + ecco_restoring = ECCORestoring(ecco_fts, ecco_grid, mask, field_name, timescale) + # Defining the forcing that depends on the restoring field. - restoring_forcing = Forcing(ecco_restoring; field_dependencies = field_name) + restoring_forcing = Forcing(ecco_restoring; discrete_form = true) return restoring_forcing end \ No newline at end of file diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 1f918ba1..52721115 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -193,14 +193,14 @@ end while iterating(Σ★ - Σ₀, iteration, maxiter, similarity_theory) Σ₀ = Σ★ - Σ★, uτ, = refine_characteristic_scales(Σ★, uτ, - similarity_theory, - surface_state, - differences, - atmos_boundary_layer_height, - thermodynamics_parameters, - gravitational_acceleration, - von_karman_constant) + Σ★, uτ = refine_characteristic_scales(Σ★, uτ, + similarity_theory, + surface_state, + differences, + atmos_boundary_layer_height, + thermodynamics_parameters, + gravitational_acceleration, + von_karman_constant) iteration += 1 end From fd94299127b1a9f2eef0fd7cea156aae56a05a0c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:13:26 -0400 Subject: [PATCH 474/716] better restoring --- src/DataWrangling/ecco_restoring.jl | 73 ++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 0cc2f3af..88544865 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -18,9 +18,11 @@ import Oceananigans.OutputReaders: new_backend, update_field_time_series! @inline instantiate(T::DataType) = T() @inline instantiate(T) = T -struct ECCONetCDFBackend <: AbstractInMemoryBackend{Int} +struct ECCONetCDFBackend{N} <: AbstractInMemoryBackend{Int} start :: Int length :: Int + + ECCONetCDFBackend{N}(start::Int, length::Int) where N = new{N}(start, length) end """ @@ -29,14 +31,17 @@ end Represents an ECCO FieldTimeSeries backed by ECCO native .nc files. Each time instance is stored in an individual file. """ -ECCONetCDFBackend(length) = ECCONetCDFBackend(1, length) +ECCONetCDFBackend(length; on_native_grid = false) = ECCONetCDFBackend{on_native_grid}(1, length) -Base.length(backend::ECCONetCDFBackend) = backend.length +Base.length(backend::ECCONetCDFBackend) = backend.length Base.summary(backend::ECCONetCDFBackend) = string("ECCONetCDFBackend(", backend.start, ", ", backend.length, ")") -const ECCONetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:ECCONetCDFBackend} +const ECCONetCDFFTS{N} = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:ECCONetCDFBackend{N}} where N + +new_backend(::ECCONetCDFBackend{N}, start, length) where N = ECCONetCDFBackend{N}(start, length) -new_backend(::ECCONetCDFBackend, start, length) = ECCONetCDFBackend(start, length) +on_native_grid(::ECCONetCDFBackend{N}) where N = N +on_native_grid(::ECCONetCDFBackend{N}) where N = N function set!(fts::ECCONetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts.name) @@ -50,7 +55,11 @@ function set!(fts::ECCONetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts. arch = architecture(fts) f = inpainted_ecco_field(metadata; architecture = arch) - set!(fts[t], f) + if on_native_grid(backend) + set!(fts[t], f) + else + interpolate!(fts[t], f) + end end fill_halo_regions!(fts) @@ -102,9 +111,10 @@ Create a field time series object for ECCO data. - time_indexing: The time indexing scheme to use (default: Cyclical()). """ function ECCO_field_time_series(metadata::ECCOMetadata; - architecture = CPU(), - time_indices_in_memory = 2, - time_indexing = Cyclical()) + architecture = CPU(), + time_indices_in_memory = 2, + time_indexing = Cyclical(), + grid = nothing) # ECCO data is too chunky to allow other backends backend = ECCONetCDFBackend(time_indices_in_memory) @@ -120,7 +130,9 @@ function ECCO_field_time_series(metadata::ECCOMetadata; boundary_conditions = FieldBoundaryConditions(ECCO_native_grid, location) times = ecco_times(metadata) - fts = FieldTimeSeries{location...}(ECCO_native_grid, times; + fts_grid = isnothing(grid) ? ECCO_native_grid : grid + + fts = FieldTimeSeries{location...}(fts_grid, times; backend, time_indexing, boundary_conditions, @@ -172,6 +184,7 @@ struct ECCORestoring{FTS, G, M, V, N} <: Function varname :: V λ :: N end + Adapt.adapt_structure(to, p::ECCORestoring) = ECCORestoring(Adapt.adapt(to, p.ecco_fts), Adapt.adapt(to, p.ecco_grid), @@ -184,27 +197,42 @@ Adapt.adapt_structure(to, p::ECCORestoring) = # Figure out all the inputs: time, location, and node time = Time(clock.time) loc = location(p.ecco_fts) - X = node(i, j, k, grid, instantiate.(loc)...) # Retrieve the variable to force @inbounds var = fields[i, j, k, p.varname] - # Extracting the ECCO field time series data and parameters - ecco_times = p.ecco_fts.times - ecco_grid = p.ecco_grid - ecco_data = p.ecco_fts.data - ecco_backend = p.ecco_fts.backend - ecco_time_indexing = p.ecco_fts.time_indexing + ecco_backend = p.ecco_fts.backend + native_grid = on_native_grid(ecco_backend) + + ecco_var = get_ecco_variable(Val(native_grid), p.ecco_fts, i, j, k, p.ecco_grid, grid, time) - # Interpolating the ECCO field time series data onto the current node and time - ecco_var = interpolate(X, time, ecco_data, instantiate.(loc), ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) - # Extracting the mask value at the current node mask = stateindex(p.mask, i, j, k, grid, time, loc) return 1 / p.λ * mask * (ecco_var - var) end +# Differentiating between restoring done with an ECCO FTS +# that lives on the native ecco grid, that requires interpolation in space +# _inside_ the restoring function and restoring based on an ECCO +# FTS defined on the model grid that requires only time interpolation +@inline function get_ecco_variable(::Val{true}, ecco_fts, i, j, k, ecco_grid, grid, time) + # Extracting the ECCO field time series data and parameters + ecco_times = ecco_fts.times + ecco_data = ecco_fts.data + ecco_time_indexing = ecco_fts.time_indexing + ecco_backend = ecco_fts.backend + ecco_location = instantiated_location(ecco_fts) + + X = node(i, j, k, grid, ecco_location...) + + # Interpolating the ECCO field time series data onto the current node and time + return interpolate(X, time, ecco_data, ecco_location, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) +end + +# Interpolating the ecco_variable in time +@inline get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) = @inbounds ecco_fts[i, j, k, time] + """ ECCO_restoring_forcing(metadata::ECCOMetadata; architecture = CPU(), @@ -235,9 +263,10 @@ function ECCO_restoring_forcing(metadata::ECCOMetadata; time_indices_in_memory = 2, # Not more than this if we want to use GPU! time_indexing = Cyclical(), mask = 1, - timescale = 20days) + timescale = 20days, + grid = nothing) - ecco_fts = ECCO_field_time_series(metadata; architecture, time_indices_in_memory, time_indexing) + ecco_fts = ECCO_field_time_series(metadata; grid, architecture, time_indices_in_memory, time_indexing) ecco_grid = ecco_fts.grid # Grab the correct Oceananigans field to restore From 934e706333e4c6bac67d641fa3f9f44aed282e29 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:36:06 -0400 Subject: [PATCH 475/716] small test --- examples/ecco_restoring_mediterranean.jl | 203 ++++++++++++++++ .../ecco_immersed_grid.jl | 2 +- .../global_one_degree_restoring.jl | 221 ++++++++++++++++++ 3 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 examples/ecco_restoring_mediterranean.jl create mode 100644 prototype_omip_simulation/global_one_degree_restoring.jl diff --git a/examples/ecco_restoring_mediterranean.jl b/examples/ecco_restoring_mediterranean.jl new file mode 100644 index 00000000..31ca625e --- /dev/null +++ b/examples/ecco_restoring_mediterranean.jl @@ -0,0 +1,203 @@ +using GLMakie +using Oceananigans +using Oceananigans: architecture +using ClimaOcean +using ClimaOcean.ECCO +using ClimaOcean.ECCO: ECCO4Monthly +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity +using Oceananigans.Coriolis: ActiveCellEnstrophyConserving +using Oceananigans.Units +using Printf + +using CFTime +using Dates + +##### +##### Regional Mediterranean grid +##### + +# Domain and Grid size +# +# We construct a grid that represents the Mediterranean sea, +# with a resolution of 1/10th of a degree (roughly 10 km resolution) +λ₁, λ₂ = ( 0, 42) # domain in longitude +φ₁, φ₂ = (30, 45) # domain in latitude +# A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters +z_faces = stretched_vertical_faces(depth = 5000, + surface_layer_Δz = 2.5, + stretching = PowerLawStretching(1.070), + surface_layer_height = 50) + +Nx = 4 * 42 # 1 / 4th of a degree resolution +Ny = 4 * 15 # 1 / 4th of a degree resolution +Nz = length(z_faces) - 1 + +grid = LatitudeLongitudeGrid(CPU(); + size = (Nx, Ny, Nz), + latitude = (φ₁, φ₂), + longitude = (λ₁, λ₂), + z = z_faces, + halo = (7, 7, 7)) + +# Interpolating the bathymetry onto the grid +# +# We regrid the bathymetry onto the grid. +# we allow a minimum depth of 10 meters (all shallower regions are +# considered land) and we use 25 intermediate grids (interpolation_passes = 25) +# Note that more interpolation passes will smooth the bathymetry +bottom_height = regrid_bathymetry(grid, + height_above_water = 1, + minimum_depth = 10, + interpolation_passes = 25, + connected_regions_allowed = 1) + +# Let's use an active cell map to elide computation in inactive cells +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) + +# Correct oceananigans +import Oceananigans.Advection: nothing_to_default + +nothing_to_default(user_value; default) = isnothing(user_value) ? default : user_value + +dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) + +temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) +salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) + +FT = ECCO_restoring_forcing(temperature; timescale = 2days) +FS = ECCO_restoring_forcing(salinity; timescale = 2days) + +# Constructing the model +# +# We construct a model that evolves two tracers, temperature (:T), salinity (:S) +# We do not have convection since the simulation is just slumping to equilibrium so we do not need a turbulence closure +# We select a linear equation of state for buoyancy calculation, and WENO schemes for both tracer and momentum advection. +# The free surface utilizes a split-explicit formulation with a barotropic CFL of 0.75 based on wave speed. +model = HydrostaticFreeSurfaceModel(; grid, + momentum_advection = WENOVectorInvariant(), + tracer_advection = WENO(grid; order = 7), + free_surface = SplitExplicitFreeSurface(grid; cfl = 0.75), + buoyancy = SeawaterBuoyancy(), + tracers = (:T, :S, :c), + # forcing = (T = FT, S = FS), + coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) + +# Initializing the model +# +# the model can be initialized with custom values or with ecco fields. +# In this case, our ECCO dataset has access to a temperature and a salinity +# field, so we initialize T and S from ECCO. +# We initialize our passive tracer with a surface blob near to the coasts of Libia +@info "initializing model" +libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 + +set!(model, c = libia_blob, T = temperature[1], S = salinity[1]) + +fig = Figure() +ax = Axis(fig[1, 1]) +heatmap!(ax, interior(model.tracers.T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) +ax = Axis(fig[1, 2]) +heatmap!(ax, interior(model.tracers.S, :, :, Nz), colorrange = (35, 40), colormap = :haline) + +simulation = Simulation(model, Δt = 10minutes, stop_time = 10*365days) + +function progress(sim) + u, v, w = sim.model.velocities + T, S = sim.model.tracers + + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(T, S): %.2f, %.2f\n", + prettytime(sim.model.clock.time), + sim.model.clock.iteration, + prettytime(sim.Δt), + maximum(abs, u), maximum(abs, v), maximum(abs, w), + maximum(abs, T), maximum(abs, S)) +end + +simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +# Simulation warm up! +# +# We have regridded from a coarse solution (1/4er of a degree) to a +# fine grid (1/15th of a degree). Also, the bathymetry has little mismatches +# that might crash our simulation. We warm up the simulation with a little +# time step for few iterations to allow the solution to adjust to the new_grid +# bathymetry +simulation.Δt = 10 +simulation.stop_iteration = 1000 +run!(simulation) + +# Run the real simulation +# +# Now that the solution has adjusted to the bathymetry we can ramp up the time +# step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.2 +wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 10minutes, max_change = 1.1) + +simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) + +# Let's reset the maximum number of iterations +simulation.stop_iteration = Inf + +simulation.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); + indices = (:, :, Nz), + schedule = TimeInterval(1days), + overwrite_existing = true, + filename = "med_surface_field") + +run!(simulation) + +# Record a video +# +# Let's read the data and record a video of the Mediterranean Sea's surface +# (1) Zonal velocity (u) +# (2) Meridional velocity (v) +# (3) Temperature (T) +# (4) Salinity (S) +u_series = FieldTimeSeries("med_surface_field.jld2", "u") +v_series = FieldTimeSeries("med_surface_field.jld2", "v") +T_series = FieldTimeSeries("med_surface_field.jld2", "T") +S_series = FieldTimeSeries("med_surface_field.jld2", "S") +c_series = FieldTimeSeries("med_surface_field.jld2", "c") +iter = Observable(1) + +u = @lift begin + f = interior(u_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end +v = @lift begin + f = interior(v_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end +T = @lift begin + f = interior(T_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end +S = @lift begin + f = interior(S_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end +c = @lift begin + f = interior(c_series[$iter], :, :, 1) + f[f .== 0] .= NaN + f +end + +fig = Figure() +ax = Axis(fig[1, 1], title = "surface zonal velocity ms⁻¹") +heatmap!(u) +ax = Axis(fig[1, 2], title = "surface meridional velocity ms⁻¹") +heatmap!(v) +ax = Axis(fig[2, 1], title = "surface temperature ᵒC") +heatmap!(T) +ax = Axis(fig[2, 2], title = "surface salinity psu") +heatmap!(S) +ax = Axis(fig[2, 3], title = "passive tracer -") +heatmap!(c) + +GLMakie.record(fig, "mediterranean_video.mp4", 1:length(u_series.times); framerate = 5) do i + @info "recording iteration $i" + iter[] = i +end \ No newline at end of file diff --git a/prototype_omip_simulation/ecco_immersed_grid.jl b/prototype_omip_simulation/ecco_immersed_grid.jl index 0ad2408c..a6d4a0b6 100644 --- a/prototype_omip_simulation/ecco_immersed_grid.jl +++ b/prototype_omip_simulation/ecco_immersed_grid.jl @@ -2,7 +2,7 @@ using Oceananigans.Grids: architecture, location, node, with_halo using ClimaOcean.DataWrangling.ECCO: ecco_mask function ecco_immersed_grid(metadata) - mask = ecco_mask(; metadata) + mask = ecco_mask(metadata) grid = with_halo((3, 3, 3), mask.grid) Nx, Ny, Nz = size(grid) diff --git a/prototype_omip_simulation/global_one_degree_restoring.jl b/prototype_omip_simulation/global_one_degree_restoring.jl new file mode 100644 index 00000000..0f5c8e7c --- /dev/null +++ b/prototype_omip_simulation/global_one_degree_restoring.jl @@ -0,0 +1,221 @@ +using Printf +using Oceananigans +using Oceananigans.Units +using ClimaOcean +using OrthogonalSphericalShellGrids +using Oceananigans +using Oceananigans: architecture +using ClimaOcean +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity +using Oceananigans.Coriolis: ActiveCellEnstrophyConserving +using Oceananigans.Units +using ClimaOcean.OceanSimulations +using ClimaOcean.OceanSeaIceModels +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes, simplified_bulk_coefficients +using ClimaOcean.VerticalGrids: exponential_z_faces +using ClimaOcean.JRA55 +using ClimaOcean.ECCO +using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere +using ClimaOcean.ECCO: ECCO_restoring_forcing, ECCO4Monthly, ECCO2Daily, ECCOMetadata +using ClimaOcean.Bathymetry + +using CFTime +using Dates + +include("tripolar_specific_methods.jl") +# include("xin_kai_vertical_diffusivity.jl") + +##### +##### Global Ocean at 1/6th of a degree +##### + +bathymetry_file = nothing # "bathymetry_tmp.jld2" + +# 60 vertical levels +z_faces = exponential_z_faces(Nz=20, depth=6000) + +Nx = 360 +Ny = 180 +Nz = length(z_faces) - 1 + +arch = CPU() + +grid = TripolarGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = z_faces, + north_poles_latitude = 55, + first_pole_longitude = 75) + +bottom_height = retrieve_bathymetry(grid, bathymetry_file; + minimum_depth = 10, + dir = "./", + interpolation_passes = 20, + connected_regions_allowed = 0) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) + +##### +##### The Ocean component +##### + +const Lz = grid.Lz +const h = Nz / 4.5 + +@inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) +@inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) + +free_surface = SplitExplicitFreeSurface(grid; substeps = 75) +vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = νz) + +closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) # + +##### +##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic +##### + +# Build a mask that goes from 0 to 1 as a cubic function of φ between +# 70 degrees and 90 degrees and zero derivatives at 70 and 90. +x₁ = 70 +x₂ = 90 +y₁ = 0 +y₂ = 1 + +A⁺ = [ x₁^3 x₁^2 x₁ 1 + x₂^3 x₂^2 x₂ 1 + 3*x₁^2 2*x₁ 1 0 + 3*x₂^2 2*x₂ 1 0] + +b⁺ = [y₁, y₂, 0, 0] + +const c⁺ = A⁺ \ b⁺ + +x₁ = - 70 +x₂ = - 90 +y₁ = 0 +y₂ = 1 + +A⁻ = [ x₁^3 x₁^2 x₁ 1 + x₂^3 x₂^2 x₂ 1 + 3*x₁^2 2*x₁ 1 0 + 3*x₂^2 2*x₂ 1 0] + +b⁻ = [y₁, y₂, 0, 0] + +const c⁻ = A⁻ \ b⁻ + +@inline mask(λ, φ, z, t) = ifelse(φ >= 70, c⁺[1] * φ^3 + c⁺[2] * φ^2 + c⁺[3] * φ + c⁺[4], + ifelse(φ <= -70, c⁻[1] * φ^3 + c⁻[2] * φ^2 + c⁻[3] * φ + c⁻[4], 0)) + +dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) + +temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) +salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) + +FT = ECCO_restoring_forcing(temperature; grid, mask, architecture = arch, timescale = 20days) +FS = ECCO_restoring_forcing(salinity; grid, mask, architecture = arch, timescale = 20days) + +forcing = (; T = FT, S = FS) + +tracer_advection = WENO() +momentum_advection = VectorInvariant(vorticity_scheme = WENO(), + divergence_scheme = WENO()) + +ocean = ocean_simulation(grid; free_surface, + closure, + forcing, + momentum_advection, + tracer_advection) +model = ocean.model + +set!(model, + T = ECCOMetadata(:temperature, DateTimeProlepticGregorian(1992, 1, 2), ECCO2Daily()), + S = ECCOMetadata(:salinity, DateTimeProlepticGregorian(1992, 1, 2), ECCO2Daily())) + +##### +##### The atmosphere +##### + +backend = JRA55NetCDFBackend(4) +atmosphere = JRA55_prescribed_atmosphere(arch; backend) +radiation = Radiation(arch) + +sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() + +similarity_theory = SimilarityTheoryTurbulentFluxes(grid; bulk_coefficients = simplified_bulk_coefficients) + +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, similarity_theory, radiation) + +wall_time = [time_ns()] + +function progress(sim) + u, v, w = sim.model.velocities + T, S = sim.model.tracers + + Tmax = maximum(interior(T)) + Tmin = minimum(interior(T)) + umax = maximum(interior(u)), maximum(interior(v)), maximum(interior(w)) + step_time = 1e-9 * (time_ns() - wall_time[1]) + + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", + prettytime(sim.model.clock.time), + sim.model.clock.iteration, + prettytime(sim.Δt), + umax..., Tmax, Tmin, prettytime(step_time)) + + wall_time[1] = time_ns() +end + +ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +fluxes = (u = model.velocities.u.boundary_conditions.top.condition, + v = model.velocities.v.boundary_conditions.top.condition, + T = model.tracers.T.boundary_conditions.top.condition, + S = model.tracers.S.boundary_conditions.top.condition) + +ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, + schedule = TimeInterval(0.5days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "surface_fluxes") + +ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(0.5days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "surface", + indices = (:, :, grid.Nz)) + +ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(10days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "snapshots") + +ocean.output_writers[:checkpoint] = Checkpointer(model, + schedule = TimeInterval(60days), + overwrite_existing = true, + prefix = "checkpoint") + +# Simulation warm up! +ocean.Δt = 10 +ocean.stop_iteration = Inf +wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 1200, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) + +stop_time = 30days + +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) + +run!(coupled_simulation) + +wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 800, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) + +# Let's reset the maximum number of iterations +coupled_model.ocean.stop_time = 7200days +coupled_simulation.stop_time = 7200days +coupled_model.ocean.stop_iteration = Inf +coupled_simulation.stop_iteration = Inf + +run!(coupled_simulation) From 5c1eb98b60a07639e0494a06e5b2b327aa1f0668 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:46:56 -0400 Subject: [PATCH 476/716] add a couple comments --- .../seawater_saturation_specific_humidity.jl | 6 +-- .../similarity_theory_turbulent_fluxes.jl | 44 +++++++++++++++++++ .../CrossRealmFluxes/stability_functions.jl | 6 +++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl b/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl index ee780bd9..069968da 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl @@ -15,7 +15,7 @@ function WaterMoleFraction(FT=Float64) # TODO: find reference for these salinity_constituents = ( - chloride = SalinityConstituent{FT}(35.45, 0.56), + chlorine = 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), @@ -34,13 +34,13 @@ end μ_H₂O = wmf.water_molar_mass # Salinity constituents: Cl, Na, SO₄, Mg - μ_Cl = wmf.salinity_constituents.chloride.molar_mass + μ_Cl = wmf.salinity_constituents.chlorine.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 + ϵ_Cl = wmf.salinity_constituents.chlorine.mass_fraction ϵ_Na = wmf.salinity_constituents.sodium.mass_fraction ϵ_SO₄ = wmf.salinity_constituents.sulfate.mass_fraction ϵ_Mg = wmf.salinity_constituents.magnesium.mass_fraction diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 1f918ba1..dadfe727 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -102,6 +102,50 @@ struct WindVelocity end """ The exchange fluxes depend on the relative velocity between the atmosphere and the ocean """ struct RelativeVelocity end +""" + SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; + gravitational_acceleration = default_gravitational_acceleration, + von_karman_constant = convert(FT, 0.4), + turbulent_prandtl_number = convert(FT, 1), + gustiness_parameter = convert(FT, 6.5), + stability_functions = default_stability_functions(FT), + thermodynamics_parameters = PATP(FT), + water_vapor_saturation = ClasiusClapyeronSaturation(), + water_mole_fraction = convert(FT, 0.98), + roughness_lengths = default_roughness_lengths(FT), + bulk_coefficients = bulk_coefficients, + bulk_velocity = RelativeVelocity(), + tolerance = 1e-8, + maxiter = 100, + fields = nothing) + +`SimilarityTheoryTurbulentFluxes` contains parameters and settings to calculate +sea-air turbulent fluxes using Monin-Obukhov similarity theory. + +Keyword Arguments +================== + +- `gravitational_acceleration`: The gravitational acceleration (default: default_gravitational_acceleration). +- `von_karman_constant`: The von Karman constant (default: 0.4). +- `turbulent_prandtl_number`: The turbulent Prandtl number (default: 1). +- `gustiness_parameter`: The gustiness parameter that accounts for low wind speed areas (default: 6.5). +- `stability_functions`: The stability functions. Default: default_stability_functions(FT) that follow the + formulation of Edson et al (2013). +- `thermodynamics_parameters`: The thermodynamics parameters used to calculate atmospheric stability and + saturation pressure. Default: `PATP`, alias for `PrescribedAtmosphereThermodynamicsParameters`. +- `water_vapor_saturation`: The water vapor saturation law. Default: ClasiusClapyeronSaturation() that follows the + Clasius Clapyeron pressure formulation. +- `water_mole_fraction`: The water mole fraction used to calculate the seawater_saturation_specific_humidity. + Default: 0.98, the rest is assumed to be other substances such as chlorine, sodium sulfide and magnesium. +- `roughness_lengths`: The roughness lengths used to calculate the characteristic scales for momentum, temperature and + water vapor. Default: default_roughness_lengths(FT), formulation taken from Edson et al (2013). +- `bulk_coefficients`: The bulk coefficients. +- `bulk_velocity`: The velocity used to calculate the characteristic scales. Default: RelativeVelocity() (difference between + atmospheric and oceanic speed). +- `tolerance`: The tolerance for convergence (default: 1e-8). +- `maxiter`: The maximum number of iterations (default: 100). +- `fields`: The fields to calculate (default: nothing). +""" function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; gravitational_acceleration = default_gravitational_acceleration, von_karman_constant = convert(FT, 0.4), diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index 3f9d974a..ab0d4983 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -80,6 +80,7 @@ end ζ⁺ = max(zero(ζ), ζ) dζ = min(50, p₁ * ζ⁺) + # stability function for stable atmospheric conditions ψ_stable = - p₂ * ζ⁺ - 3 / 4 * (ζ⁺ - 5 / p₁) * exp(-dζ) - 3 / 4 * 5 / p₁ fₘ = sqrt(sqrt(1 - p₃ * ζ⁻)) @@ -89,6 +90,8 @@ end ψ_unstable_2 = 1.5 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3))+ π / sqrt(3) f⁻ = ζ⁻^2 / (1 + ζ⁻^2) + + # stability function for unstable atmospheric conditions ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 return ifelse(ζ < 0, ψ_unstable, ψ_stable) @@ -106,6 +109,7 @@ end ζ⁺ = max(zero(ζ), ζ) dζ = min(50, p₁ * ζ⁺) + # stability function for stable atmospheric conditions ψ_stable = - (4 * ζ⁺ / 3)^(3 / 2) - 2 / 3 * (ζ⁺ - p₂) * exp(-dζ) - p₃ fₕ = sqrt(1 - p₄ * ζ⁻) @@ -115,6 +119,8 @@ end ψ_unstable_2 = 1.5 * log((1 + fₕ + fₕ^2) / 3) - sqrt(3) * atan((1 + 2fₕ) / sqrt(3))+ π / sqrt(3) f⁻ = ζ⁻^2 / (1 + ζ⁻^2) + + # stability function for unstable atmospheric conditions ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 return ifelse(ζ < 0, ψ_unstable, ψ_stable) From 1205cd9074e31f4c0af326184c1799571887551d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:47:55 -0400 Subject: [PATCH 477/716] fix the example --- prototype_omip_simulation/comparison_to_coare.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_to_coare.jl index a5a0d4fb..3ae8cbc6 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_to_coare.jl @@ -18,7 +18,6 @@ v = ECCO2.ecco2_field(:v_velocity) include("ecco2_immersed_grid.jl") grid = ecco2_immersed_grid() -# Let's leave out the radiation for the moment (too simple to test) atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory(), grid = grid.underlying_grid) ocean = ocean_simulation(grid; momentum_advection = nothing, From e8136bae2820034dfb0b7719420e6e51366fffef Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Sat, 8 Jun 2024 14:59:09 -0400 Subject: [PATCH 478/716] correct prototype --- .../prototype_omip_simulation.jl | 75 +++++++++++++++---- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 1caefb7c..4dc4bdea 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -11,7 +11,7 @@ using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes, simplified_bulk_coefficients +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes using ClimaOcean.VerticalGrids: exponential_z_faces using ClimaOcean.JRA55 using ClimaOcean.ECCO @@ -23,7 +23,7 @@ using CFTime using Dates include("tripolar_specific_methods.jl") -# include("xin_kai_vertical_diffusivity.jl") +include("xin_kai_vertical_diffusivity.jl") ##### ##### Global Ocean at 1/6th of a degree @@ -34,11 +34,11 @@ bathymetry_file = nothing # "bathymetry_tmp.jld2" # 60 vertical levels z_faces = exponential_z_faces(Nz=60, depth=6000) -Nx = 2160 -Ny = 1100 +Nx = 1440 +Ny = 720 Nz = length(z_faces) - 1 -arch = CPU() #Distributed(GPU(), partition = Partition(2)) +arch = GPU() #Distributed(GPU(), partition = Partition(2)) grid = TripolarGrid(arch; size = (Nx, Ny, Nz), @@ -68,21 +68,70 @@ const h = Nz / 4.5 free_surface = SplitExplicitFreeSurface(grid; substeps = 75) vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = νz) -closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) # +closure = XinKaiVerticalDiffusivity() # (RiBasedVerticalDiffusivity(), vertical_diffusivity) # ##### ##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic ##### -@inline mask(λ, φ, z, t) = Int(φ > 75 | φ < -75) +# Build a mask that goes from 0 to 1 as a cubic function of φ between +# 70 degrees and 90 degrees and zero derivatives at 70 and 90. +x₁ = 70 +x₂ = 90 +y₁ = 0 +y₂ = 1 + +A⁺ = [ x₁^3 x₁^2 x₁ 1 + x₂^3 x₂^2 x₂ 1 + 3*x₁^2 2*x₁ 1 0 + 3*x₂^2 2*x₂ 1 0] + +b⁺ = [y₁, y₂, 0, 0] + +const c⁺ = A⁺ \ b⁺ + +x₁ = - 70 +x₂ = - 90 +y₁ = 0 +y₂ = 1 + +A⁻ = [ x₁^3 x₁^2 x₁ 1 + x₂^3 x₂^2 x₂ 1 + 3*x₁^2 2*x₁ 1 0 + 3*x₂^2 2*x₂ 1 0] + +b⁻ = [y₁, y₂, 0, 0] + +const c⁻ = A⁻ \ b⁻ + +struct CubicECCOMask <: Function + c⁺ :: Tuple + c⁻ :: Tuple +end + +using Adapt + +Adapt.adapt_structure(to, m :: CubicECCOMask) = CubicECCOMask(Adapt.adapt(to, m.c⁺), Adapt.adapt(to, m.c⁻)) -dates = DateTimeProlepticGregorian(1992, 1, 4) : Month(1) : DateTimeProlepticGregorian(1992, 4, 1) +@inline function (m :: CubicECCOMask)(λ, φ, z, t) + c⁺ = m.c⁺ + c⁻ = m.c⁻ + + mask = @inbounds ifelse(φ >= 70, c⁺[1] * φ^3 + c⁺[2] * φ^2 + c⁺[3] * φ + c⁺[4], + ifelse(φ <= -70, c⁻[1] * φ^3 + c⁻[2] * φ^2 + c⁻[3] * φ + c⁻[4], 0)) + + return mask +end + +mask = CubicECCOMask(tuple(c⁺...), tuple(c⁻...)) + +dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) -FT = ECCO_restoring_forcing(temperature; mask, architecture = arch, timescale = 20days) -FS = ECCO_restoring_forcing(salinity; mask, architecture = arch, timescale = 20days) +FT = ECCO_restoring_forcing(temperature; mask, grid, architecture = arch, timescale = 30days) +FS = ECCO_restoring_forcing(salinity; mask, grid, architecture = arch, timescale = 30days) forcing = (; T = FT, S = FS) @@ -105,9 +154,7 @@ radiation = Radiation(arch) sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() -similarity_theory = SimilarityTheoryTurbulentFluxes(grid; bulk_coefficients = simplified_bulk_coefficients) - -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, similarity_theory, radiation) +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) wall_time = [time_ns()] @@ -166,7 +213,7 @@ ocean.stop_iteration = 1 wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -stop_time = 30days +stop_time = 15days coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) From ed466dd985bea426a1c81436b1575a78c6f1251f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 8 Jun 2024 15:00:36 -0400 Subject: [PATCH 479/716] try it like this? --- prototype_omip_simulation/prototype_omip_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 4dc4bdea..05fc9aa9 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -111,9 +111,9 @@ end using Adapt -Adapt.adapt_structure(to, m :: CubicECCOMask) = CubicECCOMask(Adapt.adapt(to, m.c⁺), Adapt.adapt(to, m.c⁻)) +Adapt.adapt_structure(to, m::CubicECCOMask) = CubicECCOMask(Adapt.adapt(to, m.c⁺), Adapt.adapt(to, m.c⁻)) -@inline function (m :: CubicECCOMask)(λ, φ, z, t) +@inline function (m::CubicECCOMask)(λ, φ, z, t) c⁺ = m.c⁺ c⁻ = m.c⁻ From 6fd977b86b026af35dbb72a93550fc3c840a2e6c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sat, 8 Jun 2024 16:32:43 -0400 Subject: [PATCH 480/716] try like this --- .../prototype_omip_simulation.jl | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 05fc9aa9..eae32e37 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -59,16 +59,8 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_ ##### The Ocean component ##### -const Lz = grid.Lz -const h = Nz / 4.5 - -@inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) -@inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) - free_surface = SplitExplicitFreeSurface(grid; substeps = 75) -vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = νz) - -closure = XinKaiVerticalDiffusivity() # (RiBasedVerticalDiffusivity(), vertical_diffusivity) # +closure = XinKaiVerticalDiffusivity() ##### ##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic @@ -87,8 +79,7 @@ A⁺ = [ x₁^3 x₁^2 x₁ 1 3*x₂^2 2*x₂ 1 0] b⁺ = [y₁, y₂, 0, 0] - -const c⁺ = A⁺ \ b⁺ +c⁺ = A⁺ \ b⁺ x₁ = - 70 x₂ = - 90 @@ -100,13 +91,12 @@ A⁻ = [ x₁^3 x₁^2 x₁ 1 3*x₁^2 2*x₁ 1 0 3*x₂^2 2*x₂ 1 0] -b⁻ = [y₁, y₂, 0, 0] - -const c⁻ = A⁻ \ b⁻ +b⁻ = [y₁, y₂, 0, 0] +c⁻ = A⁻ \ b⁻ -struct CubicECCOMask <: Function - c⁺ :: Tuple - c⁻ :: Tuple +struct CubicECCOMask{T1, T2} <: Function + c⁺ :: T1 + c⁻ :: T2 end using Adapt @@ -123,7 +113,7 @@ Adapt.adapt_structure(to, m::CubicECCOMask) = CubicECCOMask(Adapt.adapt(to, m.c return mask end -mask = CubicECCOMask(tuple(c⁺...), tuple(c⁻...)) +mask = CubicECCOMask(on_architecture(arch, c⁺), on_architecture(arch, c⁻)) dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) From b4a163ef987d8444e432d881c1a01b0a35fea752 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Sun, 9 Jun 2024 15:33:49 -0400 Subject: [PATCH 481/716] new simulation --- prototype_omip_simulation/prototype_omip_simulation.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index eae32e37..93c2b084 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -5,10 +5,11 @@ using ClimaOcean using OrthogonalSphericalShellGrids using Oceananigans using Oceananigans: architecture -using ClimaOcean +using Oceananigans.Grids: on_architecture using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units +using ClimaOcean using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes @@ -140,7 +141,7 @@ set!(model, backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) -radiation = Radiation(arch) +radiation = Radiation(arch; ocean_albedo = ClimaOcean.OceanSeaIceModels.CrossRealmFluxes.LatitudeDependentAlbedo()) sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() From b3e877ce105885f49c0da7d6147d390007266396 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:36:17 -0400 Subject: [PATCH 482/716] try with custom stateindex --- .../prototype_omip_simulation.jl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 93c2b084..ad844258 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -19,6 +19,9 @@ using ClimaOcean.ECCO using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere using ClimaOcean.ECCO: ECCO_restoring_forcing, ECCO4Monthly, ECCO2Daily, ECCOMetadata using ClimaOcean.Bathymetry +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: LatitudeDependentAlbedo + +import ClimaOcean: stateindex using CFTime using Dates @@ -104,7 +107,7 @@ using Adapt Adapt.adapt_structure(to, m::CubicECCOMask) = CubicECCOMask(Adapt.adapt(to, m.c⁺), Adapt.adapt(to, m.c⁻)) -@inline function (m::CubicECCOMask)(λ, φ, z, t) +@inline function (m::CubicECCOMask)(λ, φ, z) c⁺ = m.c⁺ c⁻ = m.c⁻ @@ -114,8 +117,15 @@ Adapt.adapt_structure(to, m::CubicECCOMask) = CubicECCOMask(Adapt.adapt(to, m.c return mask end +@inline function stateindex(m::CubicECCOMask, i, j, k, grid, args...) + λ, φ, z = node(i, j, k, grid, Center(), Center(), Center()) + return m(λ, φ, z) +end + mask = CubicECCOMask(on_architecture(arch, c⁺), on_architecture(arch, c⁻)) +@show mask + dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) @@ -141,7 +151,7 @@ set!(model, backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) -radiation = Radiation(arch; ocean_albedo = ClimaOcean.OceanSeaIceModels.CrossRealmFluxes.LatitudeDependentAlbedo()) +radiation = Radiation(arch; ocean_albedo = LatitudeDependentAlbedo()) sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() From 0d5535fa1411fcd4ec1f93384cfb9c03b736c2f1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:41:15 -0400 Subject: [PATCH 483/716] near global example --- .../near_global_omip_simulation copy.jl | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 prototype_omip_simulation/near_global_omip_simulation copy.jl diff --git a/prototype_omip_simulation/near_global_omip_simulation copy.jl b/prototype_omip_simulation/near_global_omip_simulation copy.jl new file mode 100644 index 00000000..16969053 --- /dev/null +++ b/prototype_omip_simulation/near_global_omip_simulation copy.jl @@ -0,0 +1,149 @@ +using Printf +using Oceananigans +using Oceananigans.Units +using ClimaOcean +using OrthogonalSphericalShellGrids +using Oceananigans +using Oceananigans: architecture +using ClimaOcean +using ClimaOcean.ECCO2 +using Oceananigans.Units +using ClimaOcean.OceanSimulations +using ClimaOcean.OceanSeaIceModels +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation +using ClimaOcean.VerticalGrids: exponential_z_faces +using ClimaOcean.JRA55 +using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere +using ClimaOcean.Bathymetry + +##### +##### Near - Global Ocean at 1/4th of a degree +##### + +bathymetry_file = nothing # "bathymetry_tmp.jld2" + +# 60 vertical levels +z_faces = exponential_z_faces(Nz=60, depth=6500) + +Nx = 1440 +Ny = 600 +Nz = length(z_faces) - 1 + +arch = GPU() + +grid = LatitudeLongitudeGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = z_faces, + longitude = (0, 360), + latitude = (-75, 75)) + +bottom_height = retrieve_bathymetry(grid, bathymetry_file; + minimum_depth = 10, + dir = "./", + interpolation_passes = 20, + connected_regions_allowed = 0) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) + +##### +##### The Ocean component +##### + +# We retain all the defaults for the ocean model +ocean = ocean_simulation(grid) +model = ocean.model + +set!(model, + T = ECCO2Metadata(:temperature), + S = ECCO2Metadata(:salinity)) + +##### +##### The atmosphere +##### + +backend = JRA55NetCDFBackend(4) +atmosphere = JRA55_prescribed_atmosphere(arch; backend) + +# Tabulated albedo from Payne (1982) +radiation = Radiation(arch) + +# Simplistic sea ice that ensure "no-cooling-fluxes" where `T < T_minimum` +# to change with a thermodynamic sea-ice model +sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() + +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +wall_time = [time_ns()] + +function progress(sim) + u, v, w = sim.model.velocities + T, S = sim.model.tracers + + Tmax = maximum(interior(T)) + Tmin = minimum(interior(T)) + umax = maximum(interior(u)), maximum(interior(v)), maximum(interior(w)) + step_time = 1e-9 * (time_ns() - wall_time[1]) + + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", + prettytime(sim.model.clock.time), + sim.model.clock.iteration, + prettytime(sim.Δt), + umax..., Tmax, Tmin, prettytime(step_time)) + + wall_time[1] = time_ns() +end + +ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +fluxes = (u = model.velocities.u.boundary_conditions.top.condition, + v = model.velocities.v.boundary_conditions.top.condition, + T = model.tracers.T.boundary_conditions.top.condition, + S = model.tracers.S.boundary_conditions.top.condition) + +ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, + schedule = TimeInterval(0.5days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "surface_fluxes") + +ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(0.5days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "surface", + indices = (:, :, grid.Nz)) + +ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(10days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "snapshots") + +ocean.output_writers[:checkpoint] = Checkpointer(model, + schedule = TimeInterval(60days), + overwrite_existing = true, + prefix = "checkpoint") + +# Simulation warm up! +ocean.Δt = 10 +ocean.stop_iteration = 1 +wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) + +stop_time = 30days + +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) + +run!(coupled_simulation) + +wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 540, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) + +# Let's reset the maximum number of iterations +coupled_model.ocean.stop_time = 7200days +coupled_simulation.stop_time = 7200days +coupled_model.ocean.stop_iteration = Inf +coupled_simulation.stop_iteration = Inf + +run!(coupled_simulation) From a8a2d310280c2594c3288904f7f402d1d5c91571 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 15:53:27 -0400 Subject: [PATCH 484/716] prototype on latlong --- ...copy.jl => near_global_omip_simulation.jl} | 82 +++++++++++-------- src/ClimaOcean.jl | 2 + src/VerticalGrids.jl | 5 +- 3 files changed, 56 insertions(+), 33 deletions(-) rename prototype_omip_simulation/{near_global_omip_simulation copy.jl => near_global_omip_simulation.jl} (65%) diff --git a/prototype_omip_simulation/near_global_omip_simulation copy.jl b/prototype_omip_simulation/near_global_omip_simulation.jl similarity index 65% rename from prototype_omip_simulation/near_global_omip_simulation copy.jl rename to prototype_omip_simulation/near_global_omip_simulation.jl index 16969053..0ef09702 100644 --- a/prototype_omip_simulation/near_global_omip_simulation copy.jl +++ b/prototype_omip_simulation/near_global_omip_simulation.jl @@ -1,27 +1,16 @@ using Printf using Oceananigans using Oceananigans.Units -using ClimaOcean -using OrthogonalSphericalShellGrids -using Oceananigans using Oceananigans: architecture using ClimaOcean using ClimaOcean.ECCO2 -using Oceananigans.Units using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation -using ClimaOcean.VerticalGrids: exponential_z_faces -using ClimaOcean.JRA55 -using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere -using ClimaOcean.Bathymetry ##### ##### Near - Global Ocean at 1/4th of a degree ##### -bathymetry_file = nothing # "bathymetry_tmp.jld2" - # 60 vertical levels z_faces = exponential_z_faces(Nz=60, depth=6500) @@ -31,6 +20,7 @@ Nz = length(z_faces) - 1 arch = GPU() +# A near-global grid from 75ᵒ S to 75ᵒ N grid = LatitudeLongitudeGrid(arch; size = (Nx, Ny, Nz), halo = (7, 7, 7), @@ -38,12 +28,16 @@ grid = LatitudeLongitudeGrid(arch; longitude = (0, 360), latitude = (-75, 75)) +# We retrieve the bathymetry from the ETOPO1 data by ensuring a +# minimum depth of 10 meters (everyhting shallower is considered land) +# and removing all connected regions (inland lakes) bottom_height = retrieve_bathymetry(grid, bathymetry_file; minimum_depth = 10, dir = "./", interpolation_passes = 20, connected_regions_allowed = 0) +# An immersed boundary using a staircase representation of bathymetry grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) ##### @@ -54,6 +48,8 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_ ocean = ocean_simulation(grid) model = ocean.model +# We interpolate the initial conditions from the ECCO2 dataset +# (for the moment these are both 1st January 1992) set!(model, T = ECCO2Metadata(:temperature), S = ECCO2Metadata(:salinity)) @@ -62,23 +58,34 @@ set!(model, ##### The atmosphere ##### +# The whole prescribed atmosphere is loaded in memory +# 4 snapshots at the time. backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) -# Tabulated albedo from Payne (1982) +# Tabulated ocean albedo from Payne (1982) +# ocean emissivity is the default 0.97 radiation = Radiation(arch) +##### +##### The atmospheric-forced coupled ocean-seaice model +##### + # Simplistic sea ice that ensure "no-cooling-fluxes" where `T < T_minimum` # to change with a thermodynamic sea-ice model sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() +# The complete coupled model coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) wall_time = [time_ns()] +# We define a progress function that +# shows the maximum values of velocity and temperature +# to make sure everything proceedes as planned function progress(sim) u, v, w = sim.model.velocities - T, S = sim.model.tracers + T = sim.model.tracers.T Tmax = maximum(interior(T)) Tmin = minimum(interior(T)) @@ -101,49 +108,60 @@ fluxes = (u = model.velocities.u.boundary_conditions.top.condition, T = model.tracers.T.boundary_conditions.top.condition, S = model.tracers.S.boundary_conditions.top.condition) -ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, + +output_kwargs = (; overwrite_existing = true, array_type = Array{Float32}) + +# We add a couple of outputs: the surface state every 12 hours, the surface fluxes +# every 12 hours, and the whole state every ten days +ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; schedule = TimeInterval(0.5days), overwrite_existing = true, - array_type = Array{Float32}, - filename = "surface_fluxes") + filename = "surface_fluxes", + output_kwargs...) -ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), +ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); schedule = TimeInterval(0.5days), - overwrite_existing = true, - array_type = Array{Float32}, filename = "surface", - indices = (:, :, grid.Nz)) + indices = (:, :, grid.Nz), + output_kwargs...) -ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(10days), - overwrite_existing = true, - array_type = Array{Float32}, - filename = "snapshots") +ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); + schedule = TimeInterval(10days) + filename = "snapshots", + output_kwargs...) -ocean.output_writers[:checkpoint] = Checkpointer(model, +# Checkpointer for restarting purposes +ocean.output_writers[:checkpoint] = Checkpointer(model; schedule = TimeInterval(60days), overwrite_existing = true, prefix = "checkpoint") -# Simulation warm up! +##### +##### Run the simulation! +##### + +# warm up the simulation to ensure that the model adapts +# to the interpolated initial conditions without crashing ocean.Δt = 10 ocean.stop_iteration = 1 wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -stop_time = 30days - -coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) +# Finally, the coupled simulation! +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time = 30days) run!(coupled_simulation) -wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 540, max_change = 1.1) +# Now that the initial conditions and the initialization shocks have been smoothen out by +# the initial transient, it is time to start the actual simulation! +wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 540, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) -# Let's reset the maximum number of iterations +# Let's reset the maximum number of iterations and specify a 20years stop time coupled_model.ocean.stop_time = 7200days coupled_simulation.stop_time = 7200days coupled_model.ocean.stop_iteration = Inf coupled_simulation.stop_iteration = Inf +# Let's run it! run!(coupled_simulation) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 2786733f..e145b810 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -8,7 +8,9 @@ export JRA55NetCDFBackend, ecco2_field, regrid_bathymetry, + retrieve_bathymetry, stretched_vertical_faces, + exponential_z_faces, PowerLawStretching, LinearStretching, jra55_field_time_series, ecco2_field, ECCO2Metadata, diff --git a/src/VerticalGrids.jl b/src/VerticalGrids.jl index e886cf4a..e569b660 100644 --- a/src/VerticalGrids.jl +++ b/src/VerticalGrids.jl @@ -1,6 +1,9 @@ module VerticalGrids -export stretched_vertical_faces, PowerLawStretching, LinearStretching +export stretched_vertical_faces, + exponential_z_faces, + PowerLawStretching, + LinearStretching struct PowerLawStretching{T} power :: T From 7263d611ada38f5e98fa177611fff88e5dae0675 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 16:07:24 -0400 Subject: [PATCH 485/716] probably better? --- .../prototype_omip_simulation.jl | 52 +++++-------------- 1 file changed, 12 insertions(+), 40 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index ad844258..1a37f4f0 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -85,46 +85,18 @@ A⁺ = [ x₁^3 x₁^2 x₁ 1 b⁺ = [y₁, y₂, 0, 0] c⁺ = A⁺ \ b⁺ -x₁ = - 70 -x₂ = - 90 -y₁ = 0 -y₂ = 1 - -A⁻ = [ x₁^3 x₁^2 x₁ 1 - x₂^3 x₂^2 x₂ 1 - 3*x₁^2 2*x₁ 1 0 - 3*x₂^2 2*x₂ 1 0] - -b⁻ = [y₁, y₂, 0, 0] -c⁻ = A⁻ \ b⁻ - -struct CubicECCOMask{T1, T2} <: Function - c⁺ :: T1 - c⁻ :: T2 -end - -using Adapt - -Adapt.adapt_structure(to, m::CubicECCOMask) = CubicECCOMask(Adapt.adapt(to, m.c⁺), Adapt.adapt(to, m.c⁻)) - -@inline function (m::CubicECCOMask)(λ, φ, z) - c⁺ = m.c⁺ - c⁻ = m.c⁻ - - mask = @inbounds ifelse(φ >= 70, c⁺[1] * φ^3 + c⁺[2] * φ^2 + c⁺[3] * φ + c⁺[4], - ifelse(φ <= -70, c⁻[1] * φ^3 + c⁻[2] * φ^2 + c⁻[3] * φ + c⁻[4], 0)) - - return mask -end - -@inline function stateindex(m::CubicECCOMask, i, j, k, grid, args...) - λ, φ, z = node(i, j, k, grid, Center(), Center(), Center()) - return m(λ, φ, z) -end - -mask = CubicECCOMask(on_architecture(arch, c⁺), on_architecture(arch, c⁻)) - -@show mask +const c₁⁺ = c⁺[1] +const c₂⁺ = c⁺[2] +const c₃⁺ = c⁺[3] +const c₄⁺ = c⁺[4] + +const c₁⁻ = - c⁺[1] +const c₂⁻ = c⁺[2] +const c₃⁻ = - c⁺[3] +const c₄⁻ = c⁺[4] + +@inline mask(λ, φ, z, t) = ifelse(φ >= 70, c₁⁺ * φ^3 + c₂⁺ * φ^2 + c₃⁺ * φ + c₄⁺, + ifelse(φ <= -70, c₁⁻ * φ^3 + c₂⁻ * φ^2 + c₃⁻ * φ + c₄⁻, 0)) dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) From 5f673984e7aee4ef9e5aece68812afa276d18372 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 16:07:33 -0400 Subject: [PATCH 486/716] maybe like this is works --- prototype_omip_simulation/prototype_omip_simulation.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 1a37f4f0..1316cf78 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -85,6 +85,7 @@ A⁺ = [ x₁^3 x₁^2 x₁ 1 b⁺ = [y₁, y₂, 0, 0] c⁺ = A⁺ \ b⁺ +# Coefficients for the cubic mask const c₁⁺ = c⁺[1] const c₂⁺ = c⁺[2] const c₃⁺ = c⁺[3] From 938d39e7eada252c8c762ecd01f2be5d15d344b0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 16:09:18 -0400 Subject: [PATCH 487/716] show the backend --- prototype_omip_simulation/prototype_omip_simulation.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 1316cf78..222079c0 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -107,6 +107,10 @@ salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) FT = ECCO_restoring_forcing(temperature; mask, grid, architecture = arch, timescale = 30days) FS = ECCO_restoring_forcing(salinity; mask, grid, architecture = arch, timescale = 30days) +using ClimaOcean.ECCO: on_native_grid + +@show on_native_grid(FT.func.ecco_fts.backend) + forcing = (; T = FT, S = FS) ocean = ocean_simulation(grid; free_surface, closure, forcing) From 86dc7fcfea84c0093b390d6c7e3749fedf1ced01 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 16:26:41 -0400 Subject: [PATCH 488/716] should it work with the examples like this? --- .buildkite/pipeline.yml | 12 ++- docs/make_examples.jl | 86 +++++++++++++++++++ .../near_global_omip_simulation.jl | 51 ++++++++--- 3 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 docs/make_examples.jl rename {prototype_omip_simulation => examples}/near_global_omip_simulation.jl (83%) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 918d2786..55cd226d 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -5,6 +5,8 @@ agents: env: JULIA_LOAD_PATH: "${JULIA_LOAD_PATH}:${BUILDKITE_BUILD_CHECKOUT_PATH}/.buildkite" + OPENBLAS_NUM_THREADS: 1 + OMPI_MCA_opal_warn_on_missing_libcuda: 0 steps: - label: "initialize" @@ -41,12 +43,14 @@ steps: - label: "documentation" env: - CUDA_VISIBLE_DEVICES: "-1" JULIA_DEBUG: "Documenter" - # TMPDIR: "$TARTARUS_HOME/tmp" commands: - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" - - "julia --color=yes --project=docs/ docs/make.jl" - + - "julia --color=yes --project=docs/ docs/make_examples.jl" + agents: + slurm_mem: 120G + slurm_ntasks: 1 + slurm_gpus_per_task: 1 + - wait: ~ continue_on_failure: true diff --git a/docs/make_examples.jl b/docs/make_examples.jl new file mode 100644 index 00000000..4a51f0bd --- /dev/null +++ b/docs/make_examples.jl @@ -0,0 +1,86 @@ +pushfirst!(LOAD_PATH, joinpath(@__DIR__, "..")) # add ClimaOcean to environment stack + +using + Documenter, + Literate, + ClimaOcean + +ENV["DATADEPS_ALWAYS_ACCEPT"] = "true" + +##### +##### Generate examples +##### + +const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") +const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") + +to_be_literated = [ + "inspect_ecco2_data.jl", + "near_global_omip_simulation.jl" +] + +for file in to_be_literated + filepath = joinpath(EXAMPLES_DIR, file) + Literate.markdown(filepath, OUTPUT_DIR; flavor = Literate.DocumenterFlavor()) +end + +##### +##### Build and deploy docs +##### + +format = Documenter.HTML( + collapselevel = 2, + prettyurls = get(ENV, "CI", nothing) == "true", + canonical = "https://clima.github.io/ClimaOceanDocumentation/dev/", +) + +pages = [ + "Home" => "index.md", + + "Library" => [ + "Contents" => "library/outline.md", + "Public" => "library/public.md", + "Private" => "library/internals.md", + "Function index" => "library/function_index.md", + ], +] + +makedocs( + sitename = "ClimaOcean.jl", + modules = [ClimaOcean], + format = format, + pages = pages, + doctest = true, + clean = true, + warnonly = [:cross_references, :missing_docs], + checkdocs = :exports +) + +@info "Clean up temporary .jld2 and .nc output created by doctests or literated examples..." + +""" + recursive_find(directory, pattern) + +Return list of filepaths within `directory` that contains the `pattern::Regex`. +""" +recursive_find(directory, pattern) = + mapreduce(vcat, walkdir(directory)) do (root, dirs, files) + joinpath.(root, filter(contains(pattern), files)) + end + +files = [] +for pattern in [r"\.jld2", r"\.nc"] + global files = vcat(files, recursive_find(@__DIR__, pattern)) +end + +for file in files + rm(file) +end + +withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do + deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", + versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], + forcepush = true, + devbranch = "main", + push_preview = true) +end diff --git a/prototype_omip_simulation/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl similarity index 83% rename from prototype_omip_simulation/near_global_omip_simulation.jl rename to examples/near_global_omip_simulation.jl index 0ef09702..993c6853 100644 --- a/prototype_omip_simulation/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -11,13 +11,14 @@ using ClimaOcean.OceanSeaIceModels ##### Near - Global Ocean at 1/4th of a degree ##### -# 60 vertical levels -z_faces = exponential_z_faces(Nz=60, depth=6500) +# 40 vertical levels +z_faces = exponential_z_faces(Nz=40, depth=6000) Nx = 1440 Ny = 600 Nz = length(z_faces) - 1 +# Running on a GPU arch = GPU() # A near-global grid from 75ᵒ S to 75ᵒ N @@ -148,20 +149,42 @@ wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) # Finally, the coupled simulation! -coupled_simulation = Simulation(coupled_model; Δt=1, stop_time = 30days) +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time = 20days) run!(coupled_simulation) -# Now that the initial conditions and the initialization shocks have been smoothen out by -# the initial transient, it is time to start the actual simulation! -wizard = TimeStepWizard(; cfl = 0.35, max_Δt = 540, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +##### +##### Visualization +##### -# Let's reset the maximum number of iterations and specify a 20years stop time -coupled_model.ocean.stop_time = 7200days -coupled_simulation.stop_time = 7200days -coupled_model.ocean.stop_iteration = Inf -coupled_simulation.stop_iteration = Inf +using CairoMakie -# Let's run it! -run!(coupled_simulation) +u, v, w = model.velocities +T, S, e = model.tracers + +using Oceananigans.Models.HydrostaticFreeSurfaceModel: VerticalVorticityField + +ζ = VerticalVorticityField(model) +s = Field(sqrt(u^2 + v^2)) + +compute!(ζ) +compute!(s) + +ζ = on_architecture(CPU(), ζ) +s = on_architecture(CPU(), s) +T = on_architecture(CPU(), T) +e = on_architecture(CPU(), e) + +fig = Figure(size = (1000, 800)) + +ax = Axis(fig[1, 1], title = "Vertical vorticity [s⁻¹]") +heatmap!(ax, interior(ζ, :, :, grid.Nz), colorrange = (-4e-5, 4e-5), colormap = :bwr) + +ax = Axis(fig[1, 2], title = "Surface speed [ms⁻¹]") +heatmap!(ax, interior(s, :, :, grid.Nz), colorrange = (0, 0.5), colormap = :deep) + +ax = Axis(fig[2, 1], title = "Surface Temperature [Cᵒ]") +heatmap!(ax, interior(T, :, :, grid.Nz), colorrange = (-1, 30), colormap = :magma) + +ax = Axis(fig[2, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") +heatmap!(ax, interior(e, :, :, grid.Nz), colorrange = (0, 1e-3), colormap = :solar) \ No newline at end of file From dc88b7de6135f3b7deb2db741e65ad68425727f6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 16:56:25 -0400 Subject: [PATCH 489/716] remove docs manifest --- docs/Manifest.toml | 2087 -------------------------------------------- 1 file changed, 2087 deletions(-) delete mode 100644 docs/Manifest.toml diff --git a/docs/Manifest.toml b/docs/Manifest.toml deleted file mode 100644 index efc58ea5..00000000 --- a/docs/Manifest.toml +++ /dev/null @@ -1,2087 +0,0 @@ -# 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.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 = "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.Automa]] -deps = ["PrecompileTools", "TranscodingStreams"] -git-tree-sha1 = "588e0d680ad1d7201d4c6a804dcb1cd9cba79fbb" -uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "1.0.3" - -[[deps.BFloat16s]] -deps = ["LinearAlgebra", "Printf", "Random", "Test"] -git-tree-sha1 = "dbf84058d0a8cbbadee18d25cf606934b22d7c66" -uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" -version = "0.4.2" - -[[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.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.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.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.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.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.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.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.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.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.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.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "d4f85701f569584f2cff7ba67a137d03f0cfb7d0" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.3" - -[[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.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 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.10.0+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.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.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.InverseFunctions]] -deps = ["Test"] -git-tree-sha1 = "68772f49f54b479fa88ace904f6127f0a3bb2e46" -uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.12" - - [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.IterativeSolvers]] -deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] -git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" -uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" -version = "0.9.4" - -[[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]] -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.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.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 = "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 = "c7753cc3febe006708ce6798482004241f7d890b" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.17" - - [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 = "ddab4d40513bce53c8e3157825e245224f74fae7" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.6.0" -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.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.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.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.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.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.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 = "98ca95cf41116a24e46dc9a06fa22b923e8411b7" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.2" - -[[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_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" -uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" -version = "3.1.0+2" - -[[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.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 = "1910b8553f78cdd9a8496f51ea693b3adbd6b984" -repo-rev = "main" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" -uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.9" - - [deps.Oceananigans.extensions] - OceananigansEnzymeExt = "Enzyme" - - [deps.Oceananigans.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - -[[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.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.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.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.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.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.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.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.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.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 = "754acd3031a9f2eaf6632ba4850b1c01fe4460c1" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.1.2" - - [deps.Roots.extensions] - RootsForwardDiffExt = "ForwardDiff" - RootsIntervalRootFindingExt = "IntervalRootFinding" - RootsSymPyExt = "SymPy" - RootsSymPyPythonCallExt = "SymPyPythonCall" - -[[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.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.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.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.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 = "8254d615b8489fb0b9de960c9fae695538802834" -repo-rev = "glw/density-example" -repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" -uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.12.4" - - [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.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.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 = "37195dcb94a5970397ad425b95a9a26d0befce3a" -uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.6.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" From e6c19969f2c1a427fdf1b81358cbf34f3be02dab Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 16:58:15 -0400 Subject: [PATCH 490/716] use correct time in mask --- src/DataWrangling/ecco_restoring.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 88544865..addb945f 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -207,7 +207,7 @@ Adapt.adapt_structure(to, p::ECCORestoring) = ecco_var = get_ecco_variable(Val(native_grid), p.ecco_fts, i, j, k, p.ecco_grid, grid, time) # Extracting the mask value at the current node - mask = stateindex(p.mask, i, j, k, grid, time, loc) + mask = stateindex(p.mask, i, j, k, grid, clock.time, loc) return 1 / p.λ * mask * (ecco_var - var) end From 5007b7c9009ccd5a5328e40bd309710a9c1464ae Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:35:35 -0400 Subject: [PATCH 491/716] bugfixes in docs --- examples/near_global_omip_simulation.jl | 2 +- .../single_column_omip_simulation.jl | 92 +++++++++---------- src/OceanSimulations/OceanSimulations.jl | 16 ++-- 3 files changed, 51 insertions(+), 59 deletions(-) rename {experiments => examples}/single_column_omip_simulation.jl (81%) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 993c6853..29cece5d 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -32,7 +32,7 @@ grid = LatitudeLongitudeGrid(arch; # We retrieve the bathymetry from the ETOPO1 data by ensuring a # minimum depth of 10 meters (everyhting shallower is considered land) # and removing all connected regions (inland lakes) -bottom_height = retrieve_bathymetry(grid, bathymetry_file; +bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, dir = "./", interpolation_passes = 20, diff --git a/experiments/single_column_omip_simulation.jl b/examples/single_column_omip_simulation.jl similarity index 81% rename from experiments/single_column_omip_simulation.jl rename to examples/single_column_omip_simulation.jl index 093b9415..cdb429fe 100644 --- a/experiments/single_column_omip_simulation.jl +++ b/examples/single_column_omip_simulation.jl @@ -4,62 +4,71 @@ using Oceananigans.BuoyancyModels: buoyancy_frequency using Oceananigans.Units: Time using ClimaOcean -using ClimaOcean.DataWrangling.ECCO2: ecco2_column +using ClimaOcean.ECCO2: ECCO2Metadata +using ClimaOcean.OceanSimulations -using GLMakie +using CairoMakie using Printf using Dates -include("omip_components.jl") - locations = ( eastern_mediterranean = (λ = 30, φ = 32), - ocean_station_papa = (λ = 215, φ = 50), + ocean_station_papa = (λ = 35.1, φ = 50.1), north_atlantic = (λ = 325, φ = 50), drake_passage = (λ = 300, φ = -60), weddell_sea = (λ = 325, φ = -70), tasman_southern_ocean = (λ = 145, φ = -55), ) -location = :ocean_station_papa - -start_time = time_ns() - -epoch = Date(1992, 1, 1) -date = Date(1992, 10, 1) -start_seconds = Second(date - epoch).value -Tᵢ = ecco2_field(:temperature, date) -Sᵢ = ecco2_field(:salinity, date) - -elapsed = time_ns() - start_time -@info "Initial condition built. " * prettytime(elapsed * 1e-9) -start_time = time_ns() - ##### ##### Construct the grid ##### -Nz = 80 -H = 400 arch = CPU() -λ★, φ★ = locations[location] -i★, j★, longitude, latitude = ecco2_column(λ★, φ★) -grid = LatitudeLongitudeGrid(arch; longitude, latitude, - size = (1, 1, Nz), +Nz = 80 +H = 400 + +location = :ocean_station_papa + +λ★, φ★ = locations[location] # Ocean station papa location +longitude = λ★ .+ (-0.25, 0.25) +latitude = φ★ .+ (-0.25, 0.25) + +grid = RectilinearGrid(arch; x = longitude, y = latitude, + size = (3, 3, Nz), z = (-H, 0), topology = (Periodic, Periodic, Bounded)) -ocean = omip_ocean_component(grid) +# Building the ocean simulation +momentum_advection = nothing +tracer_advection = nothing +coriolis = FPlane(latitude = φ★) + +ocean = ocean_simulation(grid; + drag_coefficient = 0, + coriolis, + tracer_advection, + momentum_advection) +model = ocean.model + +start_time = time_ns() -backend = JRA55NetCDFBackend(8 * 60) -atmosphere = JRA55_prescribed_atmosphere(:; longitude, latitude, backend) +# Initial conditions +set!(model, T = ECCO2Metadata(:temperature), + S = ECCO2Metadata(:salinity), + e = 1e-6) + +elapsed = time_ns() - start_time +@info "Initial condition built. " * prettytime(elapsed * 1e-9) +start_time = time_ns() + +# Retrieving the atmosphere +backend = NetCDFBackend(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 @@ -134,7 +143,7 @@ Qv = coupled_model.fluxes.turbulent.fields.latent_heat ρₒ = coupled_model.fluxes.ocean_reference_density cₚ = coupled_model.fluxes.ocean_heat_capacity -Q = ρₒ * cₚ * Jᵀ +Q = ρₒ * cₚ * Jᵀ τx = ρₒ * Jᵘ τy = ρₒ * Jᵛ N² = buoyancy_frequency(ocean.model) @@ -148,31 +157,12 @@ 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) #= diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index f1d7ff63..bee46c5e 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -62,6 +62,7 @@ function ocean_simulation(grid; Δt = 5minutes, rotation_rate = Ω_Earth, gravitational_acceleration = g_Earth, drag_coefficient = 0.003, + coriolis = HydrostaticSphericalCoriolis(; rotation_rate), momentum_advection = default_momentum_advection(), tracer_advection = default_tracer_advection(), verbose = false) @@ -80,11 +81,14 @@ function ocean_simulation(grid; Δt = 5minutes, T = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵀ)), S = FieldBoundaryConditions(top = FluxBoundaryCondition(Jˢ))) - Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) - Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) - - forcing = (; u = Fu, v = Fv) - + if !(grid isa ImmersedBoundaryGrid) + forcing = NamedTuple() + else + Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) + Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) + forcing = (; u = Fu, v = Fv) + end + # Use the TEOS10 equation of state teos10 = TEOS10EquationOfState(; reference_density) buoyancy = SeawaterBuoyancy(; gravitational_acceleration, equation_of_state=teos10) @@ -102,8 +106,6 @@ function ocean_simulation(grid; Δt = 5minutes, tracer_advection = (; T = tracer_advection, S = tracer_advection, e = nothing) end - coriolis = HydrostaticSphericalCoriolis(; rotation_rate) - ocean_model = HydrostaticFreeSurfaceModel(; grid, buoyancy, closure, From 285d6145e74448696a2c8b5b295c0dc2ff57c72a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 18:00:06 -0400 Subject: [PATCH 492/716] single column simulation works --- examples/single_column_omip_simulation.jl | 57 +++++++++++++---------- src/DataWrangling/JRA55.jl | 19 +++++--- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/examples/single_column_omip_simulation.jl b/examples/single_column_omip_simulation.jl index cdb429fe..198c1a7f 100644 --- a/examples/single_column_omip_simulation.jl +++ b/examples/single_column_omip_simulation.jl @@ -1,3 +1,17 @@ +# # Single column ocean simulation forced by JRA55 Reananlysis +# +# In this example, we simulate the evolution of an ocean water column +# forced by an atmosphere prescribed by the JRA55 Reananlysis data +# +# ## Install dependencies +# +# First let's make sure we have all required packages installed. + +# ```julia +# using Pkg +# pkg"add Oceananigans, ClimaOcean, CairoMakie" +# ``` + using Oceananigans using Oceananigans.Units using Oceananigans.BuoyancyModels: buoyancy_frequency @@ -11,34 +25,26 @@ using CairoMakie using Printf using Dates -locations = ( - eastern_mediterranean = (λ = 30, φ = 32), - ocean_station_papa = (λ = 35.1, φ = 50.1), - north_atlantic = (λ = 325, φ = 50), - drake_passage = (λ = 300, φ = -60), - weddell_sea = (λ = 325, φ = -70), - tasman_southern_ocean = (λ = 145, φ = -55), -) - ##### ##### Construct the grid ##### +# Since it is a single column, and therefore computationally +# inexpensive, we can run the simulation entirely on the CPU arch = CPU() Nz = 80 H = 400 -location = :ocean_station_papa - -λ★, φ★ = locations[location] # Ocean station papa location +λ★, φ★ = 35.1, 50.1 # Ocean station papa location longitude = λ★ .+ (-0.25, 0.25) latitude = φ★ .+ (-0.25, 0.25) -grid = RectilinearGrid(arch; x = longitude, y = latitude, - size = (3, 3, Nz), - z = (-H, 0), - topology = (Periodic, Periodic, Bounded)) +grid = RectilinearGrid(size = (3, 3, Nz), + x = longitude, + y = latitude, + z = (-H, 0), + topology = (Periodic, Periodic, Bounded)) # Building the ocean simulation momentum_advection = nothing @@ -64,8 +70,10 @@ elapsed = time_ns() - start_time start_time = time_ns() # Retrieving the atmosphere -backend = NetCDFBackend(8 * 60) -atmosphere = JRA55_prescribed_atmosphere(; longitude, latitude, backend) +backend = InMemory() +atmosphere = JRA55_prescribed_atmosphere(time_indices = 1:480; + longitude, latitude, backend, + with_rivers_and_icebergs = false) ocean.model.clock.time = start_seconds ocean.model.clock.iteration = 0 @@ -88,10 +96,9 @@ 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) +coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) +coupled_simulation = Simulation(coupled_model, Δt=10minutes, stop_time=30days) elapsed = time_ns() - start_time @info "Coupled simulation built. " * prettytime(elapsed * 1e-9) @@ -143,13 +150,13 @@ 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ᵛ +Q = ρₒ * cₚ * JT +τx = ρₒ * Ju +τy = ρₒ * Jv N² = buoyancy_frequency(ocean.model) κc = ocean.model.diffusivity_fields.κᶜ -fluxes = (; τx, τy, E, Js, Q, Qc, Qc) +fluxes = (; τx, τy, E, Js, Qv, Qc) auxiliary_fields = (; N², κc) fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 1f545219..b6653ccd 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -589,6 +589,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, time_indexing = Cyclical(), measurement_height = 10, # meters + with_rivers_and_icebergs = true, other_kw...) if isnothing(backend) # apply a default @@ -614,11 +615,21 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); 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...) + if with_rivers_and_icebergs + Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) + Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) + freshwater_flux = (rain = Fra, + snow = Fsn, + rivers = Fri, + icebergs = Fic) + else + freshwater_flux = (rain = Fra, + snow = Fsn) + end + times = ua.times velocities = (u = ua, @@ -628,10 +639,6 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); q = qa, r = ra) - freshwater_flux = (rain = Fra, - snow = Fsn, - rivers = Fri, - icebergs = Fic) pressure = pa From a3bd0e480cf2a05b2d8402e07478c05a0daf2227 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 18:03:23 -0400 Subject: [PATCH 493/716] running --- examples/single_column_omip_simulation.jl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/single_column_omip_simulation.jl b/examples/single_column_omip_simulation.jl index 198c1a7f..0da67e05 100644 --- a/examples/single_column_omip_simulation.jl +++ b/examples/single_column_omip_simulation.jl @@ -2,6 +2,8 @@ # # In this example, we simulate the evolution of an ocean water column # forced by an atmosphere prescribed by the JRA55 Reananlysis data +# Specifically, the column is positioned at the location of the Ocean station +# Papa measurements (144.9ᵒ W and 50.1ᵒ N) # # ## Install dependencies # @@ -36,7 +38,8 @@ arch = CPU() Nz = 80 H = 400 -λ★, φ★ = 35.1, 50.1 # Ocean station papa location +# Ocean station papa location +λ★, φ★ = 35.1, 50.1 longitude = λ★ .+ (-0.25, 0.25) latitude = φ★ .+ (-0.25, 0.25) @@ -107,7 +110,7 @@ start_time = time_ns() wall_clock = Ref(time_ns()) function progress(sim) - msg = string("(", location, ")") + msg = "Ocean Station Papa" msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) elapsed = 1e-9 * (time_ns() - wall_clock[]) @@ -123,9 +126,10 @@ function progress(sim) τˣ = 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) + u★ = sqrt(sqrt(τˣ^2 + τʸ^2)) + Nz = size(T, 3) msg *= @sprintf(", u★: %.2f m s⁻¹", u★) msg *= @sprintf(", Q: %.2f W m⁻²", Q) From 0455ddebfec6a28e270dc962ee9ce957c7d4c0a6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 9 Jun 2024 22:51:17 -0400 Subject: [PATCH 494/716] bugfixes --- examples/near_global_omip_simulation.jl | 2 +- examples/single_column_omip_simulation.jl | 3 ++- src/Bathymetry.jl | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 29cece5d..36d3575c 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -127,7 +127,7 @@ ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, mo output_kwargs...) ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); - schedule = TimeInterval(10days) + schedule = TimeInterval(10days), filename = "snapshots", output_kwargs...) diff --git a/examples/single_column_omip_simulation.jl b/examples/single_column_omip_simulation.jl index 0da67e05..9f7c70d9 100644 --- a/examples/single_column_omip_simulation.jl +++ b/examples/single_column_omip_simulation.jl @@ -25,7 +25,6 @@ using ClimaOcean.OceanSimulations using CairoMakie using Printf -using Dates ##### ##### Construct the grid @@ -43,6 +42,7 @@ H = 400 longitude = λ★ .+ (-0.25, 0.25) latitude = φ★ .+ (-0.25, 0.25) +# We use a SingleColumnGrid grid = RectilinearGrid(size = (3, 3, Nz), x = longitude, y = latitude, @@ -80,6 +80,7 @@ atmosphere = JRA55_prescribed_atmosphere(time_indices = 1:480; ocean.model.clock.time = start_seconds ocean.model.clock.iteration = 0 +ocean.Δt = 10minutes ua = atmosphere.velocities.u va = atmosphere.velocities.v diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 1cc6205d..2ceb8b98 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -350,6 +350,7 @@ function retrieve_bathymetry(grid, filename; kw...) end retrieve_bathymetry(grid, ::Nothing; kw...) = regrid_bathymetry(grid; kw...) +retrieve_bathymetry(grid; kw...) = regrid_bathymetry(grid; kw...) end # module From fb4c35c3629191f815ed6818e015919aeb1e3e50 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:33:19 -0400 Subject: [PATCH 495/716] some restructuring --- .../CrossRealmFluxes/CrossRealmFluxes.jl | 1 + .../atmosphere_ocean_fluxes.jl | 334 ++++++++++++++++++ .../ocean_sea_ice_surface_fluxes.jl | 334 ------------------ 3 files changed, 335 insertions(+), 334 deletions(-) create mode 100644 src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index dd30a57c..98746b64 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -67,6 +67,7 @@ include("stability_functions.jl") include("seawater_saturation_specific_humidity.jl") include("similarity_theory_turbulent_fluxes.jl") include("ocean_sea_ice_surface_fluxes.jl") +include("atmosphere_ocean_fluxes.jl") include("sea_ice_ocean_fluxes.jl") end # module diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl new file mode 100644 index 00000000..7827bc7f --- /dev/null +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -0,0 +1,334 @@ + +##### +##### Surface flux computation +##### + +const c = Center() +const f = Face() + +function compute_atmosphere_ocean_fluxes!(coupled_model) + ocean = coupled_model.ocean + atmosphere = coupled_model.atmosphere + atmosphere_grid = atmosphere.grid + sea_ice = coupled_model.sea_ice + + # Basic model properties + grid = ocean.model.grid + arch = architecture(grid) + clock = coupled_model.clock + + # Ocean, atmosphere, and sea ice state + ocean_velocities = surface_velocities(ocean) + ocean_tracers = surface_tracers(ocean) + + # Fluxes, and flux contributors + centered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.uᶜᶜᶜ, + v = coupled_model.fluxes.total.ocean.momentum.vᶜᶜᶜ) + + staggered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.u, + v = coupled_model.fluxes.total.ocean.momentum.v) + + net_tracer_fluxes = coupled_model.fluxes.total.ocean.tracers + similarity_theory = coupled_model.fluxes.turbulent + radiation_properties = coupled_model.fluxes.radiation + + ocean_state = merge(ocean_velocities, ocean_tracers) + + atmosphere_velocities = map(u -> u.data, atmosphere.velocities) + atmosphere_tracers = map(c -> c.data, atmosphere.tracers) + atmosphere_pressure = atmosphere.pressure.data + + atmosphere_state = merge(atmosphere_velocities, atmosphere_tracers, (; p=atmosphere_pressure)) + freshwater_flux = map(ϕ -> ϕ.data, atmosphere.freshwater_flux) + + u = atmosphere.velocities.u # for example + atmosphere_times = u.times + atmosphere_backend = u.backend + atmosphere_time_indexing = u.time_indexing + + Qs = atmosphere.downwelling_radiation.shortwave + Ql = atmosphere.downwelling_radiation.longwave + + downwelling_radiation = (shortwave=Qs.data, longwave=Ql.data) + + kernel_size = (size(grid, 1) + 2, size(grid, 2) + 2) + + # kernel parameters that compute fluxes in 0:Nx+1 and 0:Ny+1 + kernel_parameters = KernelParameters(kernel_size, (-1, -1)) + + launch!(arch, grid, kernel_parameters, _compute_atmosphere_ocean_similarity_theory_fluxes!, + similarity_theory, + grid, + clock, + ocean_state, + coupled_model.fluxes.ocean_temperature_units, + atmosphere_state, + atmosphere_grid, + atmosphere_times, + atmosphere_backend, + atmosphere_time_indexing, + atmosphere.measurement_height, # height at which the state is known + atmosphere.boundary_layer_height, + atmosphere.thermodynamics_parameters) + + launch!(arch, grid, kernel_parameters, _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) + + limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice, + centered_velocity_fluxes, + net_tracer_fluxes, + ocean_state.T, + ocean_state.S) + + launch!(arch, grid, :xy, reconstruct_momentum_fluxes!, + grid, staggered_velocity_fluxes, centered_velocity_fluxes) + + return nothing +end + +# Fallback +@inline convert_to_latlon_frame(i, j, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_native_frame(i, j, grid, uₒ, vₒ) = uₒ, vₒ + +# Fallback! +limit_fluxes_over_sea_ice!(args...) = nothing + +@kernel function _compute_atmosphere_ocean_similarity_theory_fluxes!(similarity_theory, + grid, + clock, + ocean_state, + ocean_temperature_units, + atmos_state, + atmos_grid, + atmos_times, + atmos_backend, + atmos_time_indexing, + atmosphere_measurement_height, + atmosphere_boundary_layer_height, + atmos_thermodynamics_parameters) + + i, j = @index(Global, NTuple) + kᴺ = size(grid, 3) + + time = Time(clock.time) + + # Extract state variables at cell centers + @inbounds begin + # Ocean state + uₒ = ℑxᶜᵃᵃ(i, j, 1, grid, ocean_state.u) + vₒ = ℑyᵃᶜᵃ(i, j, 1, grid, ocean_state.v) + Tₒ = ocean_state.T[i, j, 1] + Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) + Sₒ = ocean_state.S[i, j, 1] + end + + # Convert the native grid velocities to a zonal - meridional + # frame of reference (assuming the frame of reference is + # latitude - longitude here, we might want to change it) + uₒ, vₒ = convert_to_latlon_frame(i, j, grid, uₒ, vₒ) + + @inbounds begin + # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) + # The third index "k" should not matter but we put the correct index to get + # a surface node anyways. + X = node(i, j, kᴺ + 1, grid, c, c, f) + atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) + + uₐ = interp_atmos_time_series(atmos_state.u, X, time, atmos_args...) + vₐ = interp_atmos_time_series(atmos_state.v, X, time, atmos_args...) + + Tₐ = interp_atmos_time_series(atmos_state.T, X, time, atmos_args...) + pₐ = interp_atmos_time_series(atmos_state.p, X, time, atmos_args...) + qₐ = interp_atmos_time_series(atmos_state.q, X, time, atmos_args...) + end + + # Build thermodynamic and dynamic states in the atmosphere and surface. + # Notation: + # ⋅ 𝒬 ≡ thermodynamic state vector + # ⋅ 𝒰 ≡ "dynamic" state vector (thermodynamics + reference height + velocity) + ℂₐ = atmos_thermodynamics_parameters + 𝒬ₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) + + hₐ = atmosphere_measurement_height # elevation of atmos variables relative to surface + Uₐ = SVector(uₐ, vₐ) + 𝒰ₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, 𝒬ₐ) + + # Build surface state with saturated specific humidity + surface_type = AtmosphericThermodynamics.Liquid() + qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, 𝒬ₐ, + 0.98, #similarity_theory.water_mole_fraction, + ClasiusClapyeronSaturation(), #similarity_theory.water_vapor_saturation, + surface_type) + + # Thermodynamic and dynamic surface state + 𝒬₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₒ, qₒ) + + h₀ = zero(grid) # surface height + Uₒ = SVector(uₒ, vₒ) + 𝒰₀ = dynamic_ocean_state = SurfaceFluxes.StateValues(h₀, Uₒ, 𝒬₀) + + Qv = similarity_theory.fields.latent_heat + Qc = similarity_theory.fields.sensible_heat + Fv = similarity_theory.fields.water_vapor + τx = similarity_theory.fields.x_momentum + τy = similarity_theory.fields.y_momentum + + g = default_gravitational_acceleration + ϰ = similarity_theory.von_karman_constant + + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) + maxiter = ifelse(inactive, 1, similarity_theory.maxiter) + + turbulent_fluxes = compute_similarity_theory_fluxes(similarity_theory, + dynamic_ocean_state, + dynamic_atmos_state, + atmosphere_boundary_layer_height, + ℂₐ, g, ϰ, maxiter) + + kᴺ = size(grid, 3) # index of the top ocean cell + + # Convert back from a zonal - meridional flux to the frame of + # reference of the native ocean grid + τˣ, τʸ = convert_to_native_frame(i, j, grid, turbulent_fluxes.x_momentum, + turbulent_fluxes.y_momentum) + + @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, τˣ) + τy[i, j, 1] = ifelse(inactive, 0, τʸ) + end +end + +@kernel function _assemble_atmosphere_ocean_fluxes!(centered_velocity_fluxes, + net_tracer_fluxes, + grid, + clock, + ocean_temperature, + ocean_salinity, + ocean_temperature_units, + similarity_theory_fields, + downwelling_radiation, + prescribed_freshwater_flux, + atmos_grid, + atmos_times, + atmos_backend, + atmos_time_indexing, + radiation_properties, + ocean_reference_density, + ocean_heat_capacity, + freshwater_density) + + i, j = @index(Global, NTuple) + kᴺ = size(grid, 3) + time = Time(clock.time) + + @inbounds begin + Tₒ = ocean_temperature[i, j, 1] + Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) + Sₒ = ocean_salinity[i, j, 1] + + X = node(i, j, kᴺ + 1, grid, c, c, f) + atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) + + Qs = interp_atmos_time_series(downwelling_radiation.shortwave, X, time, atmos_args...) + Qℓ = interp_atmos_time_series(downwelling_radiation.longwave, X, time, atmos_args...) + + # Accumulate mass fluxes of freshwater due to rain, snow, rivers, + # icebergs, and whatever else. + Mp = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_args...) + + Qc = similarity_theory_fields.sensible_heat[i, j, 1] # sensible or "conductive" heat flux + Qv = similarity_theory_fields.latent_heat[i, j, 1] # latent heat flux + Mv = similarity_theory_fields.water_vapor[i, j, 1] # mass flux of water vapor + τx = similarity_theory_fields.x_momentum[i, j, 1] # zonal momentum flux + τy = similarity_theory_fields.y_momentum[i, j, 1] # meridional momentum flux + end + + # Compute heat fluxes, bulk flux first + Qd = net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation_properties) + Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, Tₒ) + + ΣQ = Qd + Qu + Qc + Qv + + # Convert from a mass flux to a volume flux (aka velocity) + # by dividing by the density of freshwater. + # Also switch the sign, for some reason we are given freshwater flux as positive down. + ρᶠ = freshwater_density + ΣF = - Mp / ρᶠ + + # Add the contribution from the turbulent water vapor flux + Fv = Mv / ρᶠ + ΣF += Fv + + # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes + Jᵘ = centered_velocity_fluxes.u + Jᵛ = centered_velocity_fluxes.v + Jᵀ = net_tracer_fluxes.T + Jˢ = net_tracer_fluxes.S + + ρₒ = ocean_reference_density + cₒ = ocean_heat_capacity + + atmos_ocean_Jᵘ = τx / ρₒ + atmos_ocean_Jᵛ = τy / ρₒ + atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) + atmos_ocean_Jˢ = - Sₒ * ΣF + + # Mask fluxes over land for convenience + inactive = inactive_node(i, j, kᴺ, grid, c, c, c) + + @inbounds begin + Jᵘ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵘ) + Jᵛ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵛ) + Jᵀ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵀ) + Jˢ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jˢ) + end +end + +@kernel function reconstruct_momentum_fluxes!(grid, J, Jᶜᶜᶜ) + i, j = @index(Global, NTuple) + + @inbounds begin + J.u[i, j, 1] = ℑxᶠᵃᵃ(i, j, 1, grid, Jᶜᶜᶜ.u) + J.v[i, j, 1] = ℑyᵃᶠᵃ(i, j, 1, grid, Jᶜᶜᶜ.v) + end +end + +# Fallback for a `Nothing` radiation scheme +@inline net_upwelling_radiation(i, j, grid, time, ::Nothing, Tₒ) = zero(grid) +@inline net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, ::Nothing) = zero(grid) + +@inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) + α = stateindex(radiation.reflection.ocean, i, j, 1, grid, time) + ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) + + return @inbounds - (1 - α) * Qs - ϵ * Qℓ +end + +@inline function net_upwelling_radiation(i, j, grid, time, radiation, Tₒ) + σ = radiation.stefan_boltzmann_constant + ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) + + # Note: positive implies _upward_ heat flux, and therefore cooling. + return ϵ * σ * Tₒ^4 +end \ No newline at end of file diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl index 751205d5..61899ac1 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/ocean_sea_ice_surface_fluxes.jl @@ -125,340 +125,6 @@ function OceanSeaIceSurfaceFluxes(ocean, sea_ice=nothing; freshwater_density, ocean_temperature_units) end - -##### -##### Surface flux computation -##### - -const c = Center() -const f = Face() - -function compute_atmosphere_ocean_fluxes!(coupled_model) - ocean = coupled_model.ocean - atmosphere = coupled_model.atmosphere - atmosphere_grid = atmosphere.grid - sea_ice = coupled_model.sea_ice - - # Basic model properties - grid = ocean.model.grid - arch = architecture(grid) - clock = coupled_model.clock - - # Ocean, atmosphere, and sea ice state - ocean_velocities = surface_velocities(ocean) - ocean_tracers = surface_tracers(ocean) - - # Fluxes, and flux contributors - centered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.uᶜᶜᶜ, - v = coupled_model.fluxes.total.ocean.momentum.vᶜᶜᶜ) - - staggered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.u, - v = coupled_model.fluxes.total.ocean.momentum.v) - - net_tracer_fluxes = coupled_model.fluxes.total.ocean.tracers - similarity_theory = coupled_model.fluxes.turbulent - radiation_properties = coupled_model.fluxes.radiation - - ocean_state = merge(ocean_velocities, ocean_tracers) - - atmosphere_velocities = map(u -> u.data, atmosphere.velocities) - atmosphere_tracers = map(c -> c.data, atmosphere.tracers) - atmosphere_pressure = atmosphere.pressure.data - - atmosphere_state = merge(atmosphere_velocities, atmosphere_tracers, (; p=atmosphere_pressure)) - freshwater_flux = map(ϕ -> ϕ.data, atmosphere.freshwater_flux) - - u = atmosphere.velocities.u # for example - atmosphere_times = u.times - atmosphere_backend = u.backend - atmosphere_time_indexing = u.time_indexing - - Qs = atmosphere.downwelling_radiation.shortwave - Ql = atmosphere.downwelling_radiation.longwave - - downwelling_radiation = (shortwave=Qs.data, longwave=Ql.data) - - kernel_size = (size(grid, 1) + 2, size(grid, 2) + 2) - - # kernel parameters that compute fluxes in 0:Nx+1 and 0:Ny+1 - kernel_parameters = KernelParameters(kernel_size, (-1, -1)) - - launch!(arch, grid, kernel_parameters, _compute_atmosphere_ocean_similarity_theory_fluxes!, - similarity_theory, - grid, - clock, - ocean_state, - coupled_model.fluxes.ocean_temperature_units, - atmosphere_state, - atmosphere_grid, - atmosphere_times, - atmosphere_backend, - atmosphere_time_indexing, - atmosphere.measurement_height, # height at which the state is known - atmosphere.boundary_layer_height, - atmosphere.thermodynamics_parameters) - - launch!(arch, grid, kernel_parameters, _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) - - limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice, - centered_velocity_fluxes, - net_tracer_fluxes, - ocean_state.T, - ocean_state.S) - - launch!(arch, grid, :xy, reconstruct_momentum_fluxes!, - grid, staggered_velocity_fluxes, centered_velocity_fluxes) - - return nothing -end - -# Fallback -@inline convert_to_latlon_frame(i, j, grid, uₒ, vₒ) = uₒ, vₒ -@inline convert_to_native_frame(i, j, grid, uₒ, vₒ) = uₒ, vₒ - -# Fallback! -limit_fluxes_over_sea_ice!(args...) = nothing - -@kernel function _compute_atmosphere_ocean_similarity_theory_fluxes!(similarity_theory, - grid, - clock, - ocean_state, - ocean_temperature_units, - atmos_state, - atmos_grid, - atmos_times, - atmos_backend, - atmos_time_indexing, - atmosphere_measurement_height, - atmosphere_boundary_layer_height, - atmos_thermodynamics_parameters) - - i, j = @index(Global, NTuple) - kᴺ = size(grid, 3) - - time = Time(clock.time) - - # Extract state variables at cell centers - @inbounds begin - # Ocean state - uₒ = ℑxᶜᵃᵃ(i, j, 1, grid, ocean_state.u) - vₒ = ℑyᵃᶜᵃ(i, j, 1, grid, ocean_state.v) - Tₒ = ocean_state.T[i, j, 1] - Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) - Sₒ = ocean_state.S[i, j, 1] - end - - # Convert the native grid velocities to a zonal - meridional - # frame of reference (assuming the frame of reference is - # latitude - longitude here, we might want to change it) - uₒ, vₒ = convert_to_latlon_frame(i, j, grid, uₒ, vₒ) - - @inbounds begin - # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) - # The third index "k" should not matter but we put the correct index to get - # a surface node anyways. - X = node(i, j, kᴺ + 1, grid, c, c, f) - atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) - - uₐ = interp_atmos_time_series(atmos_state.u, X, time, atmos_args...) - vₐ = interp_atmos_time_series(atmos_state.v, X, time, atmos_args...) - - Tₐ = interp_atmos_time_series(atmos_state.T, X, time, atmos_args...) - pₐ = interp_atmos_time_series(atmos_state.p, X, time, atmos_args...) - qₐ = interp_atmos_time_series(atmos_state.q, X, time, atmos_args...) - end - - # Build thermodynamic and dynamic states in the atmosphere and surface. - # Notation: - # ⋅ 𝒬 ≡ thermodynamic state vector - # ⋅ 𝒰 ≡ "dynamic" state vector (thermodynamics + reference height + velocity) - ℂₐ = atmos_thermodynamics_parameters - 𝒬ₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) - - hₐ = atmosphere_measurement_height # elevation of atmos variables relative to surface - Uₐ = SVector(uₐ, vₐ) - 𝒰ₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, 𝒬ₐ) - - # Build surface state with saturated specific humidity - surface_type = AtmosphericThermodynamics.Liquid() - qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, 𝒬ₐ, - 0.98, #similarity_theory.water_mole_fraction, - ClasiusClapyeronSaturation(), #similarity_theory.water_vapor_saturation, - surface_type) - - # Thermodynamic and dynamic surface state - 𝒬₀ = thermodynamic_surface_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₒ, qₒ) - - h₀ = zero(grid) # surface height - Uₒ = SVector(uₒ, vₒ) - 𝒰₀ = dynamic_ocean_state = SurfaceFluxes.StateValues(h₀, Uₒ, 𝒬₀) - - Qv = similarity_theory.fields.latent_heat - Qc = similarity_theory.fields.sensible_heat - Fv = similarity_theory.fields.water_vapor - τx = similarity_theory.fields.x_momentum - τy = similarity_theory.fields.y_momentum - - g = default_gravitational_acceleration - ϰ = similarity_theory.von_karman_constant - - inactive = inactive_node(i, j, kᴺ, grid, c, c, c) - maxiter = ifelse(inactive, 1, similarity_theory.maxiter) - - turbulent_fluxes = compute_similarity_theory_fluxes(similarity_theory, - dynamic_ocean_state, - dynamic_atmos_state, - atmosphere_boundary_layer_height, - ℂₐ, g, ϰ, maxiter) - - kᴺ = size(grid, 3) # index of the top ocean cell - - # Convert back from a zonal - meridional flux to the frame of - # reference of the native ocean grid - τˣ, τʸ = convert_to_native_frame(i, j, grid, turbulent_fluxes.x_momentum, - turbulent_fluxes.y_momentum) - - @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, τˣ) - τy[i, j, 1] = ifelse(inactive, 0, τʸ) - end -end - -@kernel function _assemble_atmosphere_ocean_fluxes!(centered_velocity_fluxes, - net_tracer_fluxes, - grid, - clock, - ocean_temperature, - ocean_salinity, - ocean_temperature_units, - similarity_theory_fields, - downwelling_radiation, - prescribed_freshwater_flux, - atmos_grid, - atmos_times, - atmos_backend, - atmos_time_indexing, - radiation_properties, - ocean_reference_density, - ocean_heat_capacity, - freshwater_density) - - i, j = @index(Global, NTuple) - kᴺ = size(grid, 3) - time = Time(clock.time) - - @inbounds begin - Tₒ = ocean_temperature[i, j, 1] - Tₒ = convert_to_kelvin(ocean_temperature_units, Tₒ) - Sₒ = ocean_salinity[i, j, 1] - - X = node(i, j, kᴺ + 1, grid, c, c, f) - atmos_args = (atmos_grid, atmos_times, atmos_backend, atmos_time_indexing) - - Qs = interp_atmos_time_series(downwelling_radiation.shortwave, X, time, atmos_args...) - Qℓ = interp_atmos_time_series(downwelling_radiation.longwave, X, time, atmos_args...) - - # Accumulate mass fluxes of freshwater due to rain, snow, rivers, - # icebergs, and whatever else. - Mp = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_args...) - - Qc = similarity_theory_fields.sensible_heat[i, j, 1] # sensible or "conductive" heat flux - Qv = similarity_theory_fields.latent_heat[i, j, 1] # latent heat flux - Mv = similarity_theory_fields.water_vapor[i, j, 1] # mass flux of water vapor - τx = similarity_theory_fields.x_momentum[i, j, 1] # zonal momentum flux - τy = similarity_theory_fields.y_momentum[i, j, 1] # meridional momentum flux - end - - # Compute heat fluxes, bulk flux first - Qd = net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation_properties) - Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, Tₒ) - - ΣQ = Qd + Qu + Qc + Qv - - # Convert from a mass flux to a volume flux (aka velocity) - # by dividing by the density of freshwater. - # Also switch the sign, for some reason we are given freshwater flux as positive down. - ρᶠ = freshwater_density - ΣF = - Mp / ρᶠ - - # Add the contribution from the turbulent water vapor flux - Fv = Mv / ρᶠ - ΣF += Fv - - # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes - Jᵘ = centered_velocity_fluxes.u - Jᵛ = centered_velocity_fluxes.v - Jᵀ = net_tracer_fluxes.T - Jˢ = net_tracer_fluxes.S - - ρₒ = ocean_reference_density - cₒ = ocean_heat_capacity - - atmos_ocean_Jᵘ = τx / ρₒ - atmos_ocean_Jᵛ = τy / ρₒ - atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) - atmos_ocean_Jˢ = - Sₒ * ΣF - - # Mask fluxes over land for convenience - inactive = inactive_node(i, j, kᴺ, grid, c, c, c) - - @inbounds begin - Jᵘ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵘ) - Jᵛ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵛ) - Jᵀ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jᵀ) - Jˢ[i, j, 1] = ifelse(inactive, 0, atmos_ocean_Jˢ) - end -end - -@kernel function reconstruct_momentum_fluxes!(grid, J, Jᶜᶜᶜ) - i, j = @index(Global, NTuple) - - @inbounds begin - J.u[i, j, 1] = ℑxᶠᵃᵃ(i, j, 1, grid, Jᶜᶜᶜ.u) - J.v[i, j, 1] = ℑyᵃᶠᵃ(i, j, 1, grid, Jᶜᶜᶜ.v) - end -end - -# Fallback for a `Nothing` radiation scheme -@inline net_upwelling_radiation(i, j, grid, time, ::Nothing, Tₒ) = zero(grid) -@inline net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, ::Nothing) = zero(grid) - -@inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) - α = stateindex(radiation.reflection.ocean, i, j, 1, grid, time) - ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) - - return @inbounds - (1 - α) * Qs - ϵ * Qℓ -end - -@inline function net_upwelling_radiation(i, j, grid, time, radiation, Tₒ) - σ = radiation.stefan_boltzmann_constant - ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) - - # Note: positive implies _upward_ heat flux, and therefore cooling. - return ϵ * σ * Tₒ^4 -end ##### ##### Utility for interpolating tuples of fields From 8d837e3cfb81f4da129dd3ea5962b5456622b93e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:02:50 -0400 Subject: [PATCH 496/716] try running this? --- examples/near_global_omip_simulation.jl | 165 ++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 examples/near_global_omip_simulation.jl diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl new file mode 100644 index 00000000..f10ee1d6 --- /dev/null +++ b/examples/near_global_omip_simulation.jl @@ -0,0 +1,165 @@ +using Printf +using Oceananigans +using Oceananigans.Units +using Oceananigans: architecture +using ClimaOcean +using ClimaOcean.ECCO2 +using ClimaOcean.OceanSimulations +using ClimaOcean.OceanSeaIceModels + +##### +##### Near - Global Ocean at 1/4th of a degree +##### + +# 40 vertical levels +z_faces = exponential_z_faces(Nz=40, depth=6000) + +Nx = 1440 +Ny = 600 +Nz = length(z_faces) - 1 + +# Running on a GPU +arch = GPU() + +# A near-global grid from 75ᵒ S to 75ᵒ N +grid = LatitudeLongitudeGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = z_faces, + longitude = (0, 360), + latitude = (-75, 75)) + +# We retrieve the bathymetry from the ETOPO1 data by ensuring a +# minimum depth of 10 meters (everyhting shallower is considered land) +# and removing all connected regions (inland lakes) +bottom_height = retrieve_bathymetry(grid; + minimum_depth = 10, + dir = "./", + interpolation_passes = 20, + connected_regions_allowed = 0) + +# An immersed boundary using a staircase representation of bathymetry +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) + +##### +##### The Ocean component +##### + +# We retain all the defaults for the ocean model +ocean = ocean_simulation(grid) +model = ocean.model + +# We interpolate the initial conditions from the ECCO2 dataset +# (for the moment these are both 1st January 1992) +set!(model, + T = ECCO2Metadata(:temperature), + S = ECCO2Metadata(:salinity)) + +##### +##### The atmosphere +##### + +# The whole prescribed atmosphere is loaded in memory +# 4 snapshots at the time. +backend = JRA55NetCDFBackend(4) +atmosphere = JRA55_prescribed_atmosphere(arch; backend) + +# Tabulated ocean albedo from Payne (1982) +# ocean emissivity is the default 0.97 +radiation = Radiation(arch) + +##### +##### The atmospheric-forced coupled ocean-seaice model +##### + +# Simplistic sea ice that ensure "no-cooling-fluxes" where `T < T_minimum` +# to change with a thermodynamic sea-ice model +sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() + +# The complete coupled model +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +wall_time = [time_ns()] + +# We define a progress function that +# shows the maximum values of velocity and temperature +# to make sure everything proceedes as planned +function progress(sim) + u, v, w = sim.model.velocities + T = sim.model.tracers.T + + Tmax = maximum(interior(T)) + Tmin = minimum(interior(T)) + umax = maximum(interior(u)), maximum(interior(v)), maximum(interior(w)) + step_time = 1e-9 * (time_ns() - wall_time[1]) + + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", + prettytime(sim.model.clock.time), + sim.model.clock.iteration, + prettytime(sim.Δt), + umax..., Tmax, Tmin, prettytime(step_time)) + + wall_time[1] = time_ns() +end + +ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +fluxes = (u = model.velocities.u.boundary_conditions.top.condition, + v = model.velocities.v.boundary_conditions.top.condition, + T = model.tracers.T.boundary_conditions.top.condition, + S = model.tracers.S.boundary_conditions.top.condition) + + +output_kwargs = (; overwrite_existing = true, array_type = Array{Float32}) + +# We add a couple of outputs: the surface state every 12 hours, the surface fluxes +# every 12 hours, and the whole state every ten days +ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; + schedule = TimeInterval(0.5days), + overwrite_existing = true, + filename = "surface_fluxes", + output_kwargs...) + +ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); + schedule = TimeInterval(0.5days), + filename = "surface", + indices = (:, :, grid.Nz), + output_kwargs...) + +ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); + schedule = TimeInterval(10days), + filename = "snapshots", + output_kwargs...) + +# Checkpointer for restarting purposes +ocean.output_writers[:checkpoint] = Checkpointer(model; + schedule = TimeInterval(60days), + overwrite_existing = true, + prefix = "checkpoint") + +##### +##### Run the simulation! +##### + +# warm up the simulation to ensure that the model adapts +# to the interpolated initial conditions without crashing +ocean.Δt = 10 +ocean.stop_iteration = 1 +wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) + +# Finally, the coupled simulation! +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time = 20days) + +run!(coupled_simulation) + +wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 800, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) + +# Let's reset the maximum number of iterations +coupled_model.ocean.stop_time = 7200days +coupled_simulation.stop_time = 7200days +coupled_model.ocean.stop_iteration = Inf +coupled_simulation.stop_iteration = Inf + +run!(coupled_simulation) From 895be667bcf9e9cd145b1fc4495987f059a21b3f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:05:35 -0400 Subject: [PATCH 497/716] update it --- examples/near_global_omip_simulation.jl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index f10ee1d6..0d94909a 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -3,10 +3,13 @@ using Oceananigans using Oceananigans.Units using Oceananigans: architecture using ClimaOcean -using ClimaOcean.ECCO2 +using ClimaOcean.ECCO using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels +using CFTime +using Dates + ##### ##### Near - Global Ocean at 1/4th of a degree ##### @@ -49,11 +52,13 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_ ocean = ocean_simulation(grid) model = ocean.model +date = DateTimeProlepticGregorian(1993, 1, 1) + # We interpolate the initial conditions from the ECCO2 dataset -# (for the moment these are both 1st January 1992) +# (for the moment these are both 1st January 1993) set!(model, - T = ECCO2Metadata(:temperature), - S = ECCO2Metadata(:salinity)) + T = ECCO2Metadata(:temperature, date, ECCO2Daily()), + S = ECCO2Metadata(:salinity, date, ECCO2Daily())) ##### ##### The atmosphere From 19af1cc8d86dc90a68752470d5917dd9fbb1f105 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:24:27 -0400 Subject: [PATCH 498/716] export stuff --- src/ClimaOcean.jl | 2 ++ src/VerticalGrids.jl | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 15aea16a..9a5244a5 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -8,8 +8,10 @@ export JRA55NetCDFBackend, ecco2_field, regrid_bathymetry, + retrieve_bathymetry, stretched_vertical_faces, PowerLawStretching, LinearStretching, + exponential_z_faces, jra55_field_time_series, ecco_field, ECCOMetadata, initialize! diff --git a/src/VerticalGrids.jl b/src/VerticalGrids.jl index e886cf4a..4b88b79c 100644 --- a/src/VerticalGrids.jl +++ b/src/VerticalGrids.jl @@ -1,6 +1,6 @@ module VerticalGrids -export stretched_vertical_faces, PowerLawStretching, LinearStretching +export stretched_vertical_faces, PowerLawStretching, LinearStretching, exponential_z_faces struct PowerLawStretching{T} power :: T From b87b723719bfeb9302969a95b03d4207401f937f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:38:08 -0400 Subject: [PATCH 499/716] bugfix --- src/Bathymetry.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 1cc6205d..2ceb8b98 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -350,6 +350,7 @@ function retrieve_bathymetry(grid, filename; kw...) end retrieve_bathymetry(grid, ::Nothing; kw...) = regrid_bathymetry(grid; kw...) +retrieve_bathymetry(grid; kw...) = regrid_bathymetry(grid; kw...) end # module From 027a74b23e695c2962a73e1c7855a92546d11db6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 10 Jun 2024 20:21:31 -0400 Subject: [PATCH 500/716] add single column to docs --- docs/make_examples.jl | 1 + ...ip_simulation.jl => JRA55forced_single_column_simulation.jl} | 0 examples/near_global_omip_simulation.jl | 2 +- 3 files changed, 2 insertions(+), 1 deletion(-) rename examples/{single_column_omip_simulation.jl => JRA55forced_single_column_simulation.jl} (100%) diff --git a/docs/make_examples.jl b/docs/make_examples.jl index 4a51f0bd..b76f3c20 100644 --- a/docs/make_examples.jl +++ b/docs/make_examples.jl @@ -16,6 +16,7 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ "inspect_ecco2_data.jl", + "JRA55forced_single_column_simulation.jl", "near_global_omip_simulation.jl" ] diff --git a/examples/single_column_omip_simulation.jl b/examples/JRA55forced_single_column_simulation.jl similarity index 100% rename from examples/single_column_omip_simulation.jl rename to examples/JRA55forced_single_column_simulation.jl diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 36d3575c..3e7558ef 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -39,7 +39,7 @@ bottom_height = retrieve_bathymetry(grid; connected_regions_allowed = 0) # An immersed boundary using a staircase representation of bathymetry -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) ##### ##### The Ocean component From 4c0c30a5b65b735c64d4e4c304137df7898c700f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 10 Jun 2024 20:54:24 -0400 Subject: [PATCH 501/716] changed filename --- examples/JRA55forced_single_column_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/JRA55forced_single_column_simulation.jl b/examples/JRA55forced_single_column_simulation.jl index 9f7c70d9..7903a049 100644 --- a/examples/JRA55forced_single_column_simulation.jl +++ b/examples/JRA55forced_single_column_simulation.jl @@ -78,7 +78,7 @@ atmosphere = JRA55_prescribed_atmosphere(time_indices = 1:480; longitude, latitude, backend, with_rivers_and_icebergs = false) -ocean.model.clock.time = start_seconds +ocean.model.clock.time = 0 ocean.model.clock.iteration = 0 ocean.Δt = 10minutes From 597757c3e1addebdb66783681b874af3981168a3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 10 Jun 2024 22:10:32 -0400 Subject: [PATCH 502/716] this should work, now start with documenting --- .../JRA55forced_single_column_simulation.jl | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/examples/JRA55forced_single_column_simulation.jl b/examples/JRA55forced_single_column_simulation.jl index 7903a049..1c9b27ec 100644 --- a/examples/JRA55forced_single_column_simulation.jl +++ b/examples/JRA55forced_single_column_simulation.jl @@ -43,11 +43,11 @@ longitude = λ★ .+ (-0.25, 0.25) latitude = φ★ .+ (-0.25, 0.25) # We use a SingleColumnGrid -grid = RectilinearGrid(size = (3, 3, Nz), - x = longitude, - y = latitude, - z = (-H, 0), - topology = (Periodic, Periodic, Bounded)) +grid = LatitudeLongitudeGrid(; size = (3, 3, Nz), + longitude, + latitude, + z = (-H, 0), + topology = (Periodic, Periodic, Bounded)) # Building the ocean simulation momentum_advection = nothing @@ -177,7 +177,6 @@ coupled_simulation.output_writers[:jld2] = JLD2OutputWriter(ocean.model, outputs run!(coupled_simulation) -#= filename *= ".jld2" ut = FieldTimeSeries(filename, "u") @@ -188,16 +187,15 @@ 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ˢ") +Qv = FieldTimeSeries(filename, "Qv") +Qc = FieldTimeSeries(filename, "Qc") +Js = FieldTimeSeries(filename, "Js") Et = FieldTimeSeries(filename, "E") -τˣt = FieldTimeSeries(filename, "τˣ") -τʸt = FieldTimeSeries(filename, "τʸ") +τˣ = FieldTimeSeries(filename, "τx") +τʸ = FieldTimeSeries(filename, "τy") Nz = size(Tt, 3) -times = Qt.times +times = Qc.times ua = atmosphere.velocities.u va = atmosphere.velocities.v @@ -253,6 +251,7 @@ slider = Slider(fig[4, 1:6], range=1:Nt, startvalue=1) n = slider.value times = (times .- times[1]) ./days +Nt = length(times) tn = @lift times[$n] colors = Makie.wong_colors() @@ -260,10 +259,11 @@ 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) +Jᵘ = interior(τˣ, 1, 1, 1, :) ./ ρₒ +Jᵛ = interior(τʸ, 1, 1, 1, :) ./ ρₒ +u★ = @. (Jᵘ^2 + Jᵛ^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") @@ -271,27 +271,26 @@ 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") +lines!(axτ, times, interior(τˣ, 1, 1, 1, :), label="Zonal") +lines!(axτ, times, interior(τʸ, 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, Tat[1:Nt] .- 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) +lines!(axQ, times, interior(Qv, 1, 1, 1, 1:Nt), color=colors[2], label="Sensible", linewidth=2) +lines!(axQ, times, interior(Qc, 1, 1, 1, 1:Nt), color=colors[3], label="Latent", linewidth=2) +lines!(axQ, times, - Qswt[1:1:Nt], color=colors[4], label="Shortwave", linewidth=2) +lines!(axQ, times, - Qlwt[1:1:Nt], 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") +lines!(axF, times, Pt[1:Nt], label="Prescribed freshwater flux") +lines!(axF, times, - interior(Et, 1, 1, 1, 1:Nt), label="Evaporation") vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) axislegend(axF) @@ -299,12 +298,12 @@ lines!(axS, times, interior(St, 1, 1, Nz, :)) vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) zc = znodes(Tt) -zf = znodes(κt) +zf = znodes(κc) 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, :) +κn = @lift κc[$n] en = @lift max.(1e-6, interior(et[$n], 1, 1, :)) N²n = @lift interior(N²t[$n], 1, 1, :) @@ -339,6 +338,4 @@ 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 -=# From 7d5f10f5d4b4af787d07bd35a0edab58d08b233c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:58:55 -0400 Subject: [PATCH 503/716] updating Oceananigans --- Manifest.toml | 341 +++++++++--------- Project.toml | 2 +- .../JRA55forced_single_column_simulation.jl | 107 +++--- src/DataWrangling/JRA55.jl | 4 +- .../similarity_theory_turbulent_fluxes.jl | 4 +- 5 files changed, 221 insertions(+), 237 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 58f5b96f..8e086043 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.3" +julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "2a8f25db6ea4e6c9eea1b6a1b3d7fec975bd0d16" +project_hash = "edb3b1f7c1c580248896d1c4ed1aa39adff53b7e" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -52,9 +52,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "133a240faec6e074e07c31ee75619c90544179cf" +git-tree-sha1 = "ed2ec3c9b483842ae59cd273834e5b46206d6dda" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.10.0" +version = "7.11.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -132,50 +132,55 @@ version = "0.1.3" [[deps.CPUSummary]] deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" +git-tree-sha1 = "585a387a490f1c4bd88be67eea15b93da5e85db7" uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.4" +version = "0.2.5" [[deps.CUDA]] deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] -git-tree-sha1 = "baa8ea7a1ea63316fa3feb454635215773c9c845" +git-tree-sha1 = "6e945e876652f2003e6ca74e19a3c45017d3e9f6" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.2.0" -weakdeps = ["ChainRulesCore", "SpecialFunctions"] +version = "5.4.2" [deps.CUDA.extensions] ChainRulesCoreExt = "ChainRulesCore" + EnzymeCoreExt = "EnzymeCore" SpecialFunctionsExt = "SpecialFunctions" + [deps.CUDA.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" +git-tree-sha1 = "c48f9da18efd43b6b7adb7ee1f93fe5f2926c339" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.7.0+1" +version = "0.9.0+0" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] -git-tree-sha1 = "38f830504358e9972d2a0c3e5d51cb865e0733df" +git-tree-sha1 = "5db9da5fdeaa708c22ba86b82c49528f402497f2" uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.2.4" +version = "0.3.3" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" +git-tree-sha1 = "bcba305388e16aa5c879e896726db9e71b4942c6" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.11.1+0" +version = "0.14.0+1" [[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" +git-tree-sha1 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.0+1" +version = "1.18.0+2" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +git-tree-sha1 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.23.0" +version = "1.24.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -183,8 +188,8 @@ weakdeps = ["SparseArrays"] [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" -repo-rev = "main" +git-tree-sha1 = "0ac8d2566e8f4887896c8a03ee87050fcbbf6599" +repo-rev = "ss/new-oceananigans" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" @@ -219,15 +224,15 @@ weakdeps = ["SpecialFunctions"] [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.10" +version = "0.12.11" [[deps.CommonDataModel]] deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" +git-tree-sha1 = "d6fb5bf939a2753c74984b11434ea25d6c397a58" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.5" +version = "0.3.6" [[deps.CommonSolve]] git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" @@ -242,9 +247,9 @@ version = "0.3.0" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.14.0" +version = "4.15.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -319,10 +324,10 @@ 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" +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 = ["Compat", "InteractiveUtils", "OrderedCollections"] @@ -374,9 +379,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.DocStringExtensions]] deps = ["LibGit2"] -git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b" +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.8.6" +version = "0.9.3" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] @@ -396,9 +401,9 @@ version = "0.1.10" [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +git-tree-sha1 = "1c6317308b9dc757616f0b5cb379db10494443a7" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.5.0+0" +version = "2.6.2+0" [[deps.ExprTools]] git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" @@ -440,15 +445,15 @@ uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FixedPointNumbers]] deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" +version = "0.8.5" [[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.93+0" +version = "2.13.96+0" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] @@ -462,15 +467,15 @@ weakdeps = ["StaticArrays"] [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +git-tree-sha1 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.1+0" +version = "2.13.2+0" [[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.10+0" +version = "1.0.14+0" [[deps.Future]] deps = ["Random"] @@ -483,9 +488,9 @@ version = "6.2.1+6" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "68e8ff56a4a355a85d2784b94614491f8c900cde" +git-tree-sha1 = "38cb19b8a3e600e509dc36a6396ac74266d108c1" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "10.1.0" +version = "10.1.1" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -495,9 +500,9 @@ version = "0.1.6" [[deps.GPUCompiler]] deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] -git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" +git-tree-sha1 = "518ebd058c9895de468a8c255797b0c53fdb44dd" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.25.0" +version = "0.26.5" [[deps.Gettext_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] @@ -507,9 +512,9 @@ 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" +git-tree-sha1 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.0+0" +version = "2.80.2+0" [[deps.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" @@ -536,9 +541,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 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +git-tree-sha1 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.5" +version = "1.10.8" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -589,9 +594,9 @@ version = "1.4.0" [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +git-tree-sha1 = "be50fe8df3acbffa0274a744f1a99d29c45a57f4" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.0.2+0" +version = "2024.1.0+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -599,9 +604,9 @@ uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[deps.InverseFunctions]] deps = ["Test"] -git-tree-sha1 = "896385798a8d49a255c398bd49162062e4a4c435" +git-tree-sha1 = "e7cbed5032c4c397a6ac23d1493f3289e01231c4" uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.13" +version = "0.1.14" weakdeps = ["Dates"] [deps.InverseFunctions.extensions] @@ -629,10 +634,10 @@ 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" +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] +git-tree-sha1 = "bdbe8222d2f5703ad6a7019277d149ec6d78c301" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.46" +version = "0.4.48" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -642,9 +647,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"] @@ -654,9 +665,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" +git-tree-sha1 = "8e5a339882cc401688d79b811d923a38ba77d50a" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.18" +version = "0.9.20" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -665,16 +676,16 @@ version = "0.9.18" EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" [[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.1+0" +version = "3.100.2+0" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "839c82932db86740ae729779e610f07a1640be9a" +git-tree-sha1 = "389aea28d882a40b5e1747069af71bdbd47a1cae" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.6.3" +version = "7.2.1" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -707,10 +718,10 @@ weakdeps = ["Serialization"] SerializationExt = ["Serialization"] [[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.1+0" +version = "2.10.2+0" [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" @@ -761,16 +772,16 @@ 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" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll"] +git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.7+0" +version = "1.8.11+0" [[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.42.0+0" +version = "1.49.0+0" [[deps.Libiconv_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -780,15 +791,15 @@ version = "1.17.0+0" [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +git-tree-sha1 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.39.3+0" +version = "2.40.1+0" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.39.3+1" +version = "2.40.1+0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -796,9 +807,9 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.27" +version = "0.3.28" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -821,9 +832,9 @@ version = "1.0.3" [[deps.LoopVectorization]] deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "a13f3be5d84b9c95465d743c82af0b094ef9c2e2" +git-tree-sha1 = "8f6786d8b2b3248d79db3ad359ce95382d5a6df8" uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.169" +version = "0.12.170" weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] [deps.LoopVectorization.extensions] @@ -837,10 +848,10 @@ 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" +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "80b2833b56d466b3858d565adcd16a4a05f2089b" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.0.0+0" +version = "2024.1.0+0" [[deps.MPI]] deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] @@ -858,21 +869,21 @@ version = "0.20.16" [[deps.MPICH_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "656036b9ed6f942d35e536e249600bc31d0f9df8" +git-tree-sha1 = "4099bb6809ac109bfc17d521dad33763bcf026b7" uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.2.0+0" +version = "4.2.1+1" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] -git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.10" +version = "0.1.11" [[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "77c3bd69fdb024d75af38713e883d0f249ce19c2" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "8c35d5420193841b2f367e658540e8d9e0601ed0" uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.3.2+0" +version = "5.4.0+0" [[deps.MacroTools]] deps = ["Markdown", "Random"] @@ -932,9 +943,9 @@ version = "2023.1.10" [[deps.NCDatasets]] deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "d40d24d12f710c39d3a66be99c567ce0032f28a7" +git-tree-sha1 = "a640912695952b074672edb5f9aaee2f7f9fd59a" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.3" +version = "0.14.4" [[deps.NVTX]] deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] @@ -972,11 +983,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 = "82eddd14528a13419be8b75da9daa23fb2a14363" -repo-rev = "main" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +git-tree-sha1 = "994ae77f4f232940822770d8ce7c2f84e373156e" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.12" +version = "0.91.1" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -1010,22 +1019,22 @@ 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" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] +git-tree-sha1 = "a9de2f1fc98b92f8856c640bf4aec1ac9b2a0d86" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.2+0" +version = "5.0.3+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +git-tree-sha1 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.2" +version = "1.4.3" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.13+1" +version = "3.0.14+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1055,12 +1064,6 @@ deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" version = "10.42.0+1" -[[deps.PMIx_jll]] -deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] -git-tree-sha1 = "360f48126b5f2c2f0c833be960097f7c62705976" -uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" -version = "4.2.9+0" - [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" @@ -1081,9 +1084,9 @@ version = "2.8.1" [[deps.PencilArrays]] deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] -git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" +git-tree-sha1 = "8c5b9251650cb0ac77911f7e8a9e8f7c15bd5c99" uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.3" +version = "0.19.4" [deps.PencilArrays.extensions] PencilArraysDiffEqExt = ["DiffEqBase"] @@ -1101,9 +1104,9 @@ version = "0.15.1" [[deps.Pixman_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +git-tree-sha1 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.42.2+0" +version = "0.43.4+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] @@ -1142,9 +1145,9 @@ version = "1.4.3" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +git-tree-sha1 = "66b20dd35966a748321d3b2537c4584cf40387c7" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.3.1" +version = "2.3.2" [[deps.Printf]] deps = ["Unicode"] @@ -1231,9 +1234,9 @@ version = "2.1.5" [[deps.Rotations]] deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.0" +version = "1.7.1" weakdeps = ["RecipesBase"] [deps.Rotations.extensions] @@ -1267,9 +1270,9 @@ version = "0.3.4" [[deps.SentinelArrays]] deps = ["Dates", "Random"] -git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +git-tree-sha1 = "90b4f68892337554d31cdcdbe19e48989f26c7e6" uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.1" +version = "1.4.3" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -1279,12 +1282,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" @@ -1301,9 +1298,9 @@ version = "1.10.0" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +git-tree-sha1 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.1" +version = "2.4.0" weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] @@ -1334,9 +1331,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +git-tree-sha1 = "6e00379a24597be4ae1ee6b2d882e15392040132" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.3" +version = "1.9.5" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -1344,9 +1341,9 @@ weakdeps = ["ChainRulesCore", "Statistics"] StaticArraysStatisticsExt = "Statistics" [[deps.StaticArraysCore]] -git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.2" +version = "1.4.3" [[deps.StaticPermutations]] git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" @@ -1416,17 +1413,15 @@ 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" +git-tree-sha1 = "89c701c87f378ce95e7ddbcd69b8f1106ba8b968" uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.9.2" +version = "0.11.0" [deps.SurfaceFluxes.extensions] - CreateParametersExt = "CLIMAParameters" + CreateParametersExt = "ClimaParams" [deps.SurfaceFluxes.weakdeps] - CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" [[deps.TOML]] deps = ["Dates"] @@ -1474,11 +1469,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "ed1a35a4b608024f60b71f92930ca9e64d55068c" -repo-rev = "glw/density-example" -repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" +git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.12.4" +version = "0.12.6" [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" @@ -1500,14 +1493,14 @@ version = "0.5.0" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] -git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +git-tree-sha1 = "5a13ae8a41237cff5ecf34f73eb1b8f42fff6531" uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" -version = "0.5.23" +version = "0.5.24" [[deps.TranscodingStreams]] -git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +git-tree-sha1 = "a947ea21087caba0a798c5e494d0bb78e3a1a3a0" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.7" +version = "0.10.9" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] @@ -1542,15 +1535,15 @@ version = "0.2.1" [[deps.UnsafeAtomicsLLVM]] deps = ["LLVM", "UnsafeAtomics"] -git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +git-tree-sha1 = "d9f5962fecd5ccece07db1ff006fb0b5271bdfdd" uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" -version = "0.1.3" +version = "0.1.4" [[deps.VectorizationBase]] deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "ac377f0a248753a1b1d58bbc92a64f5a726dfb71" +git-tree-sha1 = "e863582a41c5731f51fd050563ae91eb33cf09be" uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.66" +version = "0.21.68" [[deps.VersionParsing]] git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" @@ -1559,9 +1552,9 @@ version = "1.3.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +git-tree-sha1 = "52ff2af32e591541550bd753c0da8b9bc92bb9d9" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.6+0" +version = "2.12.7+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] @@ -1594,16 +1587,16 @@ 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" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.4+4" +version = "1.3.6+0" [[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.10+4" +version = "0.9.11+0" [[deps.Xorg_libpthread_stubs_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1641,10 +1634,10 @@ uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" version = "1.1.2+0" [[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.4.0+0" +version = "3.9.0+0" [[deps.libass_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] @@ -1657,12 +1650,6 @@ 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" @@ -1692,17 +1679,17 @@ deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" version = "1.52.0+1" +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2021.12.0+0" + [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" -[[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/Project.toml b/Project.toml index d97e9d8f..0a1f741f 100644 --- a/Project.toml +++ b/Project.toml @@ -35,7 +35,7 @@ Downloads = "1.6" JLD2 = "0.4" KernelAbstractions = "0.9" NCDatasets = "0.12, 0.13, 0.14" -Oceananigans = "0.90.10" +Oceananigans = "0.90, 0.91" SeawaterPolynomials = "0.3.4" Statistics = "1.9" julia = "1.9" diff --git a/examples/JRA55forced_single_column_simulation.jl b/examples/JRA55forced_single_column_simulation.jl index 1c9b27ec..bb6d7116 100644 --- a/examples/JRA55forced_single_column_simulation.jl +++ b/examples/JRA55forced_single_column_simulation.jl @@ -73,8 +73,9 @@ elapsed = time_ns() - start_time start_time = time_ns() # Retrieving the atmosphere +last_time = floor(Int, 31 * 24 / 3) # 31 days in hours divided by JRA55's frequency in hours backend = InMemory() -atmosphere = JRA55_prescribed_atmosphere(time_indices = 1:480; +atmosphere = JRA55_prescribed_atmosphere(time_indices = 1:last_time; longitude, latitude, backend, with_rivers_and_icebergs = false) @@ -159,7 +160,7 @@ Q = ρₒ * cₚ * JT τx = ρₒ * Ju τy = ρₒ * Jv N² = buoyancy_frequency(ocean.model) -κc = ocean.model.diffusivity_fields.κᶜ +κc = ocean.model.diffusivity_fields.κc fluxes = (; τx, τy, E, Js, Qv, Qc) @@ -179,51 +180,51 @@ 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, "κᶜ") +u = FieldTimeSeries(filename, "u") +v = FieldTimeSeries(filename, "v") +T = FieldTimeSeries(filename, "T") +S = FieldTimeSeries(filename, "S") +e = FieldTimeSeries(filename, "e") +N² = FieldTimeSeries(filename, "N²") +κ = FieldTimeSeries(filename, "κc") Qv = FieldTimeSeries(filename, "Qv") Qc = FieldTimeSeries(filename, "Qc") Js = FieldTimeSeries(filename, "Js") -Et = FieldTimeSeries(filename, "E") +Ev = FieldTimeSeries(filename, "E") τˣ = FieldTimeSeries(filename, "τx") τʸ = FieldTimeSeries(filename, "τy") Nz = size(Tt, 3) times = Qc.times -ua = atmosphere.velocities.u -va = atmosphere.velocities.v -Ta = atmosphere.tracers.T -qa = atmosphere.tracers.q +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) +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) +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)] + 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)] + Pt[n] = Pr[1, 1, 1, Time(t)] + Ps[1, 1, 1, Time(t)] end set_theme!(Theme(linewidth=3)) @@ -256,17 +257,13 @@ 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ᵘ = interior(τˣ, 1, 1, 1, :) ./ ρₒ Jᵛ = interior(τʸ, 1, 1, 1, :) ./ ρₒ u★ = @. (Jᵘ^2 + Jᵛ^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, interior(u, 1, 1, Nz, :), color=colors[1], label="Zonal") +lines!(axu, times, interior(v, 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) @@ -277,35 +274,35 @@ vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) axislegend(axτ) lines!(axT, times, Tat[1:Nt] .- 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") +lines!(axT, times, interior(T, 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(Qv, 1, 1, 1, 1:Nt), color=colors[2], label="Sensible", linewidth=2) -lines!(axQ, times, interior(Qc, 1, 1, 1, 1:Nt), color=colors[3], label="Latent", linewidth=2) -lines!(axQ, times, - Qswt[1:1:Nt], color=colors[4], label="Shortwave", linewidth=2) -lines!(axQ, times, - Qlwt[1:1:Nt], color=colors[5], label="Longwave", linewidth=2) +lines!(axQ, times, interior(Qv, 1, 1, 1, 1:Nt), color=colors[2], label="Sensible", linewidth=2) +lines!(axQ, times, interior(Qc, 1, 1, 1, 1:Nt), color=colors[3], label="Latent", linewidth=2) +lines!(axQ, times, - interior(Qsw, 1, 1, 1, 1:Nt), color=colors[4], label="Shortwave", linewidth=2) +lines!(axQ, times, - interior(Qlw, 1, 1, 1, 1:Nt), 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[1:Nt], label="Prescribed freshwater flux") -lines!(axF, times, - interior(Et, 1, 1, 1, 1:Nt), label="Evaporation") +lines!(axF, times, - interior(Ev, 1, 1, 1, 1:Nt), label="Evaporation") vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) axislegend(axF) -lines!(axS, times, interior(St, 1, 1, Nz, :)) +lines!(axS, times, interior(S, 1, 1, Nz, :)) vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) zc = znodes(Tt) zf = znodes(κc) -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 κc[$n] -en = @lift max.(1e-6, interior(et[$n], 1, 1, :)) -N²n = @lift interior(N²t[$n], 1, 1, :) +un = @lift interior(u[$n], 1, 1, :) +vn = @lift interior(v[$n], 1, 1, :) +Tn = @lift interior(T[$n], 1, 1, :) +Sn = @lift interior(S[$n], 1, 1, :) +κn = @lift interior(κ[$n], 1, 1, :) +en = @lift interior(e[$n], 1, 1, :) +N²n = @lift interior(N²[$n], 1, 1, :) scatterlines!(axuz, un, zc, label="u") scatterlines!(axuz, vn, zc, label="v") @@ -317,20 +314,20 @@ scatterlines!(axκz, κn, zf) axislegend(axuz) -Tmax = maximum(interior(Tt)) -Tmin = minimum(interior(Tt)) +Tmax = maximum(interior(T)) +Tmin = minimum(interior(T)) xlims!(axTz, Tmin - 0.1, Tmax + 0.1) -Nmax = maximum(interior(N²t)) -Nmin = minimum(interior(N²t)) +Nmax = maximum(interior(N²)) +Nmin = minimum(interior(N²)) xlims!(axNz, Nmin / 2, Nmin * 1.1) -emax = maximum(interior(et)) +emax = maximum(interior(e)) xlims!(axez, 8e-7, emax * 1.1) xlims!(axκz, 1e-7, 10) -Smax = maximum(interior(St)) -Smin = minimum(interior(St)) +Smax = maximum(interior(S)) +Smin = minimum(interior(S)) xlims!(axSz, Smin - 0.2, Smax + 0.2) display(fig) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index b6653ccd..924539f1 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -589,7 +589,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, time_indexing = Cyclical(), measurement_height = 10, # meters - with_rivers_and_icebergs = true, + include_rivers_and_icebergs = true, # rivers and icebergs are not needed in single column simulations other_kw...) if isnothing(backend) # apply a default @@ -618,7 +618,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) - if with_rivers_and_icebergs + if include_rivers_and_icebergs Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) freshwater_flux = (rain = Fra, diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index dadfe727..2adf4f38 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -3,7 +3,7 @@ using Oceananigans.Grids: AbstractGrid using Adapt using Thermodynamics: Liquid -using SurfaceFluxes.Parameters: SurfaceFluxesParameters, AbstractSurfaceFluxesParameters +using SurfaceFluxes.Parameters: SurfaceFluxesParameters using SurfaceFluxes.UniversalFunctions: BusingerParams, BusingerType using Printf @@ -29,7 +29,7 @@ import SurfaceFluxes.Parameters: ##### Bulk turbulent fluxes based on similarity theory ##### -struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, F} <: AbstractSurfaceFluxesParameters +struct SimilarityTheoryTurbulentFluxes{FT, UF, TP, S, W, R, B, V, F} gravitational_acceleration :: FT von_karman_constant :: FT turbulent_prandtl_number :: FT From 15acee322791e5480dc76b75ad266f08e2f416e7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:59:54 -0400 Subject: [PATCH 504/716] small bugfix --- examples/JRA55forced_single_column_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/JRA55forced_single_column_simulation.jl b/examples/JRA55forced_single_column_simulation.jl index bb6d7116..12cb5c7f 100644 --- a/examples/JRA55forced_single_column_simulation.jl +++ b/examples/JRA55forced_single_column_simulation.jl @@ -195,7 +195,7 @@ Ev = FieldTimeSeries(filename, "E") τˣ = FieldTimeSeries(filename, "τx") τʸ = FieldTimeSeries(filename, "τy") -Nz = size(Tt, 3) +Nz = size(T, 3) times = Qc.times ua = atmosphere.velocities.u From 437d6e9e39b6fcd6f0cf06737494c79b86de6edf Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 11 Jun 2024 12:37:12 -0400 Subject: [PATCH 505/716] new compact --- Manifest.toml | 294 ++++++++++++++++++++++++-------------------------- Project.toml | 1 + 2 files changed, 139 insertions(+), 156 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index e360c857..b1a5eccd 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.3" +julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "c27b53d61e818e623bc97d879dda37485ae23df0" +project_hash = "d2ec6eab3a1bcf9a6e07ba530f8c2ea9266b216c" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -52,9 +52,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "133a240faec6e074e07c31ee75619c90544179cf" +git-tree-sha1 = "ed2ec3c9b483842ae59cd273834e5b46206d6dda" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.10.0" +version = "7.11.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -132,15 +132,15 @@ version = "0.1.3" [[deps.CPUSummary]] deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" +git-tree-sha1 = "585a387a490f1c4bd88be67eea15b93da5e85db7" uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.4" +version = "0.2.5" [[deps.CUDA]] deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] -git-tree-sha1 = "baa8ea7a1ea63316fa3feb454635215773c9c845" +git-tree-sha1 = "dd1c682b372b6791b69f6823afe364fc92a0146c" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.2.0" +version = "5.3.1" weakdeps = ["ChainRulesCore", "SpecialFunctions"] [deps.CUDA.extensions] @@ -149,9 +149,9 @@ weakdeps = ["ChainRulesCore", "SpecialFunctions"] [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "d01bfc999768f0a31ed36f5d22a76161fc63079c" +git-tree-sha1 = "dc172b558adbf17952001e15cf0d6364e6d78c2f" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.7.0+1" +version = "0.8.1+0" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] @@ -161,21 +161,21 @@ version = "0.2.4" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "8e25c009d2bf16c2c31a70a6e9e8939f7325cc84" +git-tree-sha1 = "4ca7d6d92075906c2ce871ea8bba971fff20d00c" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.11.1+0" +version = "0.12.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" +git-tree-sha1 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.0+1" +version = "1.18.0+2" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +git-tree-sha1 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.23.0" +version = "1.24.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -183,8 +183,8 @@ weakdeps = ["SparseArrays"] [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "5e34d4ba5c3ff017de4cafa5b16945b0a65f7884" -repo-rev = "main" +git-tree-sha1 = "c900eecbb9cc3989602cfe9524070e225f512fe1" +repo-rev = "ss/new-oceananigans" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" @@ -225,15 +225,15 @@ weakdeps = ["SpecialFunctions"] [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.10" +version = "0.12.11" [[deps.CommonDataModel]] deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" +git-tree-sha1 = "d6fb5bf939a2753c74984b11434ea25d6c397a58" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.5" +version = "0.3.6" [[deps.CommonSolve]] git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" @@ -248,9 +248,9 @@ version = "0.3.0" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.14.0" +version = "4.15.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -325,10 +325,10 @@ 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" +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 = ["Compat", "InteractiveUtils", "OrderedCollections"] @@ -380,9 +380,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.DocStringExtensions]] deps = ["LibGit2"] -git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b" +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.8.6" +version = "0.9.3" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] @@ -402,9 +402,9 @@ version = "0.1.10" [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +git-tree-sha1 = "1c6317308b9dc757616f0b5cb379db10494443a7" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.5.0+0" +version = "2.6.2+0" [[deps.ExprTools]] git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" @@ -446,15 +446,15 @@ uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FixedPointNumbers]] deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" +version = "0.8.5" [[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.93+0" +version = "2.13.96+0" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] @@ -468,15 +468,15 @@ weakdeps = ["StaticArrays"] [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +git-tree-sha1 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.1+0" +version = "2.13.2+0" [[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.10+0" +version = "1.0.14+0" [[deps.Future]] deps = ["Random"] @@ -489,9 +489,9 @@ version = "6.2.1+6" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "68e8ff56a4a355a85d2784b94614491f8c900cde" +git-tree-sha1 = "38cb19b8a3e600e509dc36a6396ac74266d108c1" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "10.1.0" +version = "10.1.1" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -501,9 +501,9 @@ version = "0.1.6" [[deps.GPUCompiler]] deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] -git-tree-sha1 = "a846f297ce9d09ccba02ead0cae70690e072a119" +git-tree-sha1 = "1600477fba37c9fc067b9be21f5e8101f24a8865" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.25.0" +version = "0.26.4" [[deps.Gettext_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] @@ -513,9 +513,9 @@ 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" +git-tree-sha1 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.0+0" +version = "2.80.2+0" [[deps.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" @@ -542,9 +542,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 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +git-tree-sha1 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.5" +version = "1.10.8" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -595,9 +595,9 @@ version = "1.4.0" [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +git-tree-sha1 = "be50fe8df3acbffa0274a744f1a99d29c45a57f4" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.0.2+0" +version = "2024.1.0+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -605,9 +605,9 @@ uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[deps.InverseFunctions]] deps = ["Test"] -git-tree-sha1 = "896385798a8d49a255c398bd49162062e4a4c435" +git-tree-sha1 = "e7cbed5032c4c397a6ac23d1493f3289e01231c4" uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.13" +version = "0.1.14" weakdeps = ["Dates"] [deps.InverseFunctions.extensions] @@ -635,10 +635,10 @@ 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" +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] +git-tree-sha1 = "bdbe8222d2f5703ad6a7019277d149ec6d78c301" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.46" +version = "0.4.48" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -666,9 +666,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "ed7167240f40e62d97c1f5f7735dea6de3cc5c49" +git-tree-sha1 = "8e5a339882cc401688d79b811d923a38ba77d50a" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.18" +version = "0.9.20" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -677,10 +677,10 @@ version = "0.9.18" EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" [[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.1+0" +version = "3.100.2+0" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] @@ -719,10 +719,10 @@ weakdeps = ["Serialization"] SerializationExt = ["Serialization"] [[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.1+0" +version = "2.10.2+0" [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" @@ -773,16 +773,16 @@ 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" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll"] +git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.7+0" +version = "1.8.11+0" [[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.42.0+0" +version = "1.49.0+0" [[deps.Libiconv_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -792,15 +792,15 @@ version = "1.17.0+0" [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +git-tree-sha1 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.39.3+0" +version = "2.40.1+0" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.39.3+1" +version = "2.40.1+0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -808,9 +808,9 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.27" +version = "0.3.28" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -833,9 +833,9 @@ version = "1.0.3" [[deps.LoopVectorization]] deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "a13f3be5d84b9c95465d743c82af0b094ef9c2e2" +git-tree-sha1 = "8f6786d8b2b3248d79db3ad359ce95382d5a6df8" uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.169" +version = "0.12.170" weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] [deps.LoopVectorization.extensions] @@ -844,9 +844,9 @@ weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] [[deps.LoweredCodeUtils]] deps = ["JuliaInterpreter"] -git-tree-sha1 = "31e27f0b0bf0df3e3e951bfcc43fe8c730a219f6" +git-tree-sha1 = "c6a36b22d2cca0e1a903f00f600991f97bf5f426" uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" -version = "2.4.5" +version = "2.4.6" [[deps.Lz4_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -855,10 +855,10 @@ 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" +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "80b2833b56d466b3858d565adcd16a4a05f2089b" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.0.0+0" +version = "2024.1.0+0" [[deps.MPI]] deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] @@ -876,21 +876,21 @@ version = "0.20.16" [[deps.MPICH_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "656036b9ed6f942d35e536e249600bc31d0f9df8" +git-tree-sha1 = "4099bb6809ac109bfc17d521dad33763bcf026b7" uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.2.0+0" +version = "4.2.1+1" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] -git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.10" +version = "0.1.11" [[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "77c3bd69fdb024d75af38713e883d0f249ce19c2" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "8c35d5420193841b2f367e658540e8d9e0601ed0" uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.3.2+0" +version = "5.4.0+0" [[deps.MacroTools]] deps = ["Markdown", "Random"] @@ -990,11 +990,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 = "82eddd14528a13419be8b75da9daa23fb2a14363" +git-tree-sha1 = "6c1c50eea929254e33d2dd5fc9a0006cd5428bd7" repo-rev = "main" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.12" +version = "0.91.1" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -1028,22 +1028,22 @@ 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" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] +git-tree-sha1 = "a9de2f1fc98b92f8856c640bf4aec1ac9b2a0d86" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.2+0" +version = "5.0.3+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +git-tree-sha1 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.2" +version = "1.4.3" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.13+1" +version = "3.0.14+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1073,12 +1073,6 @@ deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" version = "10.42.0+1" -[[deps.PMIx_jll]] -deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] -git-tree-sha1 = "360f48126b5f2c2f0c833be960097f7c62705976" -uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" -version = "4.2.9+0" - [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" @@ -1099,9 +1093,9 @@ version = "2.8.1" [[deps.PencilArrays]] deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] -git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" +git-tree-sha1 = "8c5b9251650cb0ac77911f7e8a9e8f7c15bd5c99" uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.3" +version = "0.19.4" [deps.PencilArrays.extensions] PencilArraysDiffEqExt = ["DiffEqBase"] @@ -1119,9 +1113,9 @@ version = "0.15.1" [[deps.Pixman_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +git-tree-sha1 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.42.2+0" +version = "0.43.4+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] @@ -1160,9 +1154,9 @@ version = "1.4.3" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +git-tree-sha1 = "66b20dd35966a748321d3b2537c4584cf40387c7" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.3.1" +version = "2.3.2" [[deps.Printf]] deps = ["Unicode"] @@ -1255,9 +1249,9 @@ version = "2.1.5" [[deps.Rotations]] deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.0" +version = "1.7.1" weakdeps = ["RecipesBase"] [deps.Rotations.extensions] @@ -1291,9 +1285,9 @@ version = "0.3.4" [[deps.SentinelArrays]] deps = ["Dates", "Random"] -git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +git-tree-sha1 = "90b4f68892337554d31cdcdbe19e48989f26c7e6" uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.1" +version = "1.4.3" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -1303,12 +1297,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" @@ -1325,9 +1313,9 @@ version = "1.10.0" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +git-tree-sha1 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.1" +version = "2.4.0" weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] @@ -1368,9 +1356,9 @@ weakdeps = ["ChainRulesCore", "Statistics"] StaticArraysStatisticsExt = "Statistics" [[deps.StaticArraysCore]] -git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.2" +version = "1.4.3" [[deps.StaticPermutations]] git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" @@ -1524,14 +1512,14 @@ version = "0.5.0" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] -git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +git-tree-sha1 = "5a13ae8a41237cff5ecf34f73eb1b8f42fff6531" uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" -version = "0.5.23" +version = "0.5.24" [[deps.TranscodingStreams]] -git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +git-tree-sha1 = "a947ea21087caba0a798c5e494d0bb78e3a1a3a0" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.7" +version = "0.10.9" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] @@ -1566,15 +1554,15 @@ version = "0.2.1" [[deps.UnsafeAtomicsLLVM]] deps = ["LLVM", "UnsafeAtomics"] -git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +git-tree-sha1 = "d9f5962fecd5ccece07db1ff006fb0b5271bdfdd" uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" -version = "0.1.3" +version = "0.1.4" [[deps.VectorizationBase]] deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "ac377f0a248753a1b1d58bbc92a64f5a726dfb71" +git-tree-sha1 = "e863582a41c5731f51fd050563ae91eb33cf09be" uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.66" +version = "0.21.68" [[deps.VersionParsing]] git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" @@ -1583,9 +1571,9 @@ version = "1.3.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +git-tree-sha1 = "52ff2af32e591541550bd753c0da8b9bc92bb9d9" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.6+0" +version = "2.12.7+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] @@ -1618,16 +1606,16 @@ 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" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.4+4" +version = "1.3.6+0" [[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.10+4" +version = "0.9.11+0" [[deps.Xorg_libpthread_stubs_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1665,10 +1653,10 @@ uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" version = "1.1.2+0" [[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.4.0+0" +version = "3.9.0+0" [[deps.libass_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] @@ -1681,12 +1669,6 @@ 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" @@ -1716,17 +1698,17 @@ deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" version = "1.52.0+1" +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2021.12.0+0" + [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" -[[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/Project.toml b/Project.toml index 955fe6ca..3fea6452 100644 --- a/Project.toml +++ b/Project.toml @@ -35,6 +35,7 @@ CubicSplines = "0.2" DataDeps = "0.7" Downloads = "1.6" JLD2 = "0.4" +Oceananigans = "0.90, 0.91" KernelAbstractions = "0.9" NCDatasets = "0.12, 0.13, 0.14" SeawaterPolynomials = "0.3.4" From f5eeff91c1df4bf49d3c8865fa5fb9bf453ba4b3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:09:13 -0400 Subject: [PATCH 506/716] bugfix --- examples/JRA55forced_single_column_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/JRA55forced_single_column_simulation.jl b/examples/JRA55forced_single_column_simulation.jl index 12cb5c7f..f04514d6 100644 --- a/examples/JRA55forced_single_column_simulation.jl +++ b/examples/JRA55forced_single_column_simulation.jl @@ -77,7 +77,7 @@ last_time = floor(Int, 31 * 24 / 3) # 31 days in hours divided by JRA55's freque backend = InMemory() atmosphere = JRA55_prescribed_atmosphere(time_indices = 1:last_time; longitude, latitude, backend, - with_rivers_and_icebergs = false) + include_rivers_and_icebergs = false) ocean.model.clock.time = 0 ocean.model.clock.iteration = 0 From 029b3b41e4cfdf34a30c52e667b36943ed1301ae Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:16:43 -0400 Subject: [PATCH 507/716] might be right now --- .../tripolar_specific_methods.jl | 51 ++++++++++++++----- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index 1fc06b7e..c248f35e 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -2,6 +2,7 @@ using ClimaOcean import ClimaOcean.InitialConditions: interpolate! using Oceananigans +using Oceananigans.Operators using Oceananigans.BoundaryConditions using Oceananigans.Fields: OneField using Oceananigans.Grids: peripheral_node @@ -27,23 +28,45 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, c # Here we assume that the tripolar grid is locally orthogonal @inline function convert_to_latlong_frame(i, j, grid::TRG, uₒ, vₒ) - φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) - φ₂ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) - - θ = φ₂ - φ₁ - d₁ = hack_cosd(θ) - d₂ = hack_sind(θ) - + + φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) + φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) + Δyᶜᶜᵃ = Δyᶜᶜᶜ(i, j, 1, grid) + + ũ = deg2rad(φᶜᶠᵃ₊ - φᶜᶠᵃ₋) / Δyᶜᶜᵃ + + φᶠᶜᵃ₊ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) + φᶠᶜᵃ₋ = φnode(i, j, 1, grid, Face(), Center(), Center()) + Δxᶜᶜᵃ = Δxᶜᶜᶜ(i, j, 1, grid) + + ṽ = - deg2rad(φᶠᶜᵃ₊ - φᶠᶜᵃ₋) / Δxᶜᶜᵃ + + 𝒰 = sqrt(ũ^2 + ṽ^2) + + d₁ = ũ / 𝒰 + d₂ = ṽ / 𝒰 + return uₒ * d₁ - vₒ * d₂, uₒ * d₂ + vₒ * d₁ end @inline function convert_to_native_frame(i, j, grid::TRG, uₒ, vₒ) - φ₁ = φnode(i, j, 1, grid, Face(), Center(), Center()) - φ₂ = φnode(i, j+1, 1, grid, Face(), Center(), Center()) - - θ = φ₂ - φ₁ - d₁ = hack_cosd(θ) - d₂ = hack_sind(θ) - + + φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) + φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) + Δyᶜᶜᵃ = Δyᶜᶜᶜ(i, j, 1, grid) + + ũ = deg2rad(φᶜᶠᵃ₊ - φᶜᶠᵃ₋) / Δyᶜᶜᵃ + + φᶠᶜᵃ₊ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) + φᶠᶜᵃ₋ = φnode(i, j, 1, grid, Face(), Center(), Center()) + Δxᶜᶜᵃ = Δxᶜᶜᶜ(i, j, 1, grid) + + ṽ = - deg2rad(φᶠᶜᵃ₊ - φᶠᶜᵃ₋) / Δxᶜᶜᵃ + + 𝒰 = sqrt(ũ^2 + ṽ^2) + + d₁ = ũ / 𝒰 + d₂ = ṽ / 𝒰 + return uₒ * d₁ + vₒ * d₂, uₒ * d₂ - vₒ * d₁ end From 09f298da5fcf845e866b72a3d209020849b64c06 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:39:26 -0400 Subject: [PATCH 508/716] start without near global omip --- docs/make_examples.jl | 2 +- examples/JRA55forced_single_column_simulation.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/make_examples.jl b/docs/make_examples.jl index b76f3c20..807cf045 100644 --- a/docs/make_examples.jl +++ b/docs/make_examples.jl @@ -17,7 +17,7 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ "inspect_ecco2_data.jl", "JRA55forced_single_column_simulation.jl", - "near_global_omip_simulation.jl" + # "near_global_omip_simulation.jl" ] for file in to_be_literated diff --git a/examples/JRA55forced_single_column_simulation.jl b/examples/JRA55forced_single_column_simulation.jl index f04514d6..48f06d3b 100644 --- a/examples/JRA55forced_single_column_simulation.jl +++ b/examples/JRA55forced_single_column_simulation.jl @@ -294,8 +294,8 @@ axislegend(axF) lines!(axS, times, interior(S, 1, 1, Nz, :)) vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) -zc = znodes(Tt) -zf = znodes(κc) +zc = znodes(T) +zf = znodes(κ) un = @lift interior(u[$n], 1, 1, :) vn = @lift interior(v[$n], 1, 1, :) Tn = @lift interior(T[$n], 1, 1, :) From c3498f41ee6c7d9c5a8497748a753448fb6f2060 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:09:11 -0400 Subject: [PATCH 509/716] fix ecco test --- test/test_ecco2.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_ecco2.jl b/test/test_ecco2.jl index abbebec2..f5bc431a 100644 --- a/test/test_ecco2.jl +++ b/test/test_ecco2.jl @@ -43,7 +43,7 @@ end @testset "setting a field with ECCO2" begin for arch in test_architectures - grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (-5, 5), z = (-200, 0)) + grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (0, 80), longitude = (-5, 5), z = (-200, 0)) field = CenterField(grid) set!(field, ECCO2Metadata(:temperature)) set!(field, ECCO2Metadata(:salinity)) From 470c65ecc6623a29553e87e4465be233ce9a551f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:43:49 -0400 Subject: [PATCH 510/716] another bugfix --- test/test_ecco2.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_ecco2.jl b/test/test_ecco2.jl index f5bc431a..c940c2b3 100644 --- a/test/test_ecco2.jl +++ b/test/test_ecco2.jl @@ -43,7 +43,7 @@ end @testset "setting a field with ECCO2" begin for arch in test_architectures - grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (0, 80), longitude = (-5, 5), z = (-200, 0)) + grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (175, 185), z = (-200, 0)) field = CenterField(grid) set!(field, ECCO2Metadata(:temperature)) set!(field, ECCO2Metadata(:salinity)) From 7f74a6a854cfac8ef131e434e3fde9bc4ce0fce8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 13 Jun 2024 09:42:07 -0400 Subject: [PATCH 511/716] Update src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl Co-authored-by: Gregory L. Wagner --- src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index 5d748476..5208db51 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -60,7 +60,7 @@ function MomentumRoughnessLength(FT=Float64; gravitational_acceleration = default_gravitational_acceleration, maximum_roughness_length = 1.0, # An estimate? air_kinematic_viscosity = temperature_dependent_viscosity, - _wave_parameter = 0.011, + gravity_wave_parameter = 0.011, laminar_parameter = 0.11) return MomentumRoughnessLength(convert(FT, gravitational_acceleration), From bd710fc0178ace87727f42981807cf9d9edfbaf0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 13 Jun 2024 09:43:08 -0400 Subject: [PATCH 512/716] Update src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl Co-authored-by: Gregory L. Wagner --- src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index d171ce16..e2197c76 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -61,7 +61,6 @@ and day in the year. # Arguments ============ - - `arch`: The architecture to use (default: `CPU()`). - `FT`: The floating-point type to use (default: `Float64`). From 881b5b01f1cb1ef0a3fe8133e0126c055fe278d7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 13 Jun 2024 09:43:16 -0400 Subject: [PATCH 513/716] Update src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl Co-authored-by: Gregory L. Wagner --- .../CrossRealmFluxes/tabulated_albedo.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index e2197c76..aefff645 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -45,10 +45,10 @@ const α_payne = [ 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0 """ TabulatedAlbedo(arch = CPU(), FT = Float64; - S₀ = convert(FT, 1365), - α_table = α_payne, - φ_values = (0:2:90) ./ 180 * π, - 𝓉_values = 0:0.05:1) + S₀ = convert(FT, 1365), + α_table = α_payne, + φ_values = (0:2:90) ./ 180 * π, + 𝓉_values = 0:0.05:1) Constructs a `TabulatedAlbedo` object that interpolated the albedo from a value table `α_table` that is function of latitude `φ` and atmospheric transimissivity `𝓉`. From 21a3e2cc5fbe164d0ba9d98571c8cbc4bf522a02 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 13 Jun 2024 09:46:58 -0400 Subject: [PATCH 514/716] correct typo --- src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index 5208db51..fbc0e279 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -1,7 +1,7 @@ struct MomentumRoughnessLength{FT, V} gravitational_acceleration :: FT air_kinematic_viscosity :: V - _wave_parameter :: FT + gravity_wave_parameter :: FT laminar_parameter :: FT maximum_roughness_length :: FT end @@ -65,7 +65,7 @@ function MomentumRoughnessLength(FT=Float64; return MomentumRoughnessLength(convert(FT, gravitational_acceleration), air_kinematic_viscosity, - convert(FT, _wave_parameter), + convert(FT, gravity_wave_parameter), convert(FT, laminar_parameter), convert(FT, maximum_roughness_length)) end @@ -98,7 +98,7 @@ end # Temperature and water vapor can be considered the same (Edson et al 2013) @inline function roughness_length(ℓ::MomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT g = ℓ.gravitational_acceleration - α = ℓ._wave_parameter + α = ℓ.gravity_wave_parameter β = ℓ.laminar_parameter ℓm = ℓ.maximum_roughness_length From 3f7149a61df6d7de20c96fd3d53dbca5648b1d67 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 13 Jun 2024 11:05:36 -0400 Subject: [PATCH 515/716] Update src/OceanSeaIceModels/ocean_only_model.jl Co-authored-by: Gregory L. Wagner --- src/OceanSeaIceModels/ocean_only_model.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 7d290a3f..1fa1b3ce 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -4,7 +4,7 @@ const OceanSimplifiedSeaIceModel = OceanSeaIceModel{<:MinimumTemperatureSeaIce} const NoSeaIceModel = Union{OceanOnlyModel, OceanSimplifiedSeaIceModel} ##### -##### No ice-ocean fluxes in this models!! +##### No ice-ocean fluxes in these models!! ##### import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: compute_sea_ice_ocean_fluxes! From 03533f4ab48965132f695c1a8f9ffc4a6710fef3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:56:31 -0400 Subject: [PATCH 516/716] TemperatureDependentAirViscosity and ReynoldsScalingFunction --- .../CrossRealmFluxes/roughness_lengths.jl | 65 ++++++++++++++++--- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index fbc0e279..b54bff29 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -59,7 +59,7 @@ Keyword Arguments function MomentumRoughnessLength(FT=Float64; gravitational_acceleration = default_gravitational_acceleration, maximum_roughness_length = 1.0, # An estimate? - air_kinematic_viscosity = temperature_dependent_viscosity, + air_kinematic_viscosity = TemperatureDependentViscosity(FT), gravity_wave_parameter = 0.011, laminar_parameter = 0.11) @@ -77,17 +77,43 @@ function default_roughness_lengths(FT=Float64) return SimilarityScales(momentum, temperature, water_vapor) end -# Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ ℓu / ν` -# Edson et al. (2013), equation (28) -@inline empirical_scaling_function(R★ :: FT, args...) where FT = - ifelse(R★ == 0, FT(0), convert(FT, 5.85e-5 / R★ ^ 0.72)) +# Temperature-dependent viscosity law +struct TemperatureDependentAirViscosity{FT} + C₀ :: FT + C₁ :: FT + C₂ :: FT + C₃ :: FT +end -# Temeprature-dependent viscosity law: assumes that θ comes in Kelvin -@inline function temperature_dependent_viscosity(θ :: FT) where FT +""" + TemperatureDependentAirViscosity([FT = Float64; + C₀ = 1.326e-5, + C₁ = C₀ * 6.542e-3, + C₂ = C₀ * 8.301e-6, + C₃ = - C₀ * 4.84e-9]) + +Constructs a `TemperatureDependentAirViscosity` object that calculates the kinematic +viscosity of air as +```math +C₀ + C₁ T + C₂ T^2 + C₃ T^3. +``` +""" +function TemperatureDependentAirViscosity(FT = Float64; + C₀ = 1.326e-5, + C₁ = C₀ * 6.542e-3, + C₂ = C₀ * 8.301e-6, + C₃ = - C₀ * 4.84e-9) + + return TemperatureDependentAirViscosity(convert(FT, C₀), + convert(FT, C₁), + convert(FT, C₂), + convert(FT, C₃)) +end + +""" Calculate the air viscosity based on the temperature θ in Celsius. """ +@inline function (ν::TemperatureDependentViscosity)(θ) T = convert(FT, θ - celsius_to_kelvin) - ν = convert(FT, 1.326e-5 * (1 + 6.542e-3 * T + 8.301e-6 * T^2 - 4.84e-9 * T^3)) - - return ν + return C₀ + C₁ * T + C₂ * T^2 + C₃ * T^3 end # Fallbacks for constant roughness length! @@ -113,6 +139,25 @@ end return min(α * u★^2 / g + ℓᴿ, ℓm) end +struct ReynoldsScalingFunction{FT} + A :: FT + b :: FT +end + +""" + ReynoldsScalingFunction(FT = Float64; A = 5.85e-5, b = 0.72) + +Empirical fit of the scalar roughness length with roughness Reynolds number `R★ = u★ ℓu / ν`. +Edson et al. (2013), equation (28). +```math + ℓs = A / R★ ^ b +``` +""" +ReynoldsScalingFunction(FT = Float64; A = 5.85e-5, b = 0.72) = + ReynoldsScalingFunction(convert(FT, A), convert(FT, b)) + +@inline (s::ReynoldsScalingFunction)(R★, args...) = ifelse(R★ == 0, FT(0), s.A / R★ ^ s.b) + # Edson 2013 formulation of scalar roughness length @inline function roughness_length(ℓ::ScalarRoughnessLength{FT}, ℓu, u★, 𝒬, ℂ) where FT ℓm = ℓ.maximum_roughness_length From 5ac8c83b11dca83672d9494d719d5b49f72473e8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:57:04 -0400 Subject: [PATCH 517/716] update ScalarRoughnessLength --- src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index b54bff29..f94c42f8 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -30,7 +30,7 @@ Keyword Arguments """ function ScalarRoughnessLength(FT=Float64; air_kinematic_viscosity = temperature_dependent_viscosity, - reynolds_number_scaling_function = empirical_scaling_function, + reynolds_number_scaling_function = ReynoldsScalingFunction(FT), maximum_roughness_length = 1.6e-4) # Values from COARE3.6 return ScalarRoughnessLength(air_kinematic_viscosity, From 28eb46cc3c5fee2618c4fd70c2a4485a82d74350 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:04:58 -0400 Subject: [PATCH 518/716] correct FT in albedo --- src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index aefff645..90637765 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -78,9 +78,9 @@ function TabulatedAlbedo(arch = CPU(), FT = Float64; 𝓉_values = 0:0.05:1) # Make everything GPU - ready - α_table = on_architecture(arch, α_table) - φ_values = on_architecture(arch, φ_values) - 𝓉_values = on_architecture(arch, 𝓉_values) + α_table = on_architecture(arch, convert.(FT, α_table)) + φ_values = on_architecture(arch, convert.(FT, φ_values)) + 𝓉_values = on_architecture(arch, convert.(FT, 𝓉_values)) return TabulatedAlbedo(α_table, φ_values, 𝓉_values, S₀) end From a1f3669a22690a1462bfe34dc5b54c020d3ff91a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:09:07 -0400 Subject: [PATCH 519/716] bugfix --- src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index f94c42f8..e07c3cb8 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -111,7 +111,7 @@ function TemperatureDependentAirViscosity(FT = Float64; end """ Calculate the air viscosity based on the temperature θ in Celsius. """ -@inline function (ν::TemperatureDependentViscosity)(θ) +@inline function (ν::TemperatureDependentAirViscosity)(θ) T = convert(FT, θ - celsius_to_kelvin) return C₀ + C₁ * T + C₂ * T^2 + C₃ * T^3 end From 1202a84abfe9f997a21cba92259e2e478b475090 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 13 Jun 2024 13:10:34 -0400 Subject: [PATCH 520/716] bugfix --- src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index e07c3cb8..c892e8cb 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -59,7 +59,7 @@ Keyword Arguments function MomentumRoughnessLength(FT=Float64; gravitational_acceleration = default_gravitational_acceleration, maximum_roughness_length = 1.0, # An estimate? - air_kinematic_viscosity = TemperatureDependentViscosity(FT), + air_kinematic_viscosity = TemperatureDependentAirViscosity(FT), gravity_wave_parameter = 0.011, laminar_parameter = 0.11) From 3d6bb8f04f880eec4945f84cb95f4f42271409ff Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:02:23 -0400 Subject: [PATCH 521/716] FT for tabulated albedo --- .../CrossRealmFluxes/tabulated_albedo.jl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index 90637765..ce9cb2b9 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -1,5 +1,6 @@ using Oceananigans.Fields: interpolator using Oceananigans.Grids: on_architecture +using Base using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, @@ -82,17 +83,21 @@ function TabulatedAlbedo(arch = CPU(), FT = Float64; φ_values = on_architecture(arch, convert.(FT, φ_values)) 𝓉_values = on_architecture(arch, convert.(FT, 𝓉_values)) - return TabulatedAlbedo(α_table, φ_values, 𝓉_values, S₀) + return TabulatedAlbedo(α_table, φ_values, 𝓉_values, convert(FT, S₀)) end +Base.eltype(α::TabulatedAlbedo) = Base.eltype(α.S₀) + @inline ϕ₁(ξ, η) = (1 - ξ) * (1 - η) @inline ϕ₂(ξ, η) = (1 - ξ) * η @inline ϕ₃(ξ, η) = ξ * (1 - η) @inline ϕ₄(ξ, η) = ξ * η -@inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}) +@inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}) α = radiation.reflection.ocean + FT = eltype(α) + λ, φ, z = node(i, j, 1, grid, Center(), Center(), Center()) φ = deg2rad(φ) @@ -100,7 +105,7 @@ end time = time.time day = time ÷ 86400 - day2rad = 2π / 86400 + day2rad = convert(FT, 2π / 86400) noon_in_sec = 86400 ÷ 2 sec_of_day = time - day * 86400 @@ -109,8 +114,9 @@ end h = (sec_of_day - noon_in_sec) * day2rad + λ # Declination angle δ - march_first = 80.0 + march_first = 80 δ = deg2rad((23 + 27/60) * sind(360 * (day - march_first) / 365.25)) + δ = convert(FT, δ) # Zenith angle of the sun (if smaller than 0 we are in the dark) cosθₛ = max(0, sin(φ) * sin(δ) + cos(h) * cos(δ) * cos(φ)) From 03f35cec04a3af2bdeaae9fedb0ac41dca91c1c4 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 14 Jun 2024 14:45:02 -0400 Subject: [PATCH 522/716] using zstar --- zstar_prototype_omip/Manifest.toml | 1822 +++++++++++++++++ zstar_prototype_omip/Project.toml | 13 + .../prototype_omip_simulation.jl | 174 ++ zstar_prototype_omip/setup_satori.sh | 23 + .../tripolar_specific_methods.jl | 72 + .../xin_kai_vertical_diffusivity.jl | 252 +++ 6 files changed, 2356 insertions(+) create mode 100644 zstar_prototype_omip/Manifest.toml create mode 100644 zstar_prototype_omip/Project.toml create mode 100644 zstar_prototype_omip/prototype_omip_simulation.jl create mode 100755 zstar_prototype_omip/setup_satori.sh create mode 100644 zstar_prototype_omip/tripolar_specific_methods.jl create mode 100644 zstar_prototype_omip/xin_kai_vertical_diffusivity.jl diff --git a/zstar_prototype_omip/Manifest.toml b/zstar_prototype_omip/Manifest.toml new file mode 100644 index 00000000..ceaace7e --- /dev/null +++ b/zstar_prototype_omip/Manifest.toml @@ -0,0 +1,1822 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.1" +manifest_format = "2.0" +project_hash = "1cab777b23bf99dac075dcd3cc1d9faf7933f586" + +[[deps.ANSIColoredPrinters]] +git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" +uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" +version = "0.0.1" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] +git-tree-sha1 = "c0d491ef0b135fd7d63cbc6404286bc633329425" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.36" + + [deps.Accessors.extensions] + AccessorsAxisKeysExt = "AxisKeys" + AccessorsIntervalSetsExt = "IntervalSets" + AccessorsStaticArraysExt = "StaticArrays" + AccessorsStructArraysExt = "StructArrays" + AccessorsUnitfulExt = "Unitful" + + [deps.Accessors.weakdeps] + AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.0.4" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "133a240faec6e074e07c31ee75619c90544179cf" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.10.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = "CUDSS" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random", "Test"] +git-tree-sha1 = "2c7cc21e8678eff479978a0a2ef5ce2f51b63dff" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.BitTwiddlingConvenienceFunctions]] +deps = ["Static"] +git-tree-sha1 = "0c5f81f47bbbcf4aea7b2959135713459170798b" +uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" +version = "0.1.5" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.5+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.3" + +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] +git-tree-sha1 = "585a387a490f1c4bd88be67eea15b93da5e85db7" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.5" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] +git-tree-sha1 = "fe61a257e94621e25471071ca58d29ea45eef13b" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.3.4" + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + EnzymeCoreExt = "EnzymeCore" + SpecialFunctionsExt = "SpecialFunctions" + + [deps.CUDA.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "dc172b558adbf17952001e15cf0d6364e6d78c2f" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.8.1+0" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "38f830504358e9972d2a0c3e5d51cb865e0733df" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.2.4" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "4ca7d6d92075906c2ce871ea8bba971fff20d00c" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.12.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 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+2" + +[[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", "CFTime", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "FFMPEG", "ImageMorphology", "JLD2", "JSON3", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "Revise", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +path = ".." +uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +version = "0.2.0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "c900eecbb9cc3989602cfe9524070e225f512fe1" +repo-rev = "ss/new-oceananigans" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.1.0" + +[[deps.CloseOpenIntervals]] +deps = ["Static", "StaticArrayInterface"] +git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" +uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" +version = "0.1.12" + +[[deps.CodeTracking]] +deps = ["InteractiveUtils", "UUIDs"] +git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386" +uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" +version = "1.3.5" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.5" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.11" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "d6fb5bf939a2753c74984b11434ea25d6c397a58" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.6" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.15.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.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.CpuId]] +deps = ["Markdown"] +git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" +uuid = "adafc99b-e345-5852-983c-f28acb93d879" +version = "0.3.1" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] +git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.2.5" + +[[deps.CubicSplines]] +deps = ["Random", "Test"] +git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" +uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" +version = "0.2.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.20" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DiskArrays]] +deps = ["LRUCache", "OffsetArrays"] +git-tree-sha1 = "ef25c513cad08d7ebbed158c91768ae32f308336" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.3.23" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.8.6" + +[[deps.Documenter]] +deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] +git-tree-sha1 = "5461b2a67beb9089980e2f8f25145186b6d34f91" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "1.4.1" + +[[deps.DocumenterTools]] +deps = ["Base64", "DocStringExtensions", "LibGit2"] +git-tree-sha1 = "58db9d1c626de92318ee35cbaf466739f4b5a09a" +uuid = "35a29f4d-8980-5a13-9543-d66fff28ecb8" +version = "0.1.2" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.Elliptic]] +git-tree-sha1 = "71c79e77221ab3a29918aaf6db4f217b89138608" +uuid = "b305315f-e792-5b7a-8f41-49f472929428" +version = "1.0.1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c6317308b9dc757616f0b5cb379db10494443a7" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.6.2+0" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.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 = "4820348781ae578893311153d69049a93d05f39d" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.8.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.10+0" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.3" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.96+0" + +[[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.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.2+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.14+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 = "68e8ff56a4a355a85d2784b94614491f8c900cde" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "10.1.0" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "1600477fba37c9fc067b9be21f5e8101f24a8865" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.26.4" + +[[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 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.2+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.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "38c8874692d48d5440d5752d6c74b0c6b0b60739" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.2+1" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.8" + +[[deps.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.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] +git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.16" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.10.0+0" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "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.ImageCore]] +deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "b2a7eaa169c13f5bcae8131a83bc30eff8f71be0" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.2" + +[[deps.ImageMorphology]] +deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] +git-tree-sha1 = "6f0a801136cb9c229aebea0df296cdcd471dbcd1" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.4.5" + +[[deps.IncompleteLU]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "6c676e79f98abb6d33fa28122cad099f1e464afe" +uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" +version = "0.2.1" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be50fe8df3acbffa0274a744f1a99d29c45a57f4" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.1.0+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "e7cbed5032c4c397a6ac23d1493f3289e01231c4" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.14" +weakdeps = ["Dates"] + + [deps.InverseFunctions.extensions] + DatesExt = "Dates" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] +git-tree-sha1 = "bdbe8222d2f5703ad6a7019277d149ec6d78c301" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.48" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.13.2" + +[[deps.JuliaInterpreter]] +deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] +git-tree-sha1 = "e9648d90370e2d0317f9518c9c6e0841db54a90b" +uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" +version = "0.9.31" + +[[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 = "db02395e4c374030c53dc28f3c1d33dec35f7272" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.19" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.2+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"] +git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.2+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LayoutPointers]] +deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "62edfee3211981241b57ff1cedf4d74d79519277" +uuid = "10f19ff3-798f-405d-979b-55457f8fc047" +version = "0.1.15" + +[[deps.LazilyInitializedFields]] +git-tree-sha1 = "8f7f3cabab0fd1800699663533b6d5cb3fc0e612" +uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf" +version = "1.2.2" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.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"] +git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.11+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.49.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 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.40.1+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.40.1+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.LoopVectorization]] +deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] +git-tree-sha1 = "8f6786d8b2b3248d79db3ad359ce95382d5a6df8" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.170" +weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.LoweredCodeUtils]] +deps = ["JuliaInterpreter"] +git-tree-sha1 = "c6a36b22d2cca0e1a903f00f600991f97bf5f426" +uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" +version = "2.4.6" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.9.4+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "80b2833b56d466b3858d565adcd16a4a05f2089b" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.1.0+0" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "b4d8707e42b693720b54f0b3434abee6dd4d947a" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.16" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "4099bb6809ac109bfc17d521dad33763bcf026b7" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.2.1+1" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.11" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "ce0ca3dd147c43de175c5aff161315a424f4b8ac" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.3.3+1" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MarkdownAST]] +deps = ["AbstractTrees", "Markdown"] +git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" +uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" +version = "0.1.2" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f12a29c4400ba812841c6ace3f4efbb6dbb3ba01" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "a640912695952b074672edb5f9aaee2f7f9fd59a" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.4" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "53046f0483375e3ed78e49190f1154fa0a4083a1" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "0.3.4" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ce3269ed42816bf18d500c9f63418d4b0d9f5a3b" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.1.0+2" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenMPI_jll", "XML2_jll", "Zlib_jll", "Zstd_jll", "libzip_jll"] +git-tree-sha1 = "a8af1798e4eb9ff768ce7fdefc0e957097793f15" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "400.902.209+0" + +[[deps.Nettle_jll]] +deps = ["Artifacts", "GMP_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "eca63e3847dad608cfa6a3329b95ef674c7160b4" +uuid = "4c82536e-c426-54e4-b420-14f461c4ed8b" +version = "3.7.2+0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Oceananigans]] +deps = ["Adapt", "CUDA", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFMPEG", "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 = "b448ece653f305dedaa372c3a113179fe2015895" +repo-rev = "ss/z-star-coordinate" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.91.0" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "e64b4f5ea6b7389f6f046d13d4896a8f9c1ba71e" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.14.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.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.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 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.3" + +[[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.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.OrthogonalSphericalShellGrids]] +deps = ["Adapt", "CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays", "Printf"] +git-tree-sha1 = "f67a694f199a05eb618ef3d90fa9e5fbb7ed7410" +repo-rev = "main" +repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl" +uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" +version = "0.1.0" + +[[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.PMIx_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] +git-tree-sha1 = "360f48126b5f2c2f0c833be960097f7c62705976" +uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" +version = "4.2.9+0" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.PencilArrays]] +deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] +git-tree-sha1 = "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.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.43.4+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.PolyesterWeave]] +deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] +git-tree-sha1 = "240d7170f5ffdb285f9427b92333c3463bf65bf6" +uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" +version = "0.2.1" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "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.RegistryInstances]] +deps = ["LazilyInitializedFields", "Pkg", "TOML", "Tar"] +git-tree-sha1 = "ffd19052caf598b8653b99404058fce14828be51" +uuid = "2792f1a3-b283-48e8-9a74-f99dce5104f3" +version = "0.1.0" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.Revise]] +deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"] +git-tree-sha1 = "12aa2d7593df490c407a3bbd8b86b8b515017f3e" +uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" +version = "3.5.14" + +[[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.SIMDTypes]] +git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" +uuid = "94e857df-77ce-4151-89e5-788b33177be4" +version = "0.1.0" + +[[deps.SLEEFPirates]] +deps = ["IfElse", "Static", "VectorizationBase"] +git-tree-sha1 = "3aac6d68c5e57449f5b9b865c9ba50ac2970c4cf" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.42" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "6d85acd6de472f8e6da81c61c7c5b6280a55e0bc" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.4" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "363c4e82b66be7b9f7c7c7da7478fdae07de44b9" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.2" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.4.0" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.Static]] +deps = ["IfElse"] +git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "0.8.10" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.5.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "9ae599cd7529cfce7fea36cf00a62cfc56f0f37c" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.4" +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.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 = "48098ebfee40374b8415b602163e02aa7c43d32b" +repo-rev = "glw/density-example" +repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.5" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.ThreadingUtilities]] +deps = ["ManualMemory"] +git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" +uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" +version = "0.5.2" + +[[deps.TiledIteration]] +deps = ["OffsetArrays", "StaticArrayInterface"] +git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" +uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" +version = "0.5.0" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "5a13ae8a41237cff5ecf34f73eb1b8f42fff6531" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.24" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "5d54d076465da49d6746c647022f3b3674e64156" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.8" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.TupleTools]] +git-tree-sha1 = "41d61b1c545b06279871ef1a4b5fcb2cac2191cd" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.5.0" + +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.2.1" + +[[deps.UnsafeAtomicsLLVM]] +deps = ["LLVM", "UnsafeAtomics"] +git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.3" + +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "6129a4faf6242e7c3581116fbe3270f3ab17c90d" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.67" + +[[deps.VersionParsing]] +git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.3.0" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "52ff2af32e591541550bd753c0da8b9bc92bb9d9" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.7+0" + +[[deps.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", "Xorg_libX11_jll"] +git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.6+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.11+0" + +[[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.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"] +git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.9.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.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.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2021.12.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[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/zstar_prototype_omip/Project.toml b/zstar_prototype_omip/Project.toml new file mode 100644 index 00000000..e8e6b41f --- /dev/null +++ b/zstar_prototype_omip/Project.toml @@ -0,0 +1,13 @@ +[deps] +Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +CFTime = "179af706-886a-5703-950a-314cd64e0468" +ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +OrthogonalSphericalShellGrids = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" +SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +SurfaceFluxes = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" diff --git a/zstar_prototype_omip/prototype_omip_simulation.jl b/zstar_prototype_omip/prototype_omip_simulation.jl new file mode 100644 index 00000000..40fc5b14 --- /dev/null +++ b/zstar_prototype_omip/prototype_omip_simulation.jl @@ -0,0 +1,174 @@ +using Printf +using Oceananigans +using Oceananigans.Units +using ClimaOcean +using OrthogonalSphericalShellGrids +using Oceananigans +using Oceananigans: architecture +using ClimaOcean +using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity +using Oceananigans.Coriolis: ActiveCellEnstrophyConserving +using Oceananigans.Units +using ClimaOcean.OceanSimulations +using ClimaOcean.OceanSeaIceModels +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes +using ClimaOcean.VerticalGrids: exponential_z_faces +using ClimaOcean.JRA55 +using ClimaOcean.ECCO +using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere +using ClimaOcean.ECCO: ECCO_restoring_forcing, ECCO4Monthly, ECCO2Daily, ECCOMetadata +using ClimaOcean.Bathymetry + +using CFTime +using Dates + +include("tripolar_specific_methods.jl") +include("xin_kai_vertical_diffusivity.jl") + +##### +##### Global Ocean at 1/6th of a degree +##### + +bathymetry_file = nothing # "bathymetry_tmp.jld2" + +# 60 vertical levels +z_faces = exponential_z_faces(Nz=60, depth=6500) + +Nx = 2160 +Ny = 1100 +Nz = length(z_faces) - 1 + +arch = GPU() #Distributed(GPU(), partition = Partition(2)) + +grid = TripolarGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = z_faces, + north_poles_latitude = 45, + first_pole_longitude = 75) + +bottom_height = retrieve_bathymetry(grid, bathymetry_file; + minimum_depth = 10, + dir = "./", + interpolation_passes = 20, + connected_regions_allowed = 0) + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) + +using Oceananigans.Models.HydrostaticFreeSurfaceModels: generalized_spacing_grid, ZStar + +grid = generalized_spacing_grid(grid, ZStar()) + +##### +##### The Ocean component +##### + +const Lz = grid.Lz +const h = Nz / 4.5 + +@inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) +@inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) + +free_surface = SplitExplicitFreeSurface(grid; substeps = 75) +vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = νz) + +closure = XinKaiVerticalDiffusivity() # (RiBasedVerticalDiffusivity(), vertical_diffusivity) # + +##### +##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic +##### + +ocean = ocean_simulation(grid; free_surface, closure) +model = ocean.model + +initial_date = DateTimeProlepticGregorian(1993, 1, 1) + +set!(model, + T = ECCOMetadata(:temperature, initial_date, ECCO2Daily()), + S = ECCOMetadata(:salinity, initial_date, ECCO2Daily())) + +##### +##### The atmosphere +##### + +backend = JRA55NetCDFBackend(4) +atmosphere = JRA55_prescribed_atmosphere(arch; backend) +radiation = Radiation(arch) + +sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() + +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +wall_time = [time_ns()] + +function progress(sim) + u, v, w = sim.model.velocities + T, S = sim.model.tracers + + Tmax = maximum(interior(T)) + Tmin = minimum(interior(T)) + umax = maximum(interior(u)), maximum(interior(v)), maximum(interior(w)) + step_time = 1e-9 * (time_ns() - wall_time[1]) + + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", + prettytime(sim.model.clock.time), + sim.model.clock.iteration, + prettytime(sim.Δt), + umax..., Tmax, Tmin, prettytime(step_time)) + + wall_time[1] = time_ns() +end + +ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +fluxes = (u = model.velocities.u.boundary_conditions.top.condition, + v = model.velocities.v.boundary_conditions.top.condition, + T = model.tracers.T.boundary_conditions.top.condition, + S = model.tracers.S.boundary_conditions.top.condition) + +ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, + schedule = TimeInterval(0.5days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "surface_fluxes_experimental") + +ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(0.5days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "surface_experimental", + indices = (:, :, grid.Nz)) + +ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), + schedule = TimeInterval(10days), + overwrite_existing = true, + array_type = Array{Float32}, + filename = "snapshots_experimental") + +ocean.output_writers[:checkpoint] = Checkpointer(model, + schedule = TimeInterval(60days), + overwrite_existing = true, + prefix = "checkpoint_experimental") + +# Simulation warm up! +ocean.Δt = 10 +ocean.stop_iteration = 1 +wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) + +stop_time = 10days + +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) + +run!(coupled_simulation) + +wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 800, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) + +# Let's reset the maximum number of iterations +coupled_model.ocean.stop_time = 7200days +coupled_simulation.stop_time = 7200days +coupled_model.ocean.stop_iteration = Inf +coupled_simulation.stop_iteration = Inf + +run!(coupled_simulation) diff --git a/zstar_prototype_omip/setup_satori.sh b/zstar_prototype_omip/setup_satori.sh new file mode 100755 index 00000000..760e4e72 --- /dev/null +++ b/zstar_prototype_omip/setup_satori.sh @@ -0,0 +1,23 @@ +# Upload modules +module purge all +module add spack +module add cuda/11.4 +module load openmpi/3.1.6-cuda-pmi-ucx-slurm-jhklron + +# MPI specific exports +export OMPI_MCA_pml=^ucx +export OMPI_MCA_osc=^ucx +export OMPI_MCA_btl_openib_allow_ib=true + +# Julia specific enviromental variables +export COMMON="/nobackup/users/ssilvest/perlmutter-test" +export JULIA="${COMMON}/julia/julia" + +export JULIA_CUDA_MEMORY_POOL=none +export JULIA_DEPOT_PATH="${COMMON}/depot" + +# Profile specific variable +export JULIA_NVTX_CALLBACKS=gc + +# Number of threads in SLURM mode +export JULIA_NUM_THREADS=${SLURM_CPUS_PER_TASK:=1} diff --git a/zstar_prototype_omip/tripolar_specific_methods.jl b/zstar_prototype_omip/tripolar_specific_methods.jl new file mode 100644 index 00000000..c248f35e --- /dev/null +++ b/zstar_prototype_omip/tripolar_specific_methods.jl @@ -0,0 +1,72 @@ +using ClimaOcean +import ClimaOcean.InitialConditions: interpolate! + +using Oceananigans +using Oceananigans.Operators +using Oceananigans.BoundaryConditions +using Oceananigans.Fields: OneField +using Oceananigans.Grids: peripheral_node +using Oceananigans.Utils: launch! +using Oceananigans.Fields: instantiated_location, interior, CenterField +using Oceananigans.Architectures: architecture, device, GPU, child_architecture + +# Implementation of 3-dimensional regridding +# TODO: move all the following to Oceananigans! + +using Oceananigans.Fields: regrid!, interpolate! +using Oceananigans.Grids: cpu_face_constructor_x, + cpu_face_constructor_y, + cpu_face_constructor_z, + topology, + λnode, φnode + +using OrthogonalSphericalShellGrids: TRG +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, convert_to_native_frame + +@inline hack_cosd(φ) = cos(π * φ / 180) +@inline hack_sind(φ) = sin(π * φ / 180) + +# Here we assume that the tripolar grid is locally orthogonal +@inline function convert_to_latlong_frame(i, j, grid::TRG, uₒ, vₒ) + + φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) + φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) + Δyᶜᶜᵃ = Δyᶜᶜᶜ(i, j, 1, grid) + + ũ = deg2rad(φᶜᶠᵃ₊ - φᶜᶠᵃ₋) / Δyᶜᶜᵃ + + φᶠᶜᵃ₊ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) + φᶠᶜᵃ₋ = φnode(i, j, 1, grid, Face(), Center(), Center()) + Δxᶜᶜᵃ = Δxᶜᶜᶜ(i, j, 1, grid) + + ṽ = - deg2rad(φᶠᶜᵃ₊ - φᶠᶜᵃ₋) / Δxᶜᶜᵃ + + 𝒰 = sqrt(ũ^2 + ṽ^2) + + d₁ = ũ / 𝒰 + d₂ = ṽ / 𝒰 + + return uₒ * d₁ - vₒ * d₂, uₒ * d₂ + vₒ * d₁ +end + +@inline function convert_to_native_frame(i, j, grid::TRG, uₒ, vₒ) + + φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) + φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) + Δyᶜᶜᵃ = Δyᶜᶜᶜ(i, j, 1, grid) + + ũ = deg2rad(φᶜᶠᵃ₊ - φᶜᶠᵃ₋) / Δyᶜᶜᵃ + + φᶠᶜᵃ₊ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) + φᶠᶜᵃ₋ = φnode(i, j, 1, grid, Face(), Center(), Center()) + Δxᶜᶜᵃ = Δxᶜᶜᶜ(i, j, 1, grid) + + ṽ = - deg2rad(φᶠᶜᵃ₊ - φᶠᶜᵃ₋) / Δxᶜᶜᵃ + + 𝒰 = sqrt(ũ^2 + ṽ^2) + + d₁ = ũ / 𝒰 + d₂ = ṽ / 𝒰 + + return uₒ * d₁ + vₒ * d₂, uₒ * d₂ - vₒ * d₁ +end diff --git a/zstar_prototype_omip/xin_kai_vertical_diffusivity.jl b/zstar_prototype_omip/xin_kai_vertical_diffusivity.jl new file mode 100644 index 00000000..fbc127a6 --- /dev/null +++ b/zstar_prototype_omip/xin_kai_vertical_diffusivity.jl @@ -0,0 +1,252 @@ +using Oceananigans +using Oceananigans.Architectures: architecture +using Oceananigans.BuoyancyModels: ∂z_b +using Oceananigans.Operators +using Oceananigans.Grids: inactive_node +using Oceananigans.Operators: ℑzᵃᵃᶜ, ℑxyᶠᶠᵃ, ℑxyᶜᶜᵃ + +using Adapt + +using KernelAbstractions: @index, @kernel +using KernelAbstractions.Extras.LoopInfo: @unroll + +using Oceananigans.TurbulenceClosures: + tapering_factorᶠᶜᶜ, + tapering_factorᶜᶠᶜ, + tapering_factorᶜᶜᶠ, + tapering_factor, + SmallSlopeIsopycnalTensor, + AbstractScalarDiffusivity, + ExplicitTimeDiscretization, + FluxTapering, + isopycnal_rotation_tensor_xz_ccf, + isopycnal_rotation_tensor_yz_ccf, + isopycnal_rotation_tensor_zz_ccf + +import Oceananigans.TurbulenceClosures: + compute_diffusivities!, + DiffusivityFields, + viscosity, + diffusivity, + getclosure, + top_buoyancy_flux, + diffusive_flux_x, + diffusive_flux_y, + diffusive_flux_z, + viscous_flux_ux, + viscous_flux_vx, + viscous_flux_uy, + viscous_flux_vy + +using Oceananigans.Utils: launch! +using Oceananigans.Coriolis: fᶠᶠᵃ +using Oceananigans.Operators +using Oceananigans.BuoyancyModels: ∂x_b, ∂y_b, ∂z_b + +using Oceananigans.TurbulenceClosures +using Oceananigans.TurbulenceClosures: HorizontalFormulation, VerticalFormulation, AbstractScalarDiffusivity +using Oceananigans.TurbulenceClosures: AbstractScalarBiharmonicDiffusivity +using Oceananigans.Operators +using Oceananigans.Operators: Δxᶜᶜᶜ, Δyᶜᶜᶜ, ℑxyᶜᶜᵃ, ζ₃ᶠᶠᶜ, div_xyᶜᶜᶜ +using Oceananigans.Operators: Δx, Δy +using Oceananigans.Operators: ℑxyz + +using Oceananigans.Operators: ℑxyzᶜᶜᶠ, ℑyzᵃᶜᶠ, ℑxzᶜᵃᶠ, Δxᶜᶜᶜ, Δyᶜᶜᶜ + +struct XinKaiVerticalDiffusivity{TD, FT} <: AbstractScalarDiffusivity{TD, VerticalFormulation, 2} + ν₀ :: FT + νˢʰ :: FT + νᶜⁿ :: FT + Cᵉⁿ :: FT + Prₜ :: FT + Riᶜ :: FT + δRi :: FT + Q₀ :: FT + δQ :: FT +end + +function XinKaiVerticalDiffusivity{TD}(ν₀ :: FT, + νˢʰ :: FT, + νᶜⁿ :: FT, + Cᵉⁿ :: FT, + Prₜ :: FT, + Riᶜ :: FT, + δRi :: FT, + Q₀ :: FT, + δQ :: FT) where {TD, FT} + + return XinKaiVerticalDiffusivity{TD, FT}(ν₀, νˢʰ, νᶜⁿ, Cᵉⁿ, Prₜ, Riᶜ, δRi, Q₀, δQ) +end + +function XinKaiVerticalDiffusivity(time_discretization = VerticallyImplicitTimeDiscretization(), + FT = Float64; + ν₀ = 1e-5, + νˢʰ = 0.0885, + νᶜⁿ = 4.3668, + Cᵉⁿ = 0.2071, + Prₜ = 1.207, + Riᶜ = - 0.21982, + δRi = 8.342e-4, + Q₀ = 0.08116, + δQ = 0.02622) + + TD = typeof(time_discretization) + + return XinKaiVerticalDiffusivity{TD}(convert(FT, ν₀), + convert(FT, νˢʰ), + convert(FT, Cᵉⁿ), + convert(FT, Cᵉⁿ), + convert(FT, Prₜ), + convert(FT, Riᶜ), + convert(FT, δRi), + convert(FT, Q₀), + convert(FT, δQ)) +end + +XinKaiVerticalDiffusivity(FT::DataType; kw...) = + XinKaiVerticalDiffusivity(VerticallyImplicitTimeDiscretization(), FT; kw...) + +Adapt.adapt_structure(to, clo::XinKaiVerticalDiffusivity{TD, FT}) where {TD, FT} = + XinKaiVerticalDiffusivity{TD, FT}(clo.ν₀, clo.νˢʰ, clo.νᶜⁿ, clo.Cᵉⁿ, clo.Prₜ, clo.Riᶜ, clo.δRi, clo.Q₀, clo.δQ) + +##### +##### Diffusivity field utilities +##### + +const RBVD = XinKaiVerticalDiffusivity +const RBVDArray = AbstractArray{<:RBVD} +const FlavorOfXKVD = Union{RBVD, RBVDArray} +const c = Center() +const f = Face() + +@inline viscosity_location(::FlavorOfXKVD) = (c, c, f) +@inline diffusivity_location(::FlavorOfXKVD) = (c, c, f) + +@inline viscosity(::FlavorOfXKVD, diffusivities) = diffusivities.κᵘ +@inline diffusivity(::FlavorOfXKVD, diffusivities, id) = diffusivities.κᶜ + +with_tracers(tracers, closure::FlavorOfXKVD) = closure + +# Note: computing diffusivities at cell centers for now. +function DiffusivityFields(grid, tracer_names, bcs, closure::FlavorOfXKVD) + κᶜ = Field((Center, Center, Face), grid) + κᵘ = Field((Center, Center, Face), grid) + Ri = Field((Center, Center, Face), grid) + return (; κᶜ, κᵘ, Ri) +end + +function compute_diffusivities!(diffusivities, closure::FlavorOfXKVD, model; parameters = :xyz) + arch = model.architecture + grid = model.grid + clock = model.clock + tracers = model.tracers + buoyancy = model.buoyancy + velocities = model.velocities + top_tracer_bcs = NamedTuple(c => tracers[c].boundary_conditions.top for c in propertynames(tracers)) + + launch!(arch, grid, parameters, + compute_ri_number!, + diffusivities, + grid, + closure, + velocities, + tracers, + buoyancy, + top_tracer_bcs, + clock) + + # Use `only_local_halos` to ensure that no communication occurs during + # this call to fill_halo_regions! + fill_halo_regions!(diffusivities.Ri; only_local_halos=true) + + launch!(arch, grid, parameters, + compute_xinkai_diffusivities!, + diffusivities, + grid, + closure, + velocities, + tracers, + buoyancy, + top_tracer_bcs, + clock) + + return nothing +end + +@inline ϕ²(i, j, k, grid, ϕ, args...) = ϕ(i, j, k, grid, args...)^2 + +@inline function shear_squaredᶜᶜᶠ(i, j, k, grid, velocities) + ∂z_u² = ℑxᶜᵃᵃ(i, j, k, grid, ϕ², ∂zᶠᶜᶠ, velocities.u) + ∂z_v² = ℑyᵃᶜᵃ(i, j, k, grid, ϕ², ∂zᶜᶠᶠ, velocities.v) + return ∂z_u² + ∂z_v² +end + +@inline function Riᶜᶜᶠ(i, j, k, grid, velocities, buoyancy, tracers) + S² = shear_squaredᶜᶜᶠ(i, j, k, grid, velocities) + N² = ∂z_b(i, j, k, grid, buoyancy, tracers) + Ri = N² / S² + + # Clip N² and avoid NaN + return ifelse(N² <= 0, zero(grid), Ri) +end + +const c = Center() +const f = Face() + +@kernel function compute_ri_number!(diffusivities, grid, closure::FlavorOfXKVD, + velocities, tracers, buoyancy, tracer_bcs, clock) + i, j, k = @index(Global, NTuple) + @inbounds diffusivities.Ri[i, j, k] = Riᶜᶜᶠ(i, j, k, grid, velocities, buoyancy, tracers) +end + +@kernel function compute_xinkai_diffusivities!(diffusivities, grid, closure::FlavorOfXKVD, + velocities, tracers, buoyancy, tracer_bcs, clock) + i, j, k = @index(Global, NTuple) + _compute_xinkai_diffusivities!(i, j, k, diffusivities, grid, closure, + velocities, tracers, buoyancy, tracer_bcs, clock) +end + + +@inline function _compute_xinkai_diffusivities!(i, j, k, diffusivities, grid, closure, + velocities, tracers, buoyancy, tracer_bcs, clock) + + # Ensure this works with "ensembles" of closures, in addition to ordinary single closures + closure_ij = getclosure(i, j, closure) + + ν₀ = closure_ij.ν₀ + νˢʰ = closure_ij.νˢʰ + νᶜⁿ = closure_ij.νᶜⁿ + Cᵉⁿ = closure_ij.Cᵉⁿ + Prₜ = closure_ij.Prₜ + Riᶜ = closure_ij.Riᶜ + δRi = closure_ij.δRi + Q₀ = closure_ij.Q₀ + δQ = closure_ij.δQ + + Qᵇ = top_buoyancy_flux(i, j, grid, buoyancy, tracer_bcs, clock, merge(velocities, tracers)) + + # Convection and entrainment + N² = ∂z_b(i, j, k, grid, buoyancy, tracers) + N²_above = ∂z_b(i, j, k+1, grid, buoyancy, tracers) + + # Conditions + convecting = N² < 0 # applies regardless of Qᵇ + entraining = (N² > 0) & (N²_above < 0) & (Qᵇ > 0) + + # (Potentially) apply a horizontal filter to the Richardson number + Ri = ℑxyᶜᶜᵃ(i, j, k, grid, ℑxyᶠᶠᵃ, diffusivities.Ri) + + # Convective adjustment diffusivity + ν_local = ifelse(convecting, - (νᶜⁿ - νˢʰ) / 2 * tanh(Ri / δRi) + νˢʰ, clamp(Riᶜ * Ri + νˢʰ + ν₀, ν₀, νˢʰ)) + + # Entrainment diffusivity + νᵉⁿ = ifelse(entraining, Cᵉⁿ * Qᵇ / N², zero(grid)) + x = Qᵇ / (N² + 1e-11) + ν_nonlocal = ifelse(entraining, Cᵉⁿ * νᶜⁿ * 0.5 * (tanh((x - Q₀) / δQ) + 1), 0) + + # Update by averaging in time + @inbounds diffusivities.κᵘ[i, j, k] = ν_local + ν_nonlocal + @inbounds diffusivities.κᶜ[i, j, k] = (ν_local + ν_nonlocal) / Prₜ + + return nothing +end From 74190cb8274e9faf0a166ffd05c65dd609952cd3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 16 Jun 2024 15:38:06 -0400 Subject: [PATCH 523/716] small bugfix --- src/Bathymetry.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 2ceb8b98..cd7b10f8 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -7,6 +7,7 @@ using ..DataWrangling: download_progress using Oceananigans using Oceananigans.Architectures: architecture +using Oceananigans.Distributed: child_architecture using Oceananigans.Grids: halo_size, λnodes, φnodes using Oceananigans.Grids: x_domain, y_domain using Oceananigans.Grids: topology @@ -109,7 +110,7 @@ function regrid_bathymetry(target_grid; close(dataset) # Diagnose target grid information - arch = architecture(target_grid) + arch = child_architecture(target_grid) φ₁, φ₂ = y_domain(target_grid) λ₁, λ₂ = x_domain(target_grid) From 8859c50efb9ecd729fe8899ed2002bfa6e06c048 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 16 Jun 2024 15:43:15 -0400 Subject: [PATCH 524/716] bugfix --- src/Bathymetry.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index cd7b10f8..1ecd2d25 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -7,7 +7,7 @@ using ..DataWrangling: download_progress using Oceananigans using Oceananigans.Architectures: architecture -using Oceananigans.Distributed: child_architecture +using Oceananigans.DistributedComputations: child_architecture using Oceananigans.Grids: halo_size, λnodes, φnodes using Oceananigans.Grids: x_domain, y_domain using Oceananigans.Grids: topology From 2625a04906934960cd6da2b0cf39c89478952a22 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 16 Jun 2024 15:50:59 -0400 Subject: [PATCH 525/716] another try --- src/Bathymetry.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 1ecd2d25..a2065e03 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -110,7 +110,7 @@ function regrid_bathymetry(target_grid; close(dataset) # Diagnose target grid information - arch = child_architecture(target_grid) + arch = child_architecture(architecture(target_grid)) φ₁, φ₂ = y_domain(target_grid) λ₁, λ₂ = x_domain(target_grid) From 688eb574a23e9745e7e8e2aeb4cab4a07164d81d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 16 Jun 2024 16:13:11 -0400 Subject: [PATCH 526/716] better default for ECCOMetadata --- src/DataWrangling/ecco_metadata.jl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index 31fda1ca..bbf33950 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -25,7 +25,12 @@ Base.show(io::IO, metadata::ECCOMetadata) = "└── data version: $(metadata.version)") # The default is the ECCO4Monthly dataset at 1992-01-01. -ECCOMetadata(name::Symbol; version = ECCO4Monthly()) = ECCOMetadata(name, DateTimeProlepticGregorian(1992, 1, 1), version) +function ECCOMetadata(name::Symbol; + date = DateTimeProlepticGregorian(1992, 1, 1), + version = ECCO4Monthly()) + + return ECCOMetadata(name, date, version) +end # Treat ECCOMetadata as an array to allow iteration over the dates. Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i], metadata.version) From 4e96e692b21f4e4f5c7724150a341a5a190372b9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 17 Jun 2024 11:34:57 -0400 Subject: [PATCH 527/716] some initial comments --- .../CrossRealmFluxes/stability_functions.jl | 174 ++++++++++++------ 1 file changed, 113 insertions(+), 61 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index ab0d4983..9463bc23 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -26,75 +26,127 @@ function default_stability_functions(FT = Float64) return SimilarityScales(ψu, ψc, ψc) end -# Implementation of stability functions that follow Edson et al (2013) -# We can swap them out easily if we define new types `NewStability` with a method `(f::NewStability)(ζ)` -struct MomentumStabilityFunction{FT} - p₁ :: FT - p₂ :: FT - p₃ :: FT - p₄ :: FT +""" + MomentumStabilityFunction{FT} + +A struct representing the momentum stability function detailed in Edson et al (2013). +The formulation hinges on the definition of three different functions: +one for stable atmospheric conditions ``(ζ > 0)``, named ``ψₛ`` and two for unstable conditions, +named ``ψᵤ₁`` and ``ψᵤ₂``. +These stability functions are obtained by regression to experimental data. + +The stability parameter for stable atmospheric conditions is defined as +```math +dζ = min(ζmax, Aˢζ) +ψₛ = - (Bˢ ζ + Cˢ ( ζ - Dˢ ) ) exp( - dζ) - Cˢ Dˢ +``` + +While the stability parameter for unstable atmospheric conditions is calculated +as a function of the two individual stability functions as follows +```math +fᵤ₁ = √√(1 - Aᵘζ) +ψᵤ₁ = Bᵘ / 2 ⋅ log((1 + fᵤ₁ + fᵤ₁² + fᵤ₁³) / Bᵘ) - √Bᵘ atan(fᵤ₁) - Cᵘ + +fᵤ₂ = ∛(1 - Dᵘζ) +ψᵤ₂ = Eᵘ / 2 ⋅ log((1 + fᵤ₂ + fᵤ₂²) / Eᵘ) - √Eᵘ atan( (1 + 2fᵤ₂) / √Eᵘ) + Fᵘ + +f = ζ² / (1 + ζ²) +ψᵤ = (1 - f) ψᵤ₁ + f ψᵤ₂ +``` + +The superscripts ``ˢ`` and ``ᵘ`` indicate if the parameter applies to the +stability function for _stable_ or _unstable_ atmospheric conditions, respectively. +""" +@kwdef struct MomentumStabilityFunction{FT} + ζmax :: FT = 50.0 + Aˢ :: FT = 0.35 + Bˢ :: FT = 0.7 + Cˢ :: FT = 0.75 + Dˢ :: FT = 5/0.35 + Aᵘ :: FT = 15.0 + Bᵘ :: FT = 2.0 + Cᵘ :: FT = π/2 + Dᵘ :: FT = 10.15 + Eᵘ :: FT = 3.0 + Fᵘ :: FT = π / sqrt(3) end -struct ScalarStabilityFunction{FT} - p₁ :: FT - p₂ :: FT - p₃ :: FT - p₄ :: FT - p₅ :: FT -end - -function MomentumStabilityFunction(FT = Float64; - p₁ = convert(FT, 0.35), - p₂ = convert(FT, 0.7), - p₃ = convert(FT, 15), - p₄ = convert(FT, 10.15)) - - return MomentumStabilityFunction{FT}(convert(FT, p₁), - convert(FT, p₂), - convert(FT, p₃), - convert(FT, p₄)) -end - -function ScalarStabilityFunction(FT = Float64; - p₁ = convert(FT, 0.35), - p₂ = convert(FT, 14.28), - p₃ = convert(FT, 8.525), - p₄ = convert(FT, 15), - p₅ = convert(FT, 34.15)) - - return ScalarStabilityFunction{FT}(convert(FT, p₁), - convert(FT, p₂), - convert(FT, p₃), - convert(FT, p₄), - convert(FT, p₅)) +""" + ScalarStabilityFunction{FT} + +A struct representing the scalar stability function detailed in Edson et al (2013). +The formulation hinges on the definition of three different functions: +one for stable atmospheric conditions ``(ζ > 0)``, named ``ψₛ`` and two for unstable conditions, +named ``ψᵤ₁`` and ``ψᵤ₂``. +These stability functions are obtained by regression to experimental data. + +The stability parameter for stable atmospheric conditions is defined as +```math +dζ = min(ζmax, Aˢζ) +ψₛ = - (1 + Bˢ ζ) ^ Cₛ - Bˢ ( ζ - Dˢ ) * exp( - dζ) - Eˢ +``` + +While the stability parameter for unstable atmospheric conditions is calculated +as a function of the two individual stability functions as follows +```math +fᵤ₁ = √(1 - Aᵘζ) +ψᵤ₁ = Bᵘ ⋅ log((1 + fᵤ₁) / Bᵘ) + Cᵤ + +fᵤ₂ = ∛(1 - Dᵘζ) +ψᵤ₂ = Eᵘ / 2 ⋅ log((1 + fᵤ₂ + fᵤ₂²) / Eᵘ) - √Eᵘ atan( (1 + 2fᵤ₂) / √Eᵘ) + Fᵘ + +f = ζ² / (1 + ζ²) +ψᵤ = (1 - f) ψᵤ₁ + f ψᵤ₂ +``` + +The superscripts ``ˢ`` and ``ᵘ`` indicate if the parameter applies to the +stability function for _stable_ or _unstable_ atmospheric conditions, respectively. +""" +@kwdef struct ScalarStabilityFunction{FT} + ζmax :: FT = 50.0 + Aˢ :: FT = 0.35 + Bˢ :: FT = 0.7 + Cˢ :: FT = 0.75 + Dˢ :: FT = 5/0.35 + Aᵘ :: FT = 15.0 + Bᵘ :: FT = 4.0 + Cᵘ :: FT = 0.0 + Dᵘ :: FT = 10.15 + Eᵘ :: FT = 3.0 + Fᵘ :: FT = π / sqrt(3) end @inline function (ψ::MomentumStabilityFunction)(ζ) - # Parameters - p₁ = ψ.p₁ - p₂ = ψ.p₂ - p₃ = ψ.p₃ - p₄ = ψ.p₄ + ζmax = ψ.ζmax + Aˢ = ψ.Aˢ + Bˢ = ψ.Bˢ + Cˢ = ψ.Cˢ + Dˢ = ψ.Dˢ + Aᵘ = ψ.Aᵘ + Bᵘ = ψ.Bᵘ + Cᵘ = ψ.Cᵘ + Dᵘ = ψ.Dᵘ + Eᵘ = ψ.Eᵘ + Fᵘ = ψ.Fᵘ ζ⁻ = min(zero(ζ), ζ) ζ⁺ = max(zero(ζ), ζ) - dζ = min(50, p₁ * ζ⁺) - - # stability function for stable atmospheric conditions - ψ_stable = - p₂ * ζ⁺ - 3 / 4 * (ζ⁺ - 5 / p₁) * exp(-dζ) - 3 / 4 * 5 / p₁ - - fₘ = sqrt(sqrt(1 - p₃ * ζ⁻)) - ψ_unstable_1 = log((1 + fₘ)^2 * (1 + fₘ^2) / 8) - 2 * atan(fₘ) + π / 2; - - fₘ = cbrt(1 - p₄ * ζ⁻) - ψ_unstable_2 = 1.5 * log((1 + fₘ + fₘ^2) / 3) - sqrt(3) * atan((1 + 2fₘ) / sqrt(3))+ π / sqrt(3) - - f⁻ = ζ⁻^2 / (1 + ζ⁻^2) - - # stability function for unstable atmospheric conditions - ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 - - return ifelse(ζ < 0, ψ_unstable, ψ_stable) + dζ = min(ζmax, Aˢ * ζ⁺) + + # Stability parameter for _stable_ atmospheric conditions + ψₛ = - (Bˢ * ζ⁺ + Cˢ * (ζ⁺ - Dˢ)) * exp(- dζ) - Cˢ * Dˢ + + # Stability parameter for _unstable_ atmospheric conditions + fᵤ₁ = sqrt(sqrt(1 - Aᵘ * ζ⁻)) + ψᵤ₁ = Bᵘ * log((1 + fᵤ₁) / Bᵤ) + log((1 + fᵤ₁^2) / Bᵘ) - Bᵘ * atan(fᵤ₁) + Cᵘ + + fᵤ₂ = cqrt(1 - Dᵘ * ζ⁻) + ψᵤ₂ = Eᵘ / 2 * log((1 + fᵤ₂ + fᵤ₂^2) / Eᵘ) - sqrt(Eᵘ) * atan( (1 + 2fᵤ₂) / sqrt(Eᵘ)) + Fᵘ + + f = ζ⁻^2 / (1 + ζ⁻^2) + ψᵤ = (1 - f) * ψᵤ₁ + f * ψᵤ₂ + + return ifelse(ζ < 0, ψᵤ, ψₛ) end @inline function (ψ::ScalarStabilityFunction)(ζ) From d3138c307df73c480e3f2d5c218f0111f8efdb5f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 17 Jun 2024 12:03:21 -0400 Subject: [PATCH 528/716] exposing al parameters --- .../CrossRealmFluxes/stability_functions.jl | 92 ++++++++++--------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index 9463bc23..dfe51e29 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -17,11 +17,11 @@ end Statistics.norm(a::SimilarityScales) = norm(a.momentum) + norm(a.temperature) + norm(a.water_vapor) -function default_stability_functions(FT = Float64) +function edson_stability_functions(FT = Float64) # Edson et al. (2013) - ψu = MomentumStabilityFunction(FT) - ψc = ScalarStabilityFunction(FT) + ψu = MomentumStabilityFunction() + ψc = ScalarStabilityFunction() return SimilarityScales(ψu, ψc, ψc) end @@ -71,6 +71,39 @@ stability function for _stable_ or _unstable_ atmospheric conditions, respective Fᵘ :: FT = π / sqrt(3) end +@inline function (ψ::MomentumStabilityFunction)(ζ) + ζmax = ψ.ζmax + Aˢ = ψ.Aˢ + Bˢ = ψ.Bˢ + Cˢ = ψ.Cˢ + Dˢ = ψ.Dˢ + Aᵘ = ψ.Aᵘ + Bᵘ = ψ.Bᵘ + Cᵘ = ψ.Cᵘ + Dᵘ = ψ.Dᵘ + Eᵘ = ψ.Eᵘ + Fᵘ = ψ.Fᵘ + + ζ⁻ = min(zero(ζ), ζ) + ζ⁺ = max(zero(ζ), ζ) + dζ = min(ζmax, Aˢ * ζ⁺) + + # Stability parameter for _stable_ atmospheric conditions + ψₛ = - (Bˢ * ζ⁺ + Cˢ * (ζ⁺ - Dˢ)) * exp(- dζ) - Cˢ * Dˢ + + # Stability parameter for _unstable_ atmospheric conditions + fᵤ₁ = sqrt(sqrt(1 - Aᵘ * ζ⁻)) + ψᵤ₁ = Bᵘ * log((1 + fᵤ₁) / Bᵤ) + log((1 + fᵤ₁^2) / Bᵘ) - Bᵘ * atan(fᵤ₁) + Cᵘ + + fᵤ₂ = cqrt(1 - Dᵘ * ζ⁻) + ψᵤ₂ = Eᵘ / 2 * log((1 + fᵤ₂ + fᵤ₂^2) / Eᵘ) - sqrt(Eᵘ) * atan( (1 + 2fᵤ₂) / sqrt(Eᵘ)) + Fᵘ + + f = ζ⁻^2 / (1 + ζ⁻^2) + ψᵤ = (1 - f) * ψᵤ₁ + f * ψᵤ₂ + + return ifelse(ζ < 0, ψᵤ, ψₛ) +end + """ ScalarStabilityFunction{FT} @@ -105,23 +138,25 @@ stability function for _stable_ or _unstable_ atmospheric conditions, respective @kwdef struct ScalarStabilityFunction{FT} ζmax :: FT = 50.0 Aˢ :: FT = 0.35 - Bˢ :: FT = 0.7 - Cˢ :: FT = 0.75 - Dˢ :: FT = 5/0.35 + Bˢ :: FT = 2/3 + Cˢ :: FT = 3/2 + Dˢ :: FT = 14.28 + Eˢ :: FT = 8.525 Aᵘ :: FT = 15.0 - Bᵘ :: FT = 4.0 + Bᵘ :: FT = 2.0 Cᵘ :: FT = 0.0 - Dᵘ :: FT = 10.15 + Dᵘ :: FT = 34.15 Eᵘ :: FT = 3.0 Fᵘ :: FT = π / sqrt(3) end -@inline function (ψ::MomentumStabilityFunction)(ζ) +@inline function (ψ::ScalarStabilityFunction)(ζ) ζmax = ψ.ζmax Aˢ = ψ.Aˢ Bˢ = ψ.Bˢ Cˢ = ψ.Cˢ Dˢ = ψ.Dˢ + Eˢ = ψ.Eˢ Aᵘ = ψ.Aᵘ Bᵘ = ψ.Bᵘ Cᵘ = ψ.Cᵘ @@ -133,47 +168,18 @@ end ζ⁺ = max(zero(ζ), ζ) dζ = min(ζmax, Aˢ * ζ⁺) - # Stability parameter for _stable_ atmospheric conditions - ψₛ = - (Bˢ * ζ⁺ + Cˢ * (ζ⁺ - Dˢ)) * exp(- dζ) - Cˢ * Dˢ - + # stability function for stable atmospheric conditions + ψ_stable = - (1 + Bˢ * ζ⁺) ^ Cˢ - Bˢ * (ζ⁺ - Dˢ) * exp(-dζ) - Eˢ + # Stability parameter for _unstable_ atmospheric conditions - fᵤ₁ = sqrt(sqrt(1 - Aᵘ * ζ⁻)) - ψᵤ₁ = Bᵘ * log((1 + fᵤ₁) / Bᵤ) + log((1 + fᵤ₁^2) / Bᵘ) - Bᵘ * atan(fᵤ₁) + Cᵘ + fᵤ₁ = sqrt(1 - Aᵘ * ζ⁻) + ψᵤ₁ = Bᵘ * log((1 + fᵤ₁) / Bᵤ) + Cᵘ fᵤ₂ = cqrt(1 - Dᵘ * ζ⁻) ψᵤ₂ = Eᵘ / 2 * log((1 + fᵤ₂ + fᵤ₂^2) / Eᵘ) - sqrt(Eᵘ) * atan( (1 + 2fᵤ₂) / sqrt(Eᵘ)) + Fᵘ f = ζ⁻^2 / (1 + ζ⁻^2) ψᵤ = (1 - f) * ψᵤ₁ + f * ψᵤ₂ - - return ifelse(ζ < 0, ψᵤ, ψₛ) -end - -@inline function (ψ::ScalarStabilityFunction)(ζ) - # Parameters - p₁ = ψ.p₁ - p₂ = ψ.p₂ - p₃ = ψ.p₃ - p₄ = ψ.p₄ - p₅ = ψ.p₅ - - ζ⁻ = min(zero(ζ), ζ) - ζ⁺ = max(zero(ζ), ζ) - dζ = min(50, p₁ * ζ⁺) - - # stability function for stable atmospheric conditions - ψ_stable = - (4 * ζ⁺ / 3)^(3 / 2) - 2 / 3 * (ζ⁺ - p₂) * exp(-dζ) - p₃ - - fₕ = sqrt(1 - p₄ * ζ⁻) - ψ_unstable_1 = 2 * log((1 + fₕ) / 2) - - fₕ = cbrt(1 - p₅ * ζ⁻) - ψ_unstable_2 = 1.5 * log((1 + fₕ + fₕ^2) / 3) - sqrt(3) * atan((1 + 2fₕ) / sqrt(3))+ π / sqrt(3) - - f⁻ = ζ⁻^2 / (1 + ζ⁻^2) - - # stability function for unstable atmospheric conditions - ψ_unstable = (1 - f⁻) * ψ_unstable_1 + f⁻ * ψ_unstable_2 return ifelse(ζ < 0, ψ_unstable, ψ_stable) end From a187d81b62480a6649e09646b0441923835d4363 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 17 Jun 2024 12:04:32 -0400 Subject: [PATCH 529/716] better stability functions --- .../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 2adf4f38..654e6dd1 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -151,7 +151,7 @@ function SimilarityTheoryTurbulentFluxes(FT::DataType = Float64; von_karman_constant = convert(FT, 0.4), turbulent_prandtl_number = convert(FT, 1), gustiness_parameter = convert(FT, 6.5), - stability_functions = default_stability_functions(FT), + stability_functions = edson_stability_functions(FT), thermodynamics_parameters = PATP(FT), water_vapor_saturation = ClasiusClapyeronSaturation(), water_mole_fraction = convert(FT, 0.98), From 366d564f85fb40aa82cfafe85cb25886c4a2f486 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 17 Jun 2024 12:12:28 -0400 Subject: [PATCH 530/716] bugfixes --- src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl | 2 +- src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index c892e8cb..dc381c94 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -29,7 +29,7 @@ Keyword Arguments - `maximum_roughness_length::Float`: The maximum roughness length value. Defaults to `1.6e-4`. """ function ScalarRoughnessLength(FT=Float64; - air_kinematic_viscosity = temperature_dependent_viscosity, + air_kinematic_viscosity = TemperatureDependentAirViscosity(FT), reynolds_number_scaling_function = ReynoldsScalingFunction(FT), maximum_roughness_length = 1.6e-4) # Values from COARE3.6 diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index dfe51e29..7cea8460 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -169,7 +169,7 @@ end dζ = min(ζmax, Aˢ * ζ⁺) # stability function for stable atmospheric conditions - ψ_stable = - (1 + Bˢ * ζ⁺) ^ Cˢ - Bˢ * (ζ⁺ - Dˢ) * exp(-dζ) - Eˢ + ψₛ = - (1 + Bˢ * ζ⁺) ^ Cˢ - Bˢ * (ζ⁺ - Dˢ) * exp(-dζ) - Eˢ # Stability parameter for _unstable_ atmospheric conditions fᵤ₁ = sqrt(1 - Aᵘ * ζ⁻) @@ -181,5 +181,5 @@ end f = ζ⁻^2 / (1 + ζ⁻^2) ψᵤ = (1 - f) * ψᵤ₁ + f * ψᵤ₂ - return ifelse(ζ < 0, ψ_unstable, ψ_stable) + return ifelse(ζ < 0, ψᵤ, ψₛ) end From d2f5e82a9ebe0488ab7e4acf75e52cf9365f6211 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 17 Jun 2024 12:42:24 -0400 Subject: [PATCH 531/716] bugfixxed --- .../CrossRealmFluxes/roughness_lengths.jl | 7 ++++--- .../CrossRealmFluxes/stability_functions.jl | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index dc381c94..bf77e29e 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -112,8 +112,9 @@ end """ Calculate the air viscosity based on the temperature θ in Celsius. """ @inline function (ν::TemperatureDependentAirViscosity)(θ) - T = convert(FT, θ - celsius_to_kelvin) - return C₀ + C₁ * T + C₂ * T^2 + C₃ * T^3 + FT = eltype(ν.C₀) + T = convert(FT, θ - celsius_to_kelvin) + return ν.C₀ + ν.C₁ * T + ν.C₂ * T^2 + ν.C₃ * T^3 end # Fallbacks for constant roughness length! @@ -156,7 +157,7 @@ Edson et al. (2013), equation (28). ReynoldsScalingFunction(FT = Float64; A = 5.85e-5, b = 0.72) = ReynoldsScalingFunction(convert(FT, A), convert(FT, b)) -@inline (s::ReynoldsScalingFunction)(R★, args...) = ifelse(R★ == 0, FT(0), s.A / R★ ^ s.b) +@inline (s::ReynoldsScalingFunction)(R★, args...) = ifelse(R★ == 0, convert(eltype(R★), 0), s.A / R★ ^ s.b) # Edson 2013 formulation of scalar roughness length @inline function roughness_length(ℓ::ScalarRoughnessLength{FT}, ℓu, u★, 𝒬, ℂ) where FT diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index 7cea8460..5213e6e6 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -93,9 +93,9 @@ end # Stability parameter for _unstable_ atmospheric conditions fᵤ₁ = sqrt(sqrt(1 - Aᵘ * ζ⁻)) - ψᵤ₁ = Bᵘ * log((1 + fᵤ₁) / Bᵤ) + log((1 + fᵤ₁^2) / Bᵘ) - Bᵘ * atan(fᵤ₁) + Cᵘ + ψᵤ₁ = Bᵘ * log((1 + fᵤ₁) / Bᵘ) + log((1 + fᵤ₁^2) / Bᵘ) - Bᵘ * atan(fᵤ₁) + Cᵘ - fᵤ₂ = cqrt(1 - Dᵘ * ζ⁻) + fᵤ₂ = cbrt(1 - Dᵘ * ζ⁻) ψᵤ₂ = Eᵘ / 2 * log((1 + fᵤ₂ + fᵤ₂^2) / Eᵘ) - sqrt(Eᵘ) * atan( (1 + 2fᵤ₂) / sqrt(Eᵘ)) + Fᵘ f = ζ⁻^2 / (1 + ζ⁻^2) @@ -173,9 +173,9 @@ end # Stability parameter for _unstable_ atmospheric conditions fᵤ₁ = sqrt(1 - Aᵘ * ζ⁻) - ψᵤ₁ = Bᵘ * log((1 + fᵤ₁) / Bᵤ) + Cᵘ + ψᵤ₁ = Bᵘ * log((1 + fᵤ₁) / Bᵘ) + Cᵘ - fᵤ₂ = cqrt(1 - Dᵘ * ζ⁻) + fᵤ₂ = cbrt(1 - Dᵘ * ζ⁻) ψᵤ₂ = Eᵘ / 2 * log((1 + fᵤ₂ + fᵤ₂^2) / Eᵘ) - sqrt(Eᵘ) * atan( (1 + 2fᵤ₂) / sqrt(Eᵘ)) + Fᵘ f = ζ⁻^2 / (1 + ζ⁻^2) From 988f8f25a001bcd7b07b2e7581d76426bc36bd65 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:38:31 -0400 Subject: [PATCH 532/716] some refactoring + adding flux examples --- .gitignore | 14 +- docs/make_examples.jl | 3 +- examples/generate_surface_fluxes.jl | 134 ++++++++++++++++++ ...ulation.jl => single_column_simulation.jl} | 0 ...arison_to_coare.jl => comparison_coare.jl} | 2 +- .../ecco2_immersed_grid.jl | 22 --- src/DataWrangling/ECCO2.jl | 15 +- src/DataWrangling/JRA55.jl | 4 +- .../atmosphere_ocean_fluxes.jl | 6 +- .../CrossRealmFluxes/tabulated_albedo.jl | 4 +- src/OceanSeaIceModels/OceanSeaIceModels.jl | 2 +- .../PrescribedAtmospheres.jl | 16 +-- 12 files changed, 170 insertions(+), 52 deletions(-) create mode 100644 examples/generate_surface_fluxes.jl rename examples/{JRA55forced_single_column_simulation.jl => single_column_simulation.jl} (100%) rename prototype_omip_simulation/{comparison_to_coare.jl => comparison_coare.jl} (97%) delete mode 100644 prototype_omip_simulation/ecco2_immersed_grid.jl diff --git a/.gitignore b/.gitignore index 353c5651..675d9791 100644 --- a/.gitignore +++ b/.gitignore @@ -18,17 +18,19 @@ docs/build/ docs/site/ docs/src/literated/ +# Output files +*.nc +*.jld2 +*.mp4 +*.png +*.svg +*.gif + # 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 # committed for packages, but should be committed for applications that require a static # environment. # Manifest.toml - -*.nc -*.jld2 -*.mp4 *.DS_Store *.swp -*.svg -*.gif *.zip diff --git a/docs/make_examples.jl b/docs/make_examples.jl index 807cf045..642bd834 100644 --- a/docs/make_examples.jl +++ b/docs/make_examples.jl @@ -16,7 +16,8 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ "inspect_ecco2_data.jl", - "JRA55forced_single_column_simulation.jl", + "generate_surface_fluxes.jl" + "single_column_simulation.jl", # "near_global_omip_simulation.jl" ] diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl new file mode 100644 index 00000000..6aaf2a6c --- /dev/null +++ b/examples/generate_surface_fluxes.jl @@ -0,0 +1,134 @@ +# # Calculating surface fluxes with an ocean and an atmosphere +# +# ClimaOcean uses bulk formulae to estimate surface exchange of momentum, +# heat, and water vapor between the atmosphere and the ocean. +# +# This script shows an example of the turbulent surface flux calculations performed in ClimaOcean +# using ECCO2 data for the ocean and JRA55 data for the atmosphere +# +# For this example we need ClimaOcean with it's DataWrangling modules: ECCO2 and JRA55. +# We also need Oceananigans for the ImmersedBoundaryGrid and Field utilies and CairoMakie to plot + +using ClimaOcean +using ClimaOcean.ECCO2 +using ClimaOcean.JRA55 +using ClimaOcean.OceanSimulations +using Oceananigans +using CairoMakie + +# We start by defining a grid. The ECCO2 grid is a good starting point. +# The ECCO2 grid is not "immersed" by default, but we can use the ECCO mask +# to define the "bathymetry" of the ECCO fields. +# `ecco2_center_mask` produces a field with `true` values where data is missing (aka, in immersed cells). +# We can use this mask as an immersed boundary for our grid +# Let's create the grid and visualize the mask + +mask = ecco2_center_mask() +grid = mask.grid +grid = ImmersedBoundaryGrid(grid, GridFittedBoundary(mask)) + +fig = Figure() +ax = Axis(fig[1, 1]) +heatmap!(ax, interior(grid.immersed_boundary.mask, :, :, grid.Nz)) + +save("ecco_continents.png", fig) +nothing #hide + +# ![](ecco_continents.png) + +# We now construct our atmosphere and our ocean. +# The atmosphere is prescribed, downloaded from the JRA55 dataset. +# It contains +# - zonal wind `u` +# - meridional wind `v` +# - surface temperature `T` +# - surface relative humidity `q` +# - surface pressure `p` +# - downwelling shortwave radiation +# - downwelling longwave radiation +# +# We invoke the constructor with only the first two time indices, as they correspond to +# January 1st (at 00:00AM and 03:00AM). +# By passing the ECCO grid we automatically interpolate the atmospheric data on the grid. +# Note that this is recommended only for small simulations (in terms of grid size). +# By omitting the grid, the interpolation will be done on the fly. +# +# We construct the ocean simulation without bothering for advection, closures or coriolis given +# that we will not time-step the ocean but only use it to construct the fluxes + +atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory(), grid = grid.underlying_grid) + +ocean = ocean_simulation(grid; momentum_advection = nothing, + tracer_advection = nothing, + closure = nothing, + coriolis = nothing) + +# Now that we have an atmosphere, and a container for the ocean, we need to populate +# out ocean with initial conditions. To so this we can use the ECCO2 dataset by +# `set!`ting the model with the `ECCO2Metadata`. If no date is specified, +# the fields corresponding to the 1st of January 1992 (the first available date in +# ECCO2) is used. +# This command will download the fields on the local machine. + +set!(ocean.model; + T = ECCO2Metadata(:temperature), + S = ECCO2Metadata(:salinity), + u = ECCO2Metadata(:u_velocity), + v = ECCO2Metadata(:v_velocity)) + +# The final step is to construct a coupled model. +# The coupled model requires an ocean, which we have just constructed and initialized, +# an atmosphere, which we downloaded from the JRA55 dataset, the sea_ice simulation +# (in this case we neglect the sea ice by defining `sea_ice = nothing`), and a +# radiation model. +# The default radiation model is a model that assumes only two spectral bands: a shortwave and +# a longwave band. +# By constructing the coupled model, the `update_state!` function, which calculates the fluxes +# will be triggered. + +radiation = Radiation() +sea_ice = nothing +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +# Now that the surface fluxes are computed we can extract them and visualize them. +# The turbulent fluxes are stored in `coupled_model.fluxes.turbulent`. +# +# Qs = coupled_model.fluxes.turbulent.fields.sensible_heat : the sensible heat flux +# Ql = coupled_model.fluxes.turbulent.fields.latent_heat : the latent heat flux +# τx = coupled_model.fluxes.turbulent.fields.x_momentum : the zonal wind stress +# τy = coupled_model.fluxes.turbulent.fields.y_momentum : the meridional wind stress +# Mv = coupled_model.fluxes.turbulent.fields.water_vapor : evaporation +# +# They are 3D Fields with one point in the vertical. To extract the data we use the +# `interior` functionality from Oceananigans + +turbulent_fluxes = coupled_model.fluxes.turbulent.fields + +Qs = interior(turbulent_fluxes.sensible_heat, :, :, 1) +Ql = interior(turbulent_fluxes.latent_heat, :, :, 1) +τx = interior(turbulent_fluxes.x_momentum, :, :, 1) +τy = interior(turbulent_fluxes.y_momentum, :, :, 1) +Mv = interior(turbulent_fluxes.water_vapor, :, :, 1) +nothing + +fig = Figure() + +ax = Axis(fig[1, 1], title = "Sensible heat flux") +heatmap!(ax, Qs; colormap = :bwr) + +ax = Axis(fig[1, 2], title = "Latent heat flux") +heatmap!(ax, Ql; colormap = :bwr) + +ax = Axis(fig[2, 1], title = "Zonal wind stress") +heatmap!(ax, τx; colormap = :bwr) + +ax = Axis(fig[2, 2], title = "Meridional wind stress") +heatmap!(ax, τy; colormap = :bwr) + +ax = Axis(fig[3, 1], title = "Evaporation") +heatmap!(ax, Mv; colormap = :bwr) + +save("turbulent_fluxes.png", fig) +nothing #hide + +# ![](turbulent_fluxes.png) diff --git a/examples/JRA55forced_single_column_simulation.jl b/examples/single_column_simulation.jl similarity index 100% rename from examples/JRA55forced_single_column_simulation.jl rename to examples/single_column_simulation.jl diff --git a/prototype_omip_simulation/comparison_to_coare.jl b/prototype_omip_simulation/comparison_coare.jl similarity index 97% rename from prototype_omip_simulation/comparison_to_coare.jl rename to prototype_omip_simulation/comparison_coare.jl index 3ae8cbc6..9db067f1 100644 --- a/prototype_omip_simulation/comparison_to_coare.jl +++ b/prototype_omip_simulation/comparison_coare.jl @@ -18,7 +18,7 @@ v = ECCO2.ecco2_field(:v_velocity) include("ecco2_immersed_grid.jl") grid = ecco2_immersed_grid() -atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory(), grid = grid.underlying_grid) +atmosphere = JRA55_prescribed_atmosphere(1:2; grid = grid.underlying_grid) ocean = ocean_simulation(grid; momentum_advection = nothing, tracer_advection = nothing) diff --git a/prototype_omip_simulation/ecco2_immersed_grid.jl b/prototype_omip_simulation/ecco2_immersed_grid.jl deleted file mode 100644 index 64977ccc..00000000 --- a/prototype_omip_simulation/ecco2_immersed_grid.jl +++ /dev/null @@ -1,22 +0,0 @@ -using Oceananigans.Grids: architecture, location, node, with_halo - -function ecco2_immersed_grid() - mask = ecco2_center_mask() - grid = with_halo((3, 3, 3), mask.grid) - - Nx, Ny, Nz = size(grid) - bathymetry = zeros(Nx, Ny) - - for i in 1:Nx, j in 1:Ny - for k in Nz:-1:1 - if mask[i, j, k] - bathymetry[i, j] = 0.5 .* (grid.zᵃᵃᶜ[k] + grid.zᵃᵃᶠ[k+1]) - break; - elseif k == 1 - bathymetry[i, j] = - grid.Lz - 1 - end - end - end - - return ImmersedBoundaryGrid(grid, GridFittedBottom(bathymetry)) -end \ No newline at end of file diff --git a/src/DataWrangling/ECCO2.jl b/src/DataWrangling/ECCO2.jl index 5c828e2e..c1b88abe 100644 --- a/src/DataWrangling/ECCO2.jl +++ b/src/DataWrangling/ECCO2.jl @@ -165,7 +165,7 @@ function empty_ecco2_field(data::ECCO2Metadata; if variable_is_three_dimensional[variable_name] z = ECCO2_z # add vertical halo for 3D fields - halo = (horizontal_halo..., 1) + halo = (horizontal_halo..., 3) LZ = Center TZ = Bounded N = (ECCO2_Nx, ECCO2_Ny, ECCO2_Nz) @@ -251,13 +251,13 @@ end """ ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) -A boolean field where `false` represents a missing value in the ECCO2 :temperature dataset. +A boolean field where `true` represents a missing value in the ECCO2 :temperature dataset. """ function ecco2_center_mask(architecture = CPU(); minimum_value = Float32(-1e5)) Tᵢ = ecco2_field(:temperature; architecture) mask = CenterField(Tᵢ.grid, Bool) - # Set the mask with ones where T is defined + # Set the mask with ones where T is missing launch!(architecture, Tᵢ.grid, :xyz, _set_ecco2_mask!, mask, Tᵢ, minimum_value) return mask @@ -290,7 +290,7 @@ Keyword Arguments: """ function inpainted_ecco2_field(variable_name; architecture = CPU(), - filename = "./inpainted_ecco2_fields.nc", + filename = "./inpainted_ecco2_$(variable_name).nc", mask = ecco2_center_mask(architecture), kw...) @@ -330,7 +330,9 @@ function inpainted_ecco2_field(variable_name; return f end -function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename="./inpainted_ecco2_fields.nc", kw...) +function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; + filename="./inpainted_ecco2_$(ecco2_metadata.name).nc", kw...) + # Fields initialized from ECCO2 grid = field.grid arch = architecture(grid) @@ -359,7 +361,8 @@ function set!(field::DistributedField, ecco2_metadata::ECCO2Metadata; filename=" return field end -function set!(field::Field, ecco2_metadata::ECCO2Metadata; filename="./inpainted_ecco2_fields.nc", kw...) +function set!(field::Field, ecco2_metadata::ECCO2Metadata; + filename="./inpainted_ecco2_$(ecco2_metadata.name).nc", kw...) # Fields initialized from ECCO2 grid = field.grid diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 924539f1..9a7ba9af 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -13,7 +13,7 @@ using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBac using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, - TwoStreamDownwellingRadiation + TwoBandDownwellingRadiation using CUDA: @allowscalar @@ -642,7 +642,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); pressure = pa - downwelling_radiation = TwoStreamDownwellingRadiation(shortwave=Qs, longwave=Ql) + downwelling_radiation = TwoBandDownwellingRadiation(shortwave=Qs, longwave=Ql) FT = eltype(ua) measurement_height = convert(FT, measurement_height) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index 7827bc7f..d37d31eb 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -265,7 +265,7 @@ end end # Compute heat fluxes, bulk flux first - Qd = net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation_properties) + Qd = net_downwelling_radiation(i, j, grid, time, radiation_properties, Qs, Qℓ) Qu = net_upwelling_radiation(i, j, grid, time, radiation_properties, Tₒ) ΣQ = Qd + Qu + Qc + Qv @@ -316,9 +316,9 @@ end # Fallback for a `Nothing` radiation scheme @inline net_upwelling_radiation(i, j, grid, time, ::Nothing, Tₒ) = zero(grid) -@inline net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, ::Nothing) = zero(grid) +@inline net_downwelling_radiation(i, j, grid, time, ::Nothing, Qs, Qℓ) = zero(grid) -@inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation) +@inline function net_downwelling_radiation(i, j, grid, time, radiation, Qs, Qℓ) α = stateindex(radiation.reflection.ocean, i, j, 1, grid, time) ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index ce9cb2b9..62fbfc6b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -4,7 +4,7 @@ using Base using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, - TwoStreamDownwellingRadiation + TwoBandDownwellingRadiation # Bilinear interpolation of the albedo α in α_table based on a # transmissivity value (𝓉_values) and latitude (φ_values) @@ -93,7 +93,7 @@ Base.eltype(α::TabulatedAlbedo) = Base.eltype(α.S₀) @inline ϕ₃(ξ, η) = ξ * (1 - η) @inline ϕ₄(ξ, η) = ξ * η -@inline function net_downwelling_radiation(i, j, grid, time, Qs, Qℓ, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}) +@inline function net_downwelling_radiation(i, j, grid, time, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}, Qs, Qℓ) α = radiation.reflection.ocean FT = eltype(α) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index b7ff23ea..29ef4c38 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -44,7 +44,7 @@ include("PrescribedAtmospheres.jl") using .PrescribedAtmospheres: PrescribedAtmosphere, - TwoStreamDownwellingRadiation + TwoBandDownwellingRadiation include("CrossRealmFluxes/CrossRealmFluxes.jl") diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 6edffae3..b734cc03 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -354,23 +354,23 @@ function update_model_field_time_series!(atmos::PrescribedAtmosphere, time) return nothing end -struct TwoStreamDownwellingRadiation{SW, LW} +struct TwoBandDownwellingRadiation{SW, LW} shortwave :: SW longwave :: LW end """ - TwoStreamDownwellingRadiation(shortwave=nothing, longwave=nothing) + TwoBandDownwellingRadiation(shortwave=nothing, longwave=nothing) -Return a two-stream model for downwelling radiation that -passes through he atmosphere and arrives at the surface of ocean +Return a two-band model for downwelling radiation (split in a shortwave band +and a longwave band) that passes through the atmosphere and arrives at the surface of ocean or sea ice. """ -TwoStreamDownwellingRadiation(; shortwave=nothing, longwave=nothing) = - TwoStreamDownwellingRadiation(shortwave, longwave) +TwoBandDownwellingRadiation(; shortwave=nothing, longwave=nothing) = + TwoBandDownwellingRadiation(shortwave, longwave) -Adapt.adapt_structure(to, tsdr::TwoStreamDownwellingRadiation) = - TwoStreamDownwellingRadiation(adapt(to, tsdr.shortwave), +Adapt.adapt_structure(to, tsdr::TwoBandDownwellingRadiation) = + TwoBandDownwellingRadiation(adapt(to, tsdr.shortwave), adapt(to, tsdr.longwave)) end # module From 4a0164ffbc73f331fccd9c64354097dfcadb4c3c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:47:41 -0400 Subject: [PATCH 533/716] some grammar improvements --- examples/generate_surface_fluxes.jl | 60 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index 6aaf2a6c..b6246a67 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -1,13 +1,13 @@ -# # Calculating surface fluxes with an ocean and an atmosphere +# Calculating surface fluxes with an ocean and an atmosphere # -# ClimaOcean uses bulk formulae to estimate surface exchange of momentum, +# ClimaOcean uses bulk formulae to estimate the surface exchange of momentum, # heat, and water vapor between the atmosphere and the ocean. # -# This script shows an example of the turbulent surface flux calculations performed in ClimaOcean -# using ECCO2 data for the ocean and JRA55 data for the atmosphere +# This script demonstrates an example of the turbulent surface flux calculations performed in ClimaOcean +# using ECCO2 data for the ocean and JRA55 data for the atmosphere. # -# For this example we need ClimaOcean with it's DataWrangling modules: ECCO2 and JRA55. -# We also need Oceananigans for the ImmersedBoundaryGrid and Field utilies and CairoMakie to plot +# For this example, we need ClimaOcean with its DataWrangling modules: ECCO2 and JRA55. +# We also need Oceananigans for the ImmersedBoundaryGrid and Field utilities, and CairoMakie to plot. using ClimaOcean using ClimaOcean.ECCO2 @@ -19,9 +19,9 @@ using CairoMakie # We start by defining a grid. The ECCO2 grid is a good starting point. # The ECCO2 grid is not "immersed" by default, but we can use the ECCO mask # to define the "bathymetry" of the ECCO fields. -# `ecco2_center_mask` produces a field with `true` values where data is missing (aka, in immersed cells). -# We can use this mask as an immersed boundary for our grid -# Let's create the grid and visualize the mask +# `ecco2_center_mask` produces a field with `true` values where data is missing (i.e., in immersed cells). +# We can use this mask as an immersed boundary for our grid. +# Let's create the grid and visualize the mask. mask = ecco2_center_mask() grid = mask.grid @@ -36,9 +36,9 @@ nothing #hide # ![](ecco_continents.png) -# We now construct our atmosphere and our ocean. +# Next, we construct our atmosphere and ocean. # The atmosphere is prescribed, downloaded from the JRA55 dataset. -# It contains +# It contains: # - zonal wind `u` # - meridional wind `v` # - surface temperature `T` @@ -47,14 +47,14 @@ nothing #hide # - downwelling shortwave radiation # - downwelling longwave radiation # -# We invoke the constructor with only the first two time indices, as they correspond to -# January 1st (at 00:00AM and 03:00AM). -# By passing the ECCO grid we automatically interpolate the atmospheric data on the grid. +# We invoke the constructor with only the first two time indices, corresponding to +# January 1st (at 00:00 AM and 03:00 AM). +# By passing the ECCO grid, we automatically interpolate the atmospheric data onto the grid. # Note that this is recommended only for small simulations (in terms of grid size). # By omitting the grid, the interpolation will be done on the fly. # -# We construct the ocean simulation without bothering for advection, closures or coriolis given -# that we will not time-step the ocean but only use it to construct the fluxes +# We construct the ocean simulation without considering advection, closures, or Coriolis effects since +# we will not time-step the ocean but only use it to construct the fluxes. atmosphere = JRA55_prescribed_atmosphere(1:2; backend = InMemory(), grid = grid.underlying_grid) @@ -63,12 +63,12 @@ ocean = ocean_simulation(grid; momentum_advection = nothing, closure = nothing, coriolis = nothing) -# Now that we have an atmosphere, and a container for the ocean, we need to populate -# out ocean with initial conditions. To so this we can use the ECCO2 dataset by +# Now that we have an atmosphere and a container for the ocean, we need to populate +# our ocean with initial conditions. To do this, we can use the ECCO2 dataset by # `set!`ting the model with the `ECCO2Metadata`. If no date is specified, -# the fields corresponding to the 1st of January 1992 (the first available date in -# ECCO2) is used. -# This command will download the fields on the local machine. +# the fields corresponding to January 1st, 1992 (the first available date in +# ECCO2) are used. +# This command will download the fields to the local machine. set!(ocean.model; T = ECCO2Metadata(:temperature), @@ -78,19 +78,19 @@ set!(ocean.model; # The final step is to construct a coupled model. # The coupled model requires an ocean, which we have just constructed and initialized, -# an atmosphere, which we downloaded from the JRA55 dataset, the sea_ice simulation -# (in this case we neglect the sea ice by defining `sea_ice = nothing`), and a -# radiation model. -# The default radiation model is a model that assumes only two spectral bands: a shortwave and -# a longwave band. -# By constructing the coupled model, the `update_state!` function, which calculates the fluxes +# an atmosphere, which we have downloaded from the JRA55 dataset, a sea ice model +# (in this case we do not account for sea ice by defining `sea_ice = nothing`), +# and a radiation model. The default radiation model assumes two spectral bands: +# a shortwave band modeling visible and UV light, and a longwave band that accounts for +# near, mid and far infrared (mostly far infrared given the low emission temperature). +# By constructing the coupled model, the `update_state!` function, which calculates the fluxes, # will be triggered. radiation = Radiation() sea_ice = nothing coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -# Now that the surface fluxes are computed we can extract them and visualize them. +# Now that the surface fluxes are computed, we can extract and visualize them. # The turbulent fluxes are stored in `coupled_model.fluxes.turbulent`. # # Qs = coupled_model.fluxes.turbulent.fields.sensible_heat : the sensible heat flux @@ -99,8 +99,8 @@ coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) # τy = coupled_model.fluxes.turbulent.fields.y_momentum : the meridional wind stress # Mv = coupled_model.fluxes.turbulent.fields.water_vapor : evaporation # -# They are 3D Fields with one point in the vertical. To extract the data we use the -# `interior` functionality from Oceananigans +# They are 3D fields with one point in the vertical. To extract the data, we use the +# `interior` functionality from Oceananigans. turbulent_fluxes = coupled_model.fluxes.turbulent.fields From 0c3502398737a714739e861d4494c5f5de972a40 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 17 Jun 2024 22:28:22 -0400 Subject: [PATCH 534/716] bugfix in docs --- docs/make_examples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make_examples.jl b/docs/make_examples.jl index 642bd834..985a46e9 100644 --- a/docs/make_examples.jl +++ b/docs/make_examples.jl @@ -16,7 +16,7 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ "inspect_ecco2_data.jl", - "generate_surface_fluxes.jl" + "generate_surface_fluxes.jl", "single_column_simulation.jl", # "near_global_omip_simulation.jl" ] From 6a53bf542e90c05cb6a61f65b4f2d5583b48f3eb Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:04:01 -0400 Subject: [PATCH 535/716] remove useless file --- .../global_one_degree_restoring.jl | 221 ------------------ 1 file changed, 221 deletions(-) delete mode 100644 prototype_omip_simulation/global_one_degree_restoring.jl diff --git a/prototype_omip_simulation/global_one_degree_restoring.jl b/prototype_omip_simulation/global_one_degree_restoring.jl deleted file mode 100644 index 0f5c8e7c..00000000 --- a/prototype_omip_simulation/global_one_degree_restoring.jl +++ /dev/null @@ -1,221 +0,0 @@ -using Printf -using Oceananigans -using Oceananigans.Units -using ClimaOcean -using OrthogonalSphericalShellGrids -using Oceananigans -using Oceananigans: architecture -using ClimaOcean -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity -using Oceananigans.Coriolis: ActiveCellEnstrophyConserving -using Oceananigans.Units -using ClimaOcean.OceanSimulations -using ClimaOcean.OceanSeaIceModels -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes, simplified_bulk_coefficients -using ClimaOcean.VerticalGrids: exponential_z_faces -using ClimaOcean.JRA55 -using ClimaOcean.ECCO -using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere -using ClimaOcean.ECCO: ECCO_restoring_forcing, ECCO4Monthly, ECCO2Daily, ECCOMetadata -using ClimaOcean.Bathymetry - -using CFTime -using Dates - -include("tripolar_specific_methods.jl") -# include("xin_kai_vertical_diffusivity.jl") - -##### -##### Global Ocean at 1/6th of a degree -##### - -bathymetry_file = nothing # "bathymetry_tmp.jld2" - -# 60 vertical levels -z_faces = exponential_z_faces(Nz=20, depth=6000) - -Nx = 360 -Ny = 180 -Nz = length(z_faces) - 1 - -arch = CPU() - -grid = TripolarGrid(arch; - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = z_faces, - north_poles_latitude = 55, - first_pole_longitude = 75) - -bottom_height = retrieve_bathymetry(grid, bathymetry_file; - minimum_depth = 10, - dir = "./", - interpolation_passes = 20, - connected_regions_allowed = 0) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) - -##### -##### The Ocean component -##### - -const Lz = grid.Lz -const h = Nz / 4.5 - -@inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) -@inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) - -free_surface = SplitExplicitFreeSurface(grid; substeps = 75) -vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = νz) - -closure = (RiBasedVerticalDiffusivity(), vertical_diffusivity) # - -##### -##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic -##### - -# Build a mask that goes from 0 to 1 as a cubic function of φ between -# 70 degrees and 90 degrees and zero derivatives at 70 and 90. -x₁ = 70 -x₂ = 90 -y₁ = 0 -y₂ = 1 - -A⁺ = [ x₁^3 x₁^2 x₁ 1 - x₂^3 x₂^2 x₂ 1 - 3*x₁^2 2*x₁ 1 0 - 3*x₂^2 2*x₂ 1 0] - -b⁺ = [y₁, y₂, 0, 0] - -const c⁺ = A⁺ \ b⁺ - -x₁ = - 70 -x₂ = - 90 -y₁ = 0 -y₂ = 1 - -A⁻ = [ x₁^3 x₁^2 x₁ 1 - x₂^3 x₂^2 x₂ 1 - 3*x₁^2 2*x₁ 1 0 - 3*x₂^2 2*x₂ 1 0] - -b⁻ = [y₁, y₂, 0, 0] - -const c⁻ = A⁻ \ b⁻ - -@inline mask(λ, φ, z, t) = ifelse(φ >= 70, c⁺[1] * φ^3 + c⁺[2] * φ^2 + c⁺[3] * φ + c⁺[4], - ifelse(φ <= -70, c⁻[1] * φ^3 + c⁻[2] * φ^2 + c⁻[3] * φ + c⁻[4], 0)) - -dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) - -temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) -salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) - -FT = ECCO_restoring_forcing(temperature; grid, mask, architecture = arch, timescale = 20days) -FS = ECCO_restoring_forcing(salinity; grid, mask, architecture = arch, timescale = 20days) - -forcing = (; T = FT, S = FS) - -tracer_advection = WENO() -momentum_advection = VectorInvariant(vorticity_scheme = WENO(), - divergence_scheme = WENO()) - -ocean = ocean_simulation(grid; free_surface, - closure, - forcing, - momentum_advection, - tracer_advection) -model = ocean.model - -set!(model, - T = ECCOMetadata(:temperature, DateTimeProlepticGregorian(1992, 1, 2), ECCO2Daily()), - S = ECCOMetadata(:salinity, DateTimeProlepticGregorian(1992, 1, 2), ECCO2Daily())) - -##### -##### The atmosphere -##### - -backend = JRA55NetCDFBackend(4) -atmosphere = JRA55_prescribed_atmosphere(arch; backend) -radiation = Radiation(arch) - -sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() - -similarity_theory = SimilarityTheoryTurbulentFluxes(grid; bulk_coefficients = simplified_bulk_coefficients) - -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, similarity_theory, radiation) - -wall_time = [time_ns()] - -function progress(sim) - u, v, w = sim.model.velocities - T, S = sim.model.tracers - - Tmax = maximum(interior(T)) - Tmin = minimum(interior(T)) - umax = maximum(interior(u)), maximum(interior(v)), maximum(interior(w)) - step_time = 1e-9 * (time_ns() - wall_time[1]) - - @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", - prettytime(sim.model.clock.time), - sim.model.clock.iteration, - prettytime(sim.Δt), - umax..., Tmax, Tmin, prettytime(step_time)) - - wall_time[1] = time_ns() -end - -ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -fluxes = (u = model.velocities.u.boundary_conditions.top.condition, - v = model.velocities.v.boundary_conditions.top.condition, - T = model.tracers.T.boundary_conditions.top.condition, - S = model.tracers.S.boundary_conditions.top.condition) - -ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, - schedule = TimeInterval(0.5days), - overwrite_existing = true, - array_type = Array{Float32}, - filename = "surface_fluxes") - -ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(0.5days), - overwrite_existing = true, - array_type = Array{Float32}, - filename = "surface", - indices = (:, :, grid.Nz)) - -ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(10days), - overwrite_existing = true, - array_type = Array{Float32}, - filename = "snapshots") - -ocean.output_writers[:checkpoint] = Checkpointer(model, - schedule = TimeInterval(60days), - overwrite_existing = true, - prefix = "checkpoint") - -# Simulation warm up! -ocean.Δt = 10 -ocean.stop_iteration = Inf -wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 1200, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) - -stop_time = 30days - -coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) - -run!(coupled_simulation) - -wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 800, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) - -# Let's reset the maximum number of iterations -coupled_model.ocean.stop_time = 7200days -coupled_simulation.stop_time = 7200days -coupled_model.ocean.stop_iteration = Inf -coupled_simulation.stop_iteration = Inf - -run!(coupled_simulation) From 50fe31313198e5c8c62ea91d8fcb4c2c94eefa49 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:13:52 -0400 Subject: [PATCH 536/716] bugfix --- src/OceanSimulations/OceanSimulations.jl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index df2d87db..dc38fce4 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -82,11 +82,6 @@ function ocean_simulation(grid; Δt = 5minutes, T = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵀ)), S = FieldBoundaryConditions(top = FluxBoundaryCondition(Jˢ))) - Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) - Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) - - forcing = merge(forcing, (; u = Fu, v = Fv)) - if grid isa ImmersedBoundaryGrid Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) From 5862a0a092abed29ecbe4fac78044a26e2c3340b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:10:41 -0400 Subject: [PATCH 537/716] functions for time quantities --- .../CrossRealmFluxes/tabulated_albedo.jl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index 62fbfc6b..fc9c7a38 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -93,6 +93,12 @@ Base.eltype(α::TabulatedAlbedo) = Base.eltype(α.S₀) @inline ϕ₃(ξ, η) = ξ * (1 - η) @inline ϕ₄(ξ, η) = ξ * η +# Assumption: if the time is represented by a number it is defined in seconds. +# TODO: extend these functions for `DateTime` times when these are supported in +# Oceananigans. +@inline simulation_day(time::Time{<:Number}) = time.time ÷ 86400 +@inline seconds_in_day(time::Time{<:Number}, day) = time.time - day * 86400 + @inline function net_downwelling_radiation(i, j, grid, time, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}, Qs, Qℓ) α = radiation.reflection.ocean @@ -102,13 +108,12 @@ Base.eltype(α::TabulatedAlbedo) = Base.eltype(α.S₀) φ = deg2rad(φ) λ = deg2rad(λ) - time = time.time - day = time ÷ 86400 + day = simulation_day(time) day2rad = convert(FT, 2π / 86400) noon_in_sec = 86400 ÷ 2 - sec_of_day = time - day * 86400 + sec_of_day = seconds_in_day(time, day) # Hour angle h h = (sec_of_day - noon_in_sec) * day2rad + λ From ebf14fe0492718c88b3108d6da8521933fea6298 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:11:36 -0400 Subject: [PATCH 538/716] bottom drag coefficient --- src/OceanSimulations/OceanSimulations.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index dc38fce4..fdb90af6 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -61,7 +61,7 @@ function ocean_simulation(grid; Δt = 5minutes, reference_density = 1020, rotation_rate = Ω_Earth, gravitational_acceleration = g_Earth, - drag_coefficient = 0.003, + bottom_drag_coefficient = 0.003, forcing = NamedTuple(), coriolis = HydrostaticSphericalCoriolis(; rotation_rate), momentum_advection = default_momentum_advection(), @@ -74,8 +74,8 @@ function ocean_simulation(grid; Δt = 5minutes, top_ocean_heat_flux = Jᵀ = Field{Center, Center, Nothing}(grid) top_salt_flux = Jˢ = Field{Center, Center, Nothing}(grid) - u_bot_bc = FluxBoundaryCondition(u_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) - v_bot_bc = FluxBoundaryCondition(v_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) + u_bot_bc = FluxBoundaryCondition(u_quadratic_bottom_drag, discrete_form=true, parameters=bottom_drag_coefficient) + v_bot_bc = FluxBoundaryCondition(v_quadratic_bottom_drag, discrete_form=true, parameters=bottom_drag_coefficient) ocean_boundary_conditions = (u = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵘ), bottom = u_bot_bc), v = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵛ), bottom = v_bot_bc), @@ -83,8 +83,8 @@ function ocean_simulation(grid; Δt = 5minutes, S = FieldBoundaryConditions(top = FluxBoundaryCondition(Jˢ))) if grid isa ImmersedBoundaryGrid - Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) - Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) + Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=bottom_drag_coefficient) + Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=bottom_drag_coefficient) forcing = merge(forcing, (; u = Fu, v = Fv)) end From 103b504faa9f272321664baff25a3b66e28be024 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:12:34 -0400 Subject: [PATCH 539/716] back to reference height --- src/DataWrangling/JRA55.jl | 6 +++--- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 6 +++--- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 4b5e18f0..8fcd1f93 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -586,7 +586,7 @@ JRA55_prescribed_atmosphere(arch::Distributed, time_indices=Colon(); kw...) = function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, time_indexing = Cyclical(), - measurement_height = 10, # meters + reference_height = 10, # meters include_rivers_and_icebergs = true, # rivers and icebergs are not needed in single column simulations other_kw...) @@ -643,14 +643,14 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); downwelling_radiation = TwoBandDownwellingRadiation(shortwave=Qs, longwave=Ql) FT = eltype(ua) - measurement_height = convert(FT, measurement_height) + reference_height = convert(FT, reference_height) atmosphere = PrescribedAtmosphere(times, FT; velocities, freshwater_flux, tracers, downwelling_radiation, - measurement_height, + reference_height, pressure) return atmosphere diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index d37d31eb..340fab75 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -67,7 +67,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_times, atmosphere_backend, atmosphere_time_indexing, - atmosphere.measurement_height, # height at which the state is known + atmosphere.reference_height, # height at which the state is known atmosphere.boundary_layer_height, atmosphere.thermodynamics_parameters) @@ -120,7 +120,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing atmos_times, atmos_backend, atmos_time_indexing, - atmosphere_measurement_height, + atmosphere_reference_height, atmosphere_boundary_layer_height, atmos_thermodynamics_parameters) @@ -166,7 +166,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing ℂₐ = atmos_thermodynamics_parameters 𝒬ₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) - hₐ = atmosphere_measurement_height # elevation of atmos variables relative to surface + hₐ = atmosphere_reference_height # elevation of atmos variables relative to surface Uₐ = SVector(uₐ, vₐ) 𝒰ₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, 𝒬ₐ) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index b734cc03..89d025d6 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -296,7 +296,7 @@ struct PrescribedAtmosphere{G, U, P, C, F, R, TP, TI, FT} downwelling_radiation :: R thermodynamics_parameters :: TP times :: TI - measurement_height :: FT + reference_height :: FT boundary_layer_height :: FT end @@ -305,7 +305,7 @@ Base.show(io::IO, pa::PrescribedAtmosphere) = print(io, summary(pa)) """ PrescribedAtmosphere(times; - measurement_height, + reference_height, velocities = nothing, pressure = nothing, freshwater_flux = nothing, @@ -316,7 +316,7 @@ Return a representation of a prescribed time-evolving atmospheric state with data given at `times`. """ function PrescribedAtmosphere(times, FT=Float64; - measurement_height, + reference_height, velocities = nothing, boundary_layer_height = convert(FT, 600), pressure = nothing, @@ -339,7 +339,7 @@ function PrescribedAtmosphere(times, FT=Float64; downwelling_radiation, thermodynamics_parameters, times, - convert(FT, measurement_height), + convert(FT, reference_height), convert(FT, boundary_layer_height)) end From 7d4eb0ea9c06df1b9a1720e0766a39e0d51536b9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:32:51 -0400 Subject: [PATCH 540/716] some improvements --- .../CrossRealmFluxes/roughness_lengths.jl | 14 ++++----- .../CrossRealmFluxes/stability_functions.jl | 2 +- .../CrossRealmFluxes/tabulated_albedo.jl | 31 +++++++++++++------ 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl index bf77e29e..71974b3b 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/roughness_lengths.jl @@ -34,8 +34,8 @@ function ScalarRoughnessLength(FT=Float64; maximum_roughness_length = 1.6e-4) # Values from COARE3.6 return ScalarRoughnessLength(air_kinematic_viscosity, - reynolds_number_scaling_function, - convert(FT, maximum_roughness_length)) + reynolds_number_scaling_function, + convert(FT, maximum_roughness_length)) end """ @@ -104,10 +104,10 @@ function TemperatureDependentAirViscosity(FT = Float64; C₂ = C₀ * 8.301e-6, C₃ = - C₀ * 4.84e-9) - return TemperatureDependentAirViscosity(convert(FT, C₀), - convert(FT, C₁), - convert(FT, C₂), - convert(FT, C₃)) + return TemperatureDependentAirViscosity(convert(FT, C₀), + convert(FT, C₁), + convert(FT, C₂), + convert(FT, C₃)) end """ Calculate the air viscosity based on the temperature θ in Celsius. """ @@ -155,7 +155,7 @@ Edson et al. (2013), equation (28). ``` """ ReynoldsScalingFunction(FT = Float64; A = 5.85e-5, b = 0.72) = - ReynoldsScalingFunction(convert(FT, A), convert(FT, b)) + ReynoldsScalingFunction(convert(FT, A), convert(FT, b)) @inline (s::ReynoldsScalingFunction)(R★, args...) = ifelse(R★ == 0, convert(eltype(R★), 0), s.A / R★ ^ s.b) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl index 5213e6e6..f1f67cdf 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/stability_functions.jl @@ -70,7 +70,7 @@ stability function for _stable_ or _unstable_ atmospheric conditions, respective Eᵘ :: FT = 3.0 Fᵘ :: FT = π / sqrt(3) end - + @inline function (ψ::MomentumStabilityFunction)(ζ) ζmax = ψ.ζmax Aˢ = ψ.Aˢ diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index 62fbfc6b..bbf45a97 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -13,13 +13,17 @@ struct TabulatedAlbedo{M, P, T, FT} φ_values :: P 𝓉_values :: T S₀ :: FT # Solar constant W / m^2 + day_to_radians :: FT + noon_in_seconds :: Int end Adapt.adapt_structure(to, α :: TabulatedAlbedo) = TabulatedAlbedo(Adapt.adapt(to, α.α_table), Adapt.adapt(to, α.φ_values), Adapt.adapt(to, α.𝓉_values), - Adapt.adapt(to, α.S₀)) + Adapt.adapt(to, α.S₀), + Adapt.adapt(to, α.day_to_radians), + Adapt.adapt(to, α.noon_in_seconds)) # Tabulated from Payne (1972) https://doi.org/10.1175/1520-0469(1972)029<0959:AOTSS>2.0.CO;2 const α_payne = [ 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.061 0.06 @@ -76,14 +80,17 @@ function TabulatedAlbedo(arch = CPU(), FT = Float64; S₀ = convert(FT, 1365), α_table = α_payne, φ_values = (0:2:90) ./ 180 * π, - 𝓉_values = 0:0.05:1) + 𝓉_values = 0:0.05:1, + day_to_radians = convert(FT, 2π / 86400), + noon_in_seconds = 86400 ÷ 2 # assumes that midnight is at t = 0 seconds + ) # Make everything GPU - ready α_table = on_architecture(arch, convert.(FT, α_table)) φ_values = on_architecture(arch, convert.(FT, φ_values)) 𝓉_values = on_architecture(arch, convert.(FT, 𝓉_values)) - return TabulatedAlbedo(α_table, φ_values, 𝓉_values, convert(FT, S₀)) + return TabulatedAlbedo(α_table, φ_values, 𝓉_values, convert(FT, S₀), convert(FT, day_to_radians), noon_in_seconds) end Base.eltype(α::TabulatedAlbedo) = Base.eltype(α.S₀) @@ -93,6 +100,12 @@ Base.eltype(α::TabulatedAlbedo) = Base.eltype(α.S₀) @inline ϕ₃(ξ, η) = ξ * (1 - η) @inline ϕ₄(ξ, η) = ξ * η +# Assumption: if the time is represented by a number it is defined in seconds. +# TODO: extend these functions for `DateTime` times when these are supported in +# Oceananigans. +@inline simulation_day(time::Time{<:Number}) = time.time ÷ 86400 +@inline seconds_in_day(time::Time{<:Number}, day) = time.time - day * 86400 + @inline function net_downwelling_radiation(i, j, grid, time, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}, Qs, Qℓ) α = radiation.reflection.ocean @@ -102,14 +115,12 @@ Base.eltype(α::TabulatedAlbedo) = Base.eltype(α.S₀) φ = deg2rad(φ) λ = deg2rad(λ) - time = time.time - - day = time ÷ 86400 - day2rad = convert(FT, 2π / 86400) - - noon_in_sec = 86400 ÷ 2 - sec_of_day = time - day * 86400 + day = simulation_day(time) + day2rad = α.day2rad + noon_in_sec = α.noon_in_seconds + sec_of_day = seconds_in_day(time, day) + # Hour angle h h = (sec_of_day - noon_in_sec) * day2rad + λ From 8c165b943af2facc91953bfebe0532c03dc32484 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:33:33 -0400 Subject: [PATCH 541/716] bugfix --- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index d37d31eb..7db86c58 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -173,8 +173,8 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Build surface state with saturated specific humidity surface_type = AtmosphericThermodynamics.Liquid() qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, 𝒬ₐ, - 0.98, #similarity_theory.water_mole_fraction, - ClasiusClapyeronSaturation(), #similarity_theory.water_vapor_saturation, + similarity_theory.water_mole_fraction, + similarity_theory.water_vapor_saturation, surface_type) # Thermodynamic and dynamic surface state From 34b62658bbb77d1b5697d2a2f2581ef64364b1a6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:35:11 -0400 Subject: [PATCH 542/716] revert to chloride --- .../seawater_saturation_specific_humidity.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl b/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl index 069968da..f025e918 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/seawater_saturation_specific_humidity.jl @@ -15,7 +15,7 @@ function WaterMoleFraction(FT=Float64) # TODO: find reference for these salinity_constituents = ( - chlorine = SalinityConstituent{FT}(35.45, 0.56), + 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), @@ -33,14 +33,14 @@ end # Molecular weights μ_H₂O = wmf.water_molar_mass - # Salinity constituents: Cl, Na, SO₄, Mg - μ_Cl = wmf.salinity_constituents.chlorine.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.chlorine.mass_fraction + ϵ_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 From c5babb7ff6e19a3272f40c526a34fbefa7fb628c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:44:06 -0400 Subject: [PATCH 543/716] changed pipeline --- .buildkite/pipeline.yml | 2 +- .github/workflows/Documenter.yml | 2 +- docs/make.jl | 3 +++ docs/{make_examples.jl => make_without_examples.jl} | 3 --- 4 files changed, 5 insertions(+), 5 deletions(-) rename docs/{make_examples.jl => make_without_examples.jl} (95%) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 98557d20..bcdac10c 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -46,7 +46,7 @@ steps: JULIA_DEBUG: "Documenter" commands: - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" - - "julia --color=yes --project=docs/ docs/make_examples.jl" + - "julia --color=yes --project=docs/ docs/make.jl" agents: slurm_mem: 120G slurm_ntasks: 1 diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 1eb5ef50..3bfb9979 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -31,4 +31,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key JULIA_DEBUG: Documenter - run: julia --color=yes --project=docs/ docs/make.jl + run: julia --color=yes --project=docs/ docs/make_without_examples.jl diff --git a/docs/make.jl b/docs/make.jl index 9724e318..985a46e9 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -16,6 +16,9 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ "inspect_ecco2_data.jl", + "generate_surface_fluxes.jl", + "single_column_simulation.jl", + # "near_global_omip_simulation.jl" ] for file in to_be_literated diff --git a/docs/make_examples.jl b/docs/make_without_examples.jl similarity index 95% rename from docs/make_examples.jl rename to docs/make_without_examples.jl index 985a46e9..9724e318 100644 --- a/docs/make_examples.jl +++ b/docs/make_without_examples.jl @@ -16,9 +16,6 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ "inspect_ecco2_data.jl", - "generate_surface_fluxes.jl", - "single_column_simulation.jl", - # "near_global_omip_simulation.jl" ] for file in to_be_literated From 215b69227b4581cfed42e9b5a174002d3379536c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:44:46 -0400 Subject: [PATCH 544/716] use github documenter for the moment --- .buildkite/pipeline.yml | 20 ++++++++++---------- .github/workflows/Documenter.yml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index bcdac10c..ca0488fd 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -41,16 +41,16 @@ steps: commands: - "julia --project -e 'using Pkg; Pkg.test()'" - - label: "documentation" - env: - JULIA_DEBUG: "Documenter" - commands: - - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" - - "julia --color=yes --project=docs/ docs/make.jl" - agents: - slurm_mem: 120G - slurm_ntasks: 1 - slurm_gpus_per_task: 1 + # - label: "documentation" + # env: + # JULIA_DEBUG: "Documenter" + # commands: + # - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" + # - "julia --color=yes --project=docs/ docs/make.jl" + # agents: + # slurm_mem: 120G + # slurm_ntasks: 1 + # slurm_gpus_per_task: 1 - wait: ~ continue_on_failure: true diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 3bfb9979..1eb5ef50 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -31,4 +31,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key JULIA_DEBUG: Documenter - run: julia --color=yes --project=docs/ docs/make_without_examples.jl + run: julia --color=yes --project=docs/ docs/make.jl From a1ce58b88382ff78e85b8aa87408b5b4db6c3076 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:24:14 -0400 Subject: [PATCH 545/716] bugfix --- src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index bbf45a97..a414a5e0 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -1,5 +1,6 @@ using Oceananigans.Fields: interpolator using Oceananigans.Grids: on_architecture +using Oceananigans.Utils: Time using Base using ClimaOcean.OceanSeaIceModels: From 31add81cb6bd6a52a11de28642ab73f8e87ffbf6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:32:58 -0400 Subject: [PATCH 546/716] change measurement to reference --- src/DataWrangling/JRA55.jl | 6 +++--- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 6 +++--- src/OceanSeaIceModels/PrescribedAtmospheres.jl | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 9a7ba9af..9ae01cb7 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -588,7 +588,7 @@ JRA55_prescribed_atmosphere(arch::Distributed, time_indices=Colon(); kw...) = function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, time_indexing = Cyclical(), - measurement_height = 10, # meters + reference_height = 10, # meters include_rivers_and_icebergs = true, # rivers and icebergs are not needed in single column simulations other_kw...) @@ -645,14 +645,14 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); downwelling_radiation = TwoBandDownwellingRadiation(shortwave=Qs, longwave=Ql) FT = eltype(ua) - measurement_height = convert(FT, measurement_height) + reference_height = convert(FT, reference_height) atmosphere = PrescribedAtmosphere(times, FT; velocities, freshwater_flux, tracers, downwelling_radiation, - measurement_height, + reference_height, pressure) return atmosphere diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index 7db86c58..3a33de30 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -67,7 +67,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_times, atmosphere_backend, atmosphere_time_indexing, - atmosphere.measurement_height, # height at which the state is known + atmosphere.reference_height, # height at which the state is known atmosphere.boundary_layer_height, atmosphere.thermodynamics_parameters) @@ -120,7 +120,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing atmos_times, atmos_backend, atmos_time_indexing, - atmosphere_measurement_height, + atmosphere_reference_height, atmosphere_boundary_layer_height, atmos_thermodynamics_parameters) @@ -166,7 +166,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing ℂₐ = atmos_thermodynamics_parameters 𝒬ₐ = thermodynamic_atmospheric_state = AtmosphericThermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) - hₐ = atmosphere_measurement_height # elevation of atmos variables relative to surface + hₐ = atmosphere_reference_height # elevation of atmos variables relative to surface Uₐ = SVector(uₐ, vₐ) 𝒰ₐ = dynamic_atmos_state = SurfaceFluxes.StateValues(hₐ, Uₐ, 𝒬ₐ) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index b734cc03..89d025d6 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -296,7 +296,7 @@ struct PrescribedAtmosphere{G, U, P, C, F, R, TP, TI, FT} downwelling_radiation :: R thermodynamics_parameters :: TP times :: TI - measurement_height :: FT + reference_height :: FT boundary_layer_height :: FT end @@ -305,7 +305,7 @@ Base.show(io::IO, pa::PrescribedAtmosphere) = print(io, summary(pa)) """ PrescribedAtmosphere(times; - measurement_height, + reference_height, velocities = nothing, pressure = nothing, freshwater_flux = nothing, @@ -316,7 +316,7 @@ Return a representation of a prescribed time-evolving atmospheric state with data given at `times`. """ function PrescribedAtmosphere(times, FT=Float64; - measurement_height, + reference_height, velocities = nothing, boundary_layer_height = convert(FT, 600), pressure = nothing, @@ -339,7 +339,7 @@ function PrescribedAtmosphere(times, FT=Float64; downwelling_radiation, thermodynamics_parameters, times, - convert(FT, measurement_height), + convert(FT, reference_height), convert(FT, boundary_layer_height)) end From df0456eebc040ede2d955e592bf1d9d4aed260a6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:22:53 -0400 Subject: [PATCH 547/716] conversion depending on k --- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index 3a33de30..4a76e874 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -104,8 +104,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) end # Fallback -@inline convert_to_latlon_frame(i, j, grid, uₒ, vₒ) = uₒ, vₒ -@inline convert_to_native_frame(i, j, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_latlon_frame(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_native_frame(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ # Fallback! limit_fluxes_over_sea_ice!(args...) = nothing @@ -139,10 +139,12 @@ limit_fluxes_over_sea_ice!(args...) = nothing Sₒ = ocean_state.S[i, j, 1] end + kᴺ = size(grid, 3) # index of the top ocean cell + # Convert the native grid velocities to a zonal - meridional # frame of reference (assuming the frame of reference is # latitude - longitude here, we might want to change it) - uₒ, vₒ = convert_to_latlon_frame(i, j, grid, uₒ, vₒ) + uₒ, vₒ = convert_to_latlon_frame(i, j, kᴺ, grid, uₒ, vₒ) @inbounds begin # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) @@ -202,12 +204,10 @@ limit_fluxes_over_sea_ice!(args...) = nothing atmosphere_boundary_layer_height, ℂₐ, g, ϰ, maxiter) - kᴺ = size(grid, 3) # index of the top ocean cell - # Convert back from a zonal - meridional flux to the frame of # reference of the native ocean grid - τˣ, τʸ = convert_to_native_frame(i, j, grid, turbulent_fluxes.x_momentum, - turbulent_fluxes.y_momentum) + τˣ, τʸ = convert_to_native_frame(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, + turbulent_fluxes.y_momentum) @inbounds begin # +0: cooling, -0: heating From beaeacf6ec73edaca3d522f0f0ca2764b4b53d89 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:28:26 -0400 Subject: [PATCH 548/716] change to the --- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index 4a76e874..bb8758d7 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -104,8 +104,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) end # Fallback -@inline convert_to_latlon_frame(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ -@inline convert_to_native_frame(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_intrinsic_reference_frame(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ +@inline convert_to_extrinsic_reference_frame(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ # Fallback! limit_fluxes_over_sea_ice!(args...) = nothing @@ -144,7 +144,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert the native grid velocities to a zonal - meridional # frame of reference (assuming the frame of reference is # latitude - longitude here, we might want to change it) - uₒ, vₒ = convert_to_latlon_frame(i, j, kᴺ, grid, uₒ, vₒ) + uₒ, vₒ = convert_to_intrinsic_reference_frame(i, j, kᴺ, grid, uₒ, vₒ) @inbounds begin # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) @@ -206,8 +206,8 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert back from a zonal - meridional flux to the frame of # reference of the native ocean grid - τˣ, τʸ = convert_to_native_frame(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, - turbulent_fluxes.y_momentum) + τˣ, τʸ = convert_to_extrinsic_reference_frame(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, + turbulent_fluxes.y_momentum) @inbounds begin # +0: cooling, -0: heating From f235888da023c45c4697ebf93a034889d5ac3429 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:03:45 -0400 Subject: [PATCH 549/716] change name --- .../similarity_theory_turbulent_fluxes.jl | 6 +++--- test/test_surface_fluxes.jl | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 test/test_surface_fluxes.jl diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 654e6dd1..8d7ab438 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -298,14 +298,14 @@ end return b★ end -@inline characteristic_velocities(𝒰₁, 𝒰₀, ::RelativeVelocity) = @inbounds 𝒰₁.u[1] - 𝒰₀.u[1], 𝒰₁.u[2] - 𝒰₀.u[2] -@inline characteristic_velocities(𝒰₁, 𝒰₀, ::WindVelocity) = @inbounds 𝒰₁.u[1], 𝒰₁.u[2] +@inline velocity_differences(𝒰₁, 𝒰₀, ::RelativeVelocity) = @inbounds 𝒰₁.u[1] - 𝒰₀.u[1], 𝒰₁.u[2] - 𝒰₀.u[2] +@inline velocity_differences(𝒰₁, 𝒰₀, ::WindVelocity) = @inbounds 𝒰₁.u[1], 𝒰₁.u[2] @inline function state_differences(ℂ, 𝒰₁, 𝒰₀, g, bulk_velocity) z₁ = 𝒰₁.z z₀ = 𝒰₀.z Δh = z₁ - z₀ - Δu, Δv = characteristic_velocities(𝒰₁, 𝒰₀, bulk_velocity) + Δu, Δv = velocity_differences(𝒰₁, 𝒰₀, bulk_velocity) # Thermodynamic state 𝒬₁ = 𝒰₁.ts diff --git a/test/test_surface_fluxes.jl b/test/test_surface_fluxes.jl new file mode 100644 index 00000000..a126a25c --- /dev/null +++ b/test/test_surface_fluxes.jl @@ -0,0 +1,17 @@ +include("runtests_setup.jl") + +@testset "Test surface fluxes" begin + + @info " Testing zero fluxes..." + + + + @info " Testing neutral cases..." + + + @info " Testing convergence..." + + +end + + From f3487d95c911e6d8edae42a07c0cade9d88351bf Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:21:46 -0400 Subject: [PATCH 550/716] bugfix --- src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl index a414a5e0..59379da5 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/tabulated_albedo.jl @@ -117,8 +117,8 @@ Base.eltype(α::TabulatedAlbedo) = Base.eltype(α.S₀) φ = deg2rad(φ) λ = deg2rad(λ) - day = simulation_day(time) - day2rad = α.day2rad + day = simulation_day(time) + day2rad = α.day_to_radians noon_in_sec = α.noon_in_seconds sec_of_day = seconds_in_day(time, day) From c695266b1936fa52c2eb6309f3b808c93c1c8ef7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:33:54 -0400 Subject: [PATCH 551/716] namechange --- .../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 8d7ab438..d12a0abb 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -386,8 +386,8 @@ end q★ = χq * Δq # Buoyancy flux characteristic scale for gustiness (Edson 2013) - ε★ = - u★ * b★ - uᴳ = β * cbrt(ε★ * zᵢ) + Jᵇ = - u★ * b★ + uᴳ = β * cbrt(Jᵇ * zᵢ) # New velocity difference accounting for gustiness uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) From 84739269899c10879f4c3f69206645b118d131a9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:24:07 -0400 Subject: [PATCH 552/716] add surface flux tests --- .buildkite/pipeline.yml | 8 ++ src/ClimaOcean.jl | 2 + src/DataWrangling/JRA55.jl | 7 +- .../CrossRealmFluxes/CrossRealmFluxes.jl | 3 +- .../similarity_theory_turbulent_fluxes.jl | 1 + src/OceanSeaIceModels/OceanSeaIceModels.jl | 2 + src/OceanSimulations/OceanSimulations.jl | 15 +- test/runtests.jl | 4 + test/test_surface_fluxes.jl | 128 +++++++++++++++++- 9 files changed, 155 insertions(+), 15 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index ca0488fd..ef8db316 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -41,6 +41,14 @@ steps: commands: - "julia --project -e 'using Pkg; Pkg.test()'" + - label: "Run surface flux tests" + key: "tests_fluxes" + env: + CUDA_VISIBLE_DEVICES: "-1" + TEST_GROUP: "fluxes" + commands: + - "julia --project -e 'using Pkg; Pkg.test()'" + # - label: "documentation" # env: # JULIA_DEBUG: "Documenter" diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index e145b810..f4aa943b 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -4,6 +4,7 @@ export OceanSeaIceModel, MinimumTemperatureSeaIce, Radiation, + SimilarityTheoryTurbulentFluxes, JRA55_prescribed_atmosphere, JRA55NetCDFBackend, ecco2_field, @@ -13,6 +14,7 @@ export exponential_z_faces, PowerLawStretching, LinearStretching, jra55_field_time_series, + ocean_simulation, ecco2_field, ECCO2Metadata, initialize! diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 9ae01cb7..13856b3d 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -436,9 +436,12 @@ function JRA55_field_time_series(variable_name; Nrx, Nry, Nt = size(data) close(ds) + N = (Nrx, Nry) + H = min.(N, (3, 3)) + JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; - halo = (3, 3), - size = (Nrx, Nry), + halo = H, + size = N, longitude = λr, latitude = φr, topology = (TX, Bounded, Flat)) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 98746b64..22a7764e 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -4,7 +4,8 @@ using Oceananigans using Adapt export Radiation, - OceanSeaIceSurfaceFluxes + OceanSeaIceSurfaceFluxes, + SimilarityTheoryTurbulentFluxes using ..OceanSeaIceModels: SKOFTS, default_gravitational_acceleration diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index d12a0abb..3affc943 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -91,6 +91,7 @@ function Base.show(io::IO, fluxes::SimilarityTheoryTurbulentFluxes) "├── water_mole_fraction: ", summary(fluxes.water_mole_fraction), '\n', "├── water_vapor_saturation: ", summary(fluxes.water_vapor_saturation), '\n', "├── roughness_lengths: ", summary(fluxes.roughness_lengths), '\n', + "├── bulk_coefficients: ", summary(fluxes.bulk_coefficients), '\n', "└── thermodynamics_parameters: ", summary(fluxes.thermodynamics_parameters)) end diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 29ef4c38..4a9eaf7c 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -1,5 +1,7 @@ module OceanSeaIceModels +export OceanSeaIceModel, SimilarityTheoryTurbulentFluxes + using Oceananigans using SeawaterPolynomials diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index bee46c5e..ae9cbe68 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -1,6 +1,6 @@ module OceanSimulations -export load_balanced_regional_grid, ocean_simulation +export ocean_simulation using Oceananigans using Oceananigans.Units @@ -43,9 +43,6 @@ default_tracer_advection() = TracerAdvection(WENO(; order = 7), @inline u_quadratic_bottom_drag(i, j, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, 1] * spᶠᶜᶜ(i, j, 1, grid, Φ) @inline v_quadratic_bottom_drag(i, j, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, 1] * spᶜᶠᶜ(i, j, 1, grid, Φ) -@inline u_immersed_quadratic_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.u[i, j, k] * spᶠᶜᶜ(i, j, k, grid, Φ) -@inline v_immersed_quadratic_bottom_drag(i, j, k, grid, c, Φ, μ) = @inbounds - μ * Φ.v[i, j, k] * spᶜᶠᶜ(i, j, k, grid, Φ) - @inline is_immersed_drag_u(i, j, k, grid) = Int(immersed_peripheral_node(i, j, k-1, grid, Face(), Center(), Center()) & !inactive_node(i, j, k, grid, Face(), Center(), Center())) @inline is_immersed_drag_v(i, j, k, grid) = Int(immersed_peripheral_node(i, j, k-1, grid, Center(), Face(), Center()) & !inactive_node(i, j, k, grid, Center(), Face(), Center())) @@ -61,7 +58,7 @@ function ocean_simulation(grid; Δt = 5minutes, reference_density = 1020, rotation_rate = Ω_Earth, gravitational_acceleration = g_Earth, - drag_coefficient = 0.003, + bottom_drag_coefficient = 0.003, coriolis = HydrostaticSphericalCoriolis(; rotation_rate), momentum_advection = default_momentum_advection(), tracer_advection = default_tracer_advection(), @@ -73,8 +70,8 @@ function ocean_simulation(grid; Δt = 5minutes, top_ocean_heat_flux = Jᵀ = Field{Center, Center, Nothing}(grid) top_salt_flux = Jˢ = Field{Center, Center, Nothing}(grid) - u_bot_bc = FluxBoundaryCondition(u_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) - v_bot_bc = FluxBoundaryCondition(v_quadratic_bottom_drag, discrete_form=true, parameters=drag_coefficient) + u_bot_bc = FluxBoundaryCondition(u_quadratic_bottom_drag, discrete_form=true, parameters=bottom_drag_coefficient) + v_bot_bc = FluxBoundaryCondition(v_quadratic_bottom_drag, discrete_form=true, parameters=bottom_drag_coefficient) ocean_boundary_conditions = (u = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵘ), bottom = u_bot_bc), v = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵛ), bottom = v_bot_bc), @@ -84,8 +81,8 @@ function ocean_simulation(grid; Δt = 5minutes, if !(grid isa ImmersedBoundaryGrid) forcing = NamedTuple() else - Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) - Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=drag_coefficient) + Fu = Forcing(u_immersed_bottom_drag, discrete_form=true, parameters=bottom_drag_coefficient) + Fv = Forcing(v_immersed_bottom_drag, discrete_form=true, parameters=bottom_drag_coefficient) forcing = (; u = Fu, v = Fv) end diff --git a/test/runtests.jl b/test/runtests.jl index 36879aab..999c9374 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -17,3 +17,7 @@ end if test_group == :downloading || test_group == :all include("test_downloading.jl") end + +if test_group == :turbulent_fluxes || test_group == :all + include("test_surface_fluxes.jl") +end \ No newline at end of file diff --git a/test/test_surface_fluxes.jl b/test/test_surface_fluxes.jl index a126a25c..35c875d6 100644 --- a/test/test_surface_fluxes.jl +++ b/test/test_surface_fluxes.jl @@ -1,17 +1,139 @@ include("runtests_setup.jl") +using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: + celsius_to_kelvin, + convert_to_kelvin, + SimilarityScales, + seawater_saturation_specific_humidity + +using Thermodynamics +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: water_saturation_specific_humidity + +struct FixedSpecificHumidity{FT} + qₒ :: FT +end + +@inline water_saturation_specific_humidity(h::FixedSpecificHumidity, args...) = h.qₒ + @testset "Test surface fluxes" begin - @info " Testing zero fluxes..." + + grid = LatitudeLongitudeGrid(size = (1, 1, 1), + latitude = (-0.5, 0.5), + longitude = (-0.5, 0.5), + z = (-1, 0), + topology = (Periodic, Periodic, Bounded)) + + ocean = ocean_simulation(grid; momentum_advection = nothing, + tracer_advection = nothing, + closure = nothing, + bottom_drag_coefficient = 0.0) + + atmosphere = JRA55_prescribed_atmosphere(1:2; grid, backend = InMemory()) + + h = atmosphere.reference_height + pₐ = atmosphere.pressure[1][1, 1, 1] + Tₐ = atmosphere.tracers.T[1][1, 1, 1] + qₐ = atmosphere.tracers.q[1][1, 1, 1] + + uₐ = atmosphere.velocities.u[1][1, 1, 1] + vₐ = atmosphere.velocities.v[1][1, 1, 1] + ℂₐ = atmosphere.thermodynamics_parameters - @info " Testing neutral cases..." + # Force the saturation humidity of the ocean to be + # equal to the atmospheric saturation humidity + water_vapor_saturation = FixedSpecificHumidity(qₐ) + water_mole_fraction = 1 + # turbulent fluxes that force a specific humidity at the ocean's surface + similarity_theory = SimilarityTheoryTurbulentFluxes(grid; water_vapor_saturation, water_mole_fraction) + + # Thermodynamic parameters of the atmosphere + g = similarity_theory.gravitational_acceleration + 𝒬ₐ = Thermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₐ, qₐ) + cp = Thermodynamics.cp_m(ℂₐ, 𝒬ₐ) + ρₐ = Thermodynamics.air_density(ℂₐ, 𝒬ₐ) + ℰv = Thermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) + + # Ensure that the ΔT between atmosphere and ocean is zero + # Note that the Δθ accounts for the "lapse rate" at height h + Tₒ = Tₐ - celsius_to_kelvin + h / cp * g + + set!(ocean.model, u = uₐ, v = vₐ, T = Tₒ) + + # Compute the turbulent fluxes (neglecting radiation) + coupled_model = OceanSeaIceModel(ocean; atmosphere, similarity_theory) + turbulent_fluxes = coupled_model.fluxes.turbulent.fields + + # Make sure all fluxes are (almost) zero! + @test turbulent_fluxes.x_momentum[1, 1, 1] < eps(eltype(grid)) + @test turbulent_fluxes.y_momentum[1, 1, 1] < eps(eltype(grid)) + @test turbulent_fluxes.sensible_heat[1, 1, 1] < eps(eltype(grid)) + @test turbulent_fluxes.latent_heat[1, 1, 1] < eps(eltype(grid)) + @test turbulent_fluxes.water_vapor[1, 1, 1] < eps(eltype(grid)) + + @info " Testing neutral fluxes..." + + # Constructing very special fluxes that do not account for stability of + # the atmosphere, have zero gustiness and a constant roughness length of + # `1e-4` for momentum, water vapor and temperature + # For this case we can compute the fluxes by hand. + + @inline neutral_bulk_coefficients(ψ, h, ℓ, L) = log(h / ℓ) + + ℓ = 1e-4 + + roughness_lengths = SimilarityScales(ℓ, ℓ, ℓ) + similarity_theory = SimilarityTheoryTurbulentFluxes(grid; + roughness_lengths, + gustiness_parameter = 0, + bulk_coefficients = neutral_bulk_coefficients) + + # mid-latitude ocean conditions + set!(ocean.model, u = 0, v = 0, T = 15, S = 30) + + coupled_model = OceanSeaIceModel(ocean; atmosphere, similarity_theory) + + # Now manually compute the fluxes: + Tₒ = ocean.model.tracers.T[1, 1, 1] + celsius_to_kelvin + Sₒ = ocean.model.tracers.S[1, 1, 1] + qₒ = seawater_saturation_specific_humidity(ℂₐ, Tₒ, Sₒ, 𝒬ₐ, + similarity_theory.water_mole_fraction, + similarity_theory.water_vapor_saturation, + Thermodynamics.Liquid()) + + 𝒬ₒ = Thermodynamics.PhaseEquil_pTq(ℂₐ, pₐ, Tₒ, qₒ) + qₒ = Thermodynamics.vapor_specific_humidity(ℂₐ, 𝒬ₒ) + + # Differences! + Δu = uₐ + Δv = vₐ + ΔU = sqrt(Δu^2 + Δv^2) + Δθ = Tₐ - Tₒ + h / cp * g + Δq = qₐ - qₒ + ϰ = similarity_theory.von_karman_constant + + # Characteristic scales + u★ = ϰ / log(h / ℓ) * ΔU + θ★ = ϰ / log(h / ℓ) * Δθ + q★ = ϰ / log(h / ℓ) * Δq - @info " Testing convergence..." + τx = - ρₐ * u★^2 * Δu / sqrt(Δu^2 + Δv^2) + τy = - ρₐ * u★^2 * Δv / sqrt(Δu^2 + Δv^2) + Qs = - ρₐ * cp * u★ * θ★ + Mv = - ρₐ * u★ * q★ + Ql = - ρₐ * u★ * q★ * ℰv + turbulent_fluxes = coupled_model.fluxes.turbulent.fields + # Make sure fluxes agree with the hand-calculated ones + @test turbulent_fluxes.x_momentum[1, 1, 1] ≈ τx + @test turbulent_fluxes.y_momentum[1, 1, 1] ≈ τy + @test turbulent_fluxes.sensible_heat[1, 1, 1] ≈ Qs + @test turbulent_fluxes.latent_heat[1, 1, 1] ≈ Ql + @test turbulent_fluxes.water_vapor[1, 1, 1] ≈ Mv end From 2a6b1a4bb5c72cb49995550767b069cabf419eb1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:29:56 -0400 Subject: [PATCH 553/716] change name to "gusty" velocity difference --- .../similarity_theory_turbulent_fluxes.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 3affc943..d8a8a97d 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -231,14 +231,14 @@ end # The inital velocity scale assumes that # the gustiness velocity `uᴳ` is equal to 0.5 ms⁻¹. # That will be refined later on. - uτ = sqrt(Δu^2 + Δv^2 + convert(eltype(Δh), 0.25)) + ΔUᴳ = sqrt(Δu^2 + Δv^2 + convert(eltype(Δh), 0.25)) # Initialize the solver iteration = 0 while iterating(Σ★ - Σ₀, iteration, maxiter, similarity_theory) Σ₀ = Σ★ - Σ★, uτ, = refine_characteristic_scales(Σ★, uτ, + Σ★, ΔUᴳ, = refine_characteristic_scales(Σ★, uτ, similarity_theory, surface_state, differences, @@ -257,9 +257,9 @@ end q★ = q★ / similarity_theory.turbulent_prandtl_number # `u★² ≡ sqrt(τx² + τy²)` - # We remove the gustiness by dividing by `uτ` - τx = - u★^2 * Δu / uτ - τy = - u★^2 * Δv / uτ + # We remove the gustiness by dividing by `ΔUᴳ` + τx = - u★^2 * Δu / ΔUᴳ + τy = - u★^2 * Δv / ΔUᴳ 𝒬ₐ = atmos_state.ts ρₐ = AtmosphericThermodynamics.air_density(ℂₐ, 𝒬ₐ) @@ -391,7 +391,7 @@ end uᴳ = β * cbrt(Jᵇ * zᵢ) # New velocity difference accounting for gustiness - uτ = sqrt(Δu^2 + Δv^2 + uᴳ^2) + ΔUᴳ = sqrt(Δu^2 + Δv^2 + uᴳ^2) - return SimilarityScales(u★, θ★, q★), uτ + return SimilarityScales(u★, θ★, q★), ΔUᴳ end \ No newline at end of file From 36a3e179bb506dce8dea020715b9a91bd1e0d012 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:30:07 -0400 Subject: [PATCH 554/716] typo --- .../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 d8a8a97d..dcc5e212 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -238,7 +238,7 @@ end while iterating(Σ★ - Σ₀, iteration, maxiter, similarity_theory) Σ₀ = Σ★ - Σ★, ΔUᴳ, = refine_characteristic_scales(Σ★, uτ, + Σ★, ΔUᴳ = refine_characteristic_scales(Σ★, uτ, similarity_theory, surface_state, differences, From 29993f635ebef594b0f22ef68d13d0ecd91455b7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 21:03:34 -0400 Subject: [PATCH 555/716] bugfix --- .../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 dcc5e212..7cb5ebf3 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -238,7 +238,7 @@ end while iterating(Σ★ - Σ₀, iteration, maxiter, similarity_theory) Σ₀ = Σ★ - Σ★, ΔUᴳ = refine_characteristic_scales(Σ★, uτ, + Σ★, ΔUᴳ = refine_characteristic_scales(Σ★, ΔUᴳ, similarity_theory, surface_state, differences, From 24a551c7445bd59cff252be7af3882a6bb5d8006 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 22:23:12 -0400 Subject: [PATCH 556/716] correctly include runoff in forcing --- examples/single_column_simulation.jl | 6 +-- src/DataWrangling/JRA55.jl | 15 ++++--- .../atmosphere_ocean_fluxes.jl | 42 +++++++++++++++++-- .../PrescribedAtmospheres.jl | 5 ++- 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/examples/single_column_simulation.jl b/examples/single_column_simulation.jl index 48f06d3b..0d05c40c 100644 --- a/examples/single_column_simulation.jl +++ b/examples/single_column_simulation.jl @@ -64,9 +64,9 @@ model = ocean.model start_time = time_ns() # Initial conditions -set!(model, T = ECCO2Metadata(:temperature), - S = ECCO2Metadata(:salinity), - e = 1e-6) +set!(ocean.model, T = ECCO2Metadata(:temperature), + S = ECCO2Metadata(:salinity), + e = 1e-6) elapsed = time_ns() - start_time @info "Initial condition built. " * prettytime(elapsed * 1e-9) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 13856b3d..fe8dbfd5 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -621,16 +621,18 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) + freshwater_flux = (rain = Fra, + snow = Fsn) + + # Remember that rivers and icebergs are on a different grid and have + # a different frequency than the rest of the JRA55 data if include_rivers_and_icebergs Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) - freshwater_flux = (rain = Fra, - snow = Fsn, - rivers = Fri, - icebergs = Fic) + runoff_flux = (rivers = Fri, + icebergs = Fic) else - freshwater_flux = (rain = Fra, - snow = Fsn) + runoff_flux = nothing end times = ua.times @@ -653,6 +655,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); atmosphere = PrescribedAtmosphere(times, FT; velocities, freshwater_flux, + runoff_flux, tracers, downwelling_radiation, reference_height, diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index bb8758d7..7c1c9f44 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -46,6 +46,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_backend = u.backend atmosphere_time_indexing = u.time_indexing + runoff_args = get_runoff_args(atmosphere.runoff_flux) + Qs = atmosphere.downwelling_radiation.shortwave Ql = atmosphere.downwelling_radiation.longwave @@ -86,6 +88,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_times, atmosphere_backend, atmosphere_time_indexing, + runoff_args, radiation_properties, coupled_model.fluxes.ocean_reference_density, coupled_model.fluxes.ocean_heat_capacity, @@ -233,6 +236,7 @@ end atmos_times, atmos_backend, atmos_time_indexing, + runoff_args, radiation_properties, ocean_reference_density, ocean_heat_capacity, @@ -253,9 +257,10 @@ end 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. + # Accumulate mass fluxes of freshwater due to rain, snow, rivers, icebergs, and whatever else. + # Rememeber runoff fluxes could be `nothing` if rivers and icebergs are not included in the forcing Mp = interp_atmos_time_series(prescribed_freshwater_flux, X, time, atmos_args...) + Mr = get_runoff_flux(X, time, runoff_args) Qc = similarity_theory_fields.sensible_heat[i, j, 1] # sensible or "conductive" heat flux Qv = similarity_theory_fields.latent_heat[i, j, 1] # latent heat flux @@ -274,7 +279,7 @@ end # by dividing by the density of freshwater. # Also switch the sign, for some reason we are given freshwater flux as positive down. ρᶠ = freshwater_density - ΣF = - Mp / ρᶠ + ΣF = - (Mp + Mr) / ρᶠ # Add the contribution from the turbulent water vapor flux Fv = Mv / ρᶠ @@ -331,4 +336,33 @@ end # Note: positive implies _upward_ heat flux, and therefore cooling. return ϵ * σ * Tₒ^4 -end \ No newline at end of file +end + +# Retrieve the details of runoff fluxes (rivers and icebergs, if present in the simulation). +# Note that these forcing fields are different in terms of frequency (daily instead of three-hourly) +# and gridsize (1/4 degree instead of 1/2 degree) when compared to the other prescribed fluxes +# So they need to be interpolated using their own grid / times / backend / time_indexing +@inline get_runoff_args(::Nothing) = nothing + +@inline function get_runoff_args(runoff_flux) + + data = map(ϕ -> ϕ.data, runoff_flux) + grid = runoff_flux.rivers.grid + times = runoff_flux.rivers.times + backend = runoff_flux.rivers.backend + time_indexing = runoff_flux.rivers.time_indexing + + return (data, grid, times, backend, time_indexing) +end + +@inline get_runoff_flux(X, time, ::Nothing) = zero(eltype(X)) + +@inline function get_runoff_flux(X, time, runoff_args) + + @inbounds runoff_flux = runoff_args[1] # The data is located at position 1 of the tuple + @inbounds other_args = runoff_args[2:end] # Other args contain grid, times, backend and time_indexing + + Mr = interp_atmos_time_series(runoff_flux, X, time, other_args...) + + return Mr +end diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 89d025d6..3a9f3afb 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -287,12 +287,13 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters ##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic) ##### -struct PrescribedAtmosphere{G, U, P, C, F, R, TP, TI, FT} +struct PrescribedAtmosphere{G, U, P, C, F, I, R, TP, TI, FT} grid :: G velocities :: U pressure :: P tracers :: C freshwater_flux :: F + runoff_flux :: I downwelling_radiation :: R thermodynamics_parameters :: TP times :: TI @@ -321,6 +322,7 @@ function PrescribedAtmosphere(times, FT=Float64; boundary_layer_height = convert(FT, 600), pressure = nothing, freshwater_flux = nothing, + runoff_flux = nothing, downwelling_radiation = nothing, thermodynamics_parameters = PrescribedAtmosphereThermodynamicsParameters(FT), grid = nothing, @@ -336,6 +338,7 @@ function PrescribedAtmosphere(times, FT=Float64; pressure, tracers, freshwater_flux, + runoff_flux, downwelling_radiation, thermodynamics_parameters, times, From f1099d97982dc5ceed3b3208e630f13c2a30f644 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 22:24:48 -0400 Subject: [PATCH 557/716] bugfix --- examples/single_column_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/single_column_simulation.jl b/examples/single_column_simulation.jl index 0d05c40c..2e850592 100644 --- a/examples/single_column_simulation.jl +++ b/examples/single_column_simulation.jl @@ -55,10 +55,10 @@ tracer_advection = nothing coriolis = FPlane(latitude = φ★) ocean = ocean_simulation(grid; - drag_coefficient = 0, coriolis, tracer_advection, - momentum_advection) + momentum_advection, + bottom_drag_coefficient = 0) model = ocean.model start_time = time_ns() From a0682f0b29794fda6272346377c3bd7cd6c77111 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 18 Jun 2024 22:30:11 -0400 Subject: [PATCH 558/716] speed up generate fluxes --- examples/generate_surface_fluxes.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index b6246a67..859c4c6f 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -72,9 +72,7 @@ ocean = ocean_simulation(grid; momentum_advection = nothing, set!(ocean.model; T = ECCO2Metadata(:temperature), - S = ECCO2Metadata(:salinity), - u = ECCO2Metadata(:u_velocity), - v = ECCO2Metadata(:v_velocity)) + S = ECCO2Metadata(:salinity)) # The final step is to construct a coupled model. # The coupled model requires an ocean, which we have just constructed and initialized, From fc538636fee7ac616b2b2eb6a7b424d16ca08bdd Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 19 Jun 2024 09:19:21 -0400 Subject: [PATCH 559/716] error in project --- Project.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Project.toml b/Project.toml index 1a962446..1b0b49ed 100644 --- a/Project.toml +++ b/Project.toml @@ -35,7 +35,6 @@ CubicSplines = "0.2" DataDeps = "0.7" Downloads = "1.6" JLD2 = "0.4" -Oceananigans = "0.90, 0.91" KernelAbstractions = "0.9" NCDatasets = "0.12, 0.13, 0.14" Oceananigans = "0.90, 0.91" From 26b8dee438010a19819eeddb4ccb496ceb0ad0cb Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 19 Jun 2024 13:57:43 -0400 Subject: [PATCH 560/716] ok found the issue! --- src/Bathymetry.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index a2065e03..c1dc63f6 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -229,7 +229,7 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; h_data = Array(interior(target_h, :, :, 1)) if minimum_depth > 0 - shallow_ocean = h_data .> minimum_depth + shallow_ocean = h_data .> - minimum_depth h_data[shallow_ocean] .= 0 end From e1f386d9006728d17dc3d728478b7ec1f6838e41 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 19 Jun 2024 16:39:48 -0400 Subject: [PATCH 561/716] correct the functions --- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index 7c1c9f44..2acf84c1 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -147,7 +147,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert the native grid velocities to a zonal - meridional # frame of reference (assuming the frame of reference is # latitude - longitude here, we might want to change it) - uₒ, vₒ = convert_to_intrinsic_reference_frame(i, j, kᴺ, grid, uₒ, vₒ) + uₒ, vₒ = convert_to_extrinsic_reference_frame(i, j, kᴺ, grid, uₒ, vₒ) @inbounds begin # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) @@ -209,7 +209,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert back from a zonal - meridional flux to the frame of # reference of the native ocean grid - τˣ, τʸ = convert_to_extrinsic_reference_frame(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, + τˣ, τʸ = convert_to_intrinsic_reference_frame(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) @inbounds begin From 0309dddf59114180465bd976f0e5a1bdb556e883 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:23:55 -0400 Subject: [PATCH 562/716] change to z_data --- src/Bathymetry.jl | 70 +++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index c1dc63f6..152143bf 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -100,12 +100,12 @@ function regrid_bathymetry(target_grid; φ_data = dataset["lat"][:] λ_data = dataset["lon"][:] - h_data = convert.(FT, dataset["z"][:, :]) + z_data = convert.(FT, dataset["z"][:, :]) # Convert longitude to 0 - 360? λ_data .+= 180 - nhx = size(h_data, 1) - h_data = circshift(h_data, (nhx ÷ 2, 1)) + nhx = size(z_data, 1) + z_data = circshift(z_data, (nhx ÷ 2, 1)) close(dataset) @@ -144,14 +144,14 @@ function regrid_bathymetry(target_grid; # Restrict bathymetry _data to region of interest λ_data = λ_data[ii] φ_data = φ_data[jj] - h_data = h_data[ii, jj] + z_data = z_data[ii, jj] if !isnothing(height_above_water) # Overwrite the height of cells above water. # This has an impact on reconstruction. Greater height_above_water reduces total # wet area by biasing coastal regions to land during bathymetry regridding. - land = h_data .> 0 - h_data[land] .= height_above_water + land = z_data .> 0 + z_data[land] .= height_above_water end # Build the "native" grid of the bathymetry and make a bathymetry field. @@ -166,29 +166,29 @@ function regrid_bathymetry(target_grid; z = (0, 1), halo = (10, 10, 1)) - native_h = Field{Center, Center, Nothing}(native_grid) - set!(native_h, h_data) + native_z = Field{Center, Center, Nothing}(native_grid) + set!(native_z, z_data) - target_h = interpolate_bathymetry_in_passes(native_h, target_grid; + target_z = interpolate_bathymetry_in_passes(native_z, target_grid; passes = interpolation_passes, connected_regions_allowed, minimum_depth) - return target_h + return target_z end # Here we can either use `regrid!` (three dimensional version) or `interpolate` -function interpolate_bathymetry_in_passes(native_h, target_grid; +function interpolate_bathymetry_in_passes(native_z, target_grid; passes = 10, connected_regions_allowed = 3, minimum_depth = 0) Nλt, Nφt = Nt = size(target_grid) - Nλn, Nφn = Nn = size(native_h) + Nλn, Nφn = Nn = size(native_z) if any(Nt[1:2] .> Nn[1:2]) # We are refining the grid (at least in one direction), more passes will not help! - target_h = Field{Center, Center, Nothing}(target_grid) - interpolate!(target_h, native_h) - return target_h + target_z = Field{Center, Center, Nothing}(target_grid) + interpolate!(target_z, native_z) + return target_z end latitude = y_domain(target_grid) @@ -203,7 +203,7 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; Nλ = Int[Nλ..., Nλt] Nφ = Int[Nφ..., Nφt] - old_h = native_h + old_z = native_z TX, TY, _ = topology(target_grid) for pass = 1:passes - 1 @@ -217,27 +217,27 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; z = (0, 1), topology = (TX, TY, Bounded)) - new_h = Field{Center, Center, Nothing}(new_grid) + new_z = Field{Center, Center, Nothing}(new_grid) - interpolate!(new_h, old_h) - old_h = new_h + interpolate!(new_z, old_z) + old_z = new_z end - target_h = Field{Center, Center, Nothing}(target_grid) - interpolate!(target_h, old_h) + target_z = Field{Center, Center, Nothing}(target_grid) + interpolate!(target_z, old_z) - h_data = Array(interior(target_h, :, :, 1)) + z_data = Array(interior(target_z, :, :, 1)) if minimum_depth > 0 - shallow_ocean = h_data .> - minimum_depth - h_data[shallow_ocean] .= 0 + shallow_ocean = z_data .> - minimum_depth + z_data[shallow_ocean] .= 0 end - h_data = remove_lakes!(h_data; connected_regions_allowed) - set!(target_h, h_data) - fill_halo_regions!(target_h) + z_data = remove_lakes!(z_data; connected_regions_allowed) + set!(target_z, z_data) + fill_halo_regions!(target_z) - return target_h + return target_z end """ @@ -255,23 +255,23 @@ other possibly disconnected regions like the Mediterranean and the Bering sea). Default is `Inf`, which means all connected regions are kept. """ -function remove_lakes!(h_data::Field; kw...) - data = Array(interior(h_data, :, :, 1)) +function remove_lakes!(z_data::Field; kw...) + data = Array(interior(z_data, :, :, 1)) data = remove_lakes!(data; kw...) - set!(h_data, data) + set!(z_data, data) - return h_data + return z_data end -function remove_lakes!(h_data; connected_regions_allowed = Inf) +function remove_lakes!(z_data; connected_regions_allowed = Inf) if connected_regions_allowed == Inf @info "we are not removing lakes" - return h_data + return z_data end - bathtmp = deepcopy(h_data) + bathtmp = deepcopy(z_data) batneg = zeros(Bool, size(bathtmp)...) batneg[bathtmp.<0] .= true From 2378460dc9e7ebaa60940492d87a397ca089b68e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:30:22 -0400 Subject: [PATCH 563/716] improve example --- examples/generate_bathymetry.jl | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 61767fae..4db9c54b 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -17,7 +17,7 @@ h = regrid_bathymetry(grid, height_above_water=1, minimum_depth=5) λ, φ, z = nodes(h) -land = interior(h) .> 0 +land = interior(h) .>= 0 interior(h)[land] .= NaN fig = Figure(size=(2400, 1200)) @@ -46,20 +46,25 @@ grid = LatitudeLongitudeGrid(CPU(); z = (0, 1), halo = (4, 4, 4)) -h_smooth = regrid_bathymetry(grid, height_above_water=1, interpolation_passes = 40) -h_rough = regrid_bathymetry(grid, height_above_water=1, interpolation_passes = 1) +h_smooth = regrid_bathymetry(grid, height_above_water=1, minimum_depth=10, interpolation_passes = 40) +h_rough = regrid_bathymetry(grid, height_above_water=1, minimum_depth=10, interpolation_passes = 1) +h_nolakes = regrid_bathymetry(grid, height_above_water=1, minimum_depth=10, connected_regions_allowed = 0) λ, φ, z = nodes(h_smooth) -land_smooth = interior(h_smooth) .> 0 +land_smooth = interior(h_smooth) .>= 0 interior(h_smooth)[land_smooth] .= NaN -land_rough = interior(h_rough) .> 0 +land_rough = interior(h_rough) .>= 0 interior(h_rough)[land_rough] .= NaN +land_nolakes = interior(h_nolakes) .>= 0 +interior(h_nolakes)[land_nolakes] .= NaN fig = Figure(resolution=(2400, 800)) ax = Axis(fig[1, 1]) -heatmap!(ax, λ, φ, interior(h_smooth, :, :, 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)) +heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) +ax = Axis(fig[1, 3]) +heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) display(fig) From f9ba0ca4f3a9f6be20ac5cb529422603d36dcc80 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 17:45:34 -0400 Subject: [PATCH 564/716] closure --- prototype_omip_simulation/prototype_omip_simulation.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 222079c0..ed61fe51 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -27,7 +27,6 @@ using CFTime using Dates include("tripolar_specific_methods.jl") -include("xin_kai_vertical_diffusivity.jl") ##### ##### Global Ocean at 1/6th of a degree @@ -64,7 +63,6 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_ ##### free_surface = SplitExplicitFreeSurface(grid; substeps = 75) -closure = XinKaiVerticalDiffusivity() ##### ##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic @@ -113,7 +111,7 @@ using ClimaOcean.ECCO: on_native_grid forcing = (; T = FT, S = FS) -ocean = ocean_simulation(grid; free_surface, closure, forcing) +ocean = ocean_simulation(grid; free_surface, forcing) model = ocean.model initial_date = dates[1] From 05e4c0ed8ddde6d2c3108c3ee2320c32d143023a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:04:37 -0400 Subject: [PATCH 565/716] extrinsic-intrinsic --- .../tripolar_specific_methods.jl | 6 +++--- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 13 ++++--------- zstar_prototype_omip/tripolar_specific_methods.jl | 6 +++--- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index c248f35e..23c355fc 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -21,13 +21,13 @@ using Oceananigans.Grids: cpu_face_constructor_x, λnode, φnode using OrthogonalSphericalShellGrids: TRG -import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, convert_to_native_frame +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: extrinsic_vector, intrinsic_vector @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) # Here we assume that the tripolar grid is locally orthogonal -@inline function convert_to_latlong_frame(i, j, grid::TRG, uₒ, vₒ) +@inline function extrinsic_vector(i, j, grid::TRG, uₒ, vₒ) φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) @@ -49,7 +49,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, c return uₒ * d₁ - vₒ * d₂, uₒ * d₂ + vₒ * d₁ end -@inline function convert_to_native_frame(i, j, grid::TRG, uₒ, vₒ) +@inline function intrinsic_vector(i, j, grid::TRG, uₒ, vₒ) φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index 592d6afe..adfe7d94 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -107,8 +107,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) end # Fallback -@inline convert_to_intrinsic_reference_frame(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ -@inline convert_to_extrinsic_reference_frame(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ +@inline extrinsic_vector(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ +@inline intrinsic_vector(i, j, k, grid, uₒ, vₒ) = uₒ, vₒ # Fallback! limit_fluxes_over_sea_ice!(args...) = nothing @@ -147,7 +147,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert the native grid velocities to a zonal - meridional # frame of reference (assuming the frame of reference is # latitude - longitude here, we might want to change it) - uₒ, vₒ = convert_to_extrinsic_reference_frame(i, j, kᴺ, grid, uₒ, vₒ) + uₒ, vₒ = intrinsic_vector(i, j, kᴺ, grid, uₒ, vₒ) @inbounds begin # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) @@ -209,12 +209,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert back from a zonal - meridional flux to the frame of # reference of the native ocean grid -<<<<<<< HEAD - τˣ, τʸ = convert_to_intrinsic_reference_frame(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, -======= - τˣ, τʸ = convert_to_extrinsic_reference_frame(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, ->>>>>>> origin/main - turbulent_fluxes.y_momentum) + τˣ, τʸ = intrinsic_vector(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) @inbounds begin # +0: cooling, -0: heating diff --git a/zstar_prototype_omip/tripolar_specific_methods.jl b/zstar_prototype_omip/tripolar_specific_methods.jl index c248f35e..23c355fc 100644 --- a/zstar_prototype_omip/tripolar_specific_methods.jl +++ b/zstar_prototype_omip/tripolar_specific_methods.jl @@ -21,13 +21,13 @@ using Oceananigans.Grids: cpu_face_constructor_x, λnode, φnode using OrthogonalSphericalShellGrids: TRG -import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, convert_to_native_frame +import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: extrinsic_vector, intrinsic_vector @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) # Here we assume that the tripolar grid is locally orthogonal -@inline function convert_to_latlong_frame(i, j, grid::TRG, uₒ, vₒ) +@inline function extrinsic_vector(i, j, grid::TRG, uₒ, vₒ) φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) @@ -49,7 +49,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: convert_to_latlon_frame, c return uₒ * d₁ - vₒ * d₂, uₒ * d₂ + vₒ * d₁ end -@inline function convert_to_native_frame(i, j, grid::TRG, uₒ, vₒ) +@inline function intrinsic_vector(i, j, grid::TRG, uₒ, vₒ) φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) From 7fed375c3a1e4efb57f6a30ada7b2b5c61cf956f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:05:34 -0400 Subject: [PATCH 566/716] remove interpolate --- src/InitialConditions/InitialConditions.jl | 35 ---------------------- 1 file changed, 35 deletions(-) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 58c36a6b..f6731245 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -68,41 +68,6 @@ function three_dimensional_regrid!(a, b) return a end -import Oceananigans.Fields: interpolate! -using Oceananigans.Fields: _interpolate!, AbstractField -using Oceananigans.Architectures: child_architecture, architecture -using Oceananigans.Utils: launch! -using Oceananigans.BoundaryConditions - -""" - interpolate!(to_field::Field, from_field::AbstractField) - -Interpolate `from_field` `to_field` and then fill the halo regions of `to_field`. -""" -function interpolate!(to_field::Field, from_field::AbstractField) - to_grid = to_field.grid - from_grid = from_field.grid - - to_arch = child_architecture(architecture(to_field)) - from_arch = child_architecture(architecture(from_field)) - if !isnothing(from_arch) && to_arch != from_arch - msg = "Cannot interpolate! because from_field is on $from_arch while to_field is on $to_arch." - throw(ArgumentError(msg)) - end - - # Make locations - from_location = Tuple(L() for L in location(from_field)) - to_location = Tuple(L() for L in location(to_field)) - - launch!(to_arch, to_grid, size(to_field), - _interpolate!, to_field, to_grid, to_location, - from_field, from_grid, from_location) - - fill_halo_regions!(to_field) - - return nothing -end - include("diffuse_tracers.jl") end # module From 88bd8fd76f02cade8bc6c5f4edfd512d135dd77d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:07:44 -0400 Subject: [PATCH 567/716] z_data instead of h_data --- src/Bathymetry.jl | 70 +++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 9aa1af6d..6d6ce345 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -100,12 +100,12 @@ function regrid_bathymetry(target_grid; φ_data = dataset["lat"][:] λ_data = dataset["lon"][:] - h_data = convert.(FT, dataset["z"][:, :]) + z_data = convert.(FT, dataset["z"][:, :]) # Convert longitude to 0 - 360? λ_data .+= 180 - nhx = size(h_data, 1) - h_data = circshift(h_data, (nhx ÷ 2, 1)) + nhx = size(z_data, 1) + z_data = circshift(z_data, (nhx ÷ 2, 1)) close(dataset) @@ -144,14 +144,14 @@ function regrid_bathymetry(target_grid; # Restrict bathymetry _data to region of interest λ_data = λ_data[ii] φ_data = φ_data[jj] - h_data = h_data[ii, jj] + z_data = z_data[ii, jj] if !isnothing(height_above_water) # Overwrite the height of cells above water. # This has an impact on reconstruction. Greater height_above_water reduces total # wet area by biasing coastal regions to land during bathymetry regridding. - land = h_data .> 0 - h_data[land] .= height_above_water + land = z_data .> 0 + z_data[land] .= height_above_water end # Build the "native" grid of the bathymetry and make a bathymetry field. @@ -166,29 +166,29 @@ function regrid_bathymetry(target_grid; z = (0, 1), halo = (10, 10, 1)) - native_h = Field{Center, Center, Nothing}(native_grid) - set!(native_h, h_data) + native_z = Field{Center, Center, Nothing}(native_grid) + set!(native_z, z_data) - target_h = interpolate_bathymetry_in_passes(native_h, target_grid; + target_z = interpolate_bathymetry_in_passes(native_z, target_grid; passes = interpolation_passes, connected_regions_allowed, minimum_depth) - return target_h + return target_z end # Here we can either use `regrid!` (three dimensional version) or `interpolate` -function interpolate_bathymetry_in_passes(native_h, target_grid; +function interpolate_bathymetry_in_passes(native_z, target_grid; passes = 10, connected_regions_allowed = 3, minimum_depth = 0) Nλt, Nφt = Nt = size(target_grid) - Nλn, Nφn = Nn = size(native_h) + Nλn, Nφn = Nn = size(native_z) if any(Nt[1:2] .> Nn[1:2]) # We are refining the grid (at least in one direction), more passes will not help! - target_h = Field{Center, Center, Nothing}(target_grid) - interpolate!(target_h, native_h) - return target_h + target_z = Field{Center, Center, Nothing}(target_grid) + interpolate!(target_z, native_z) + return target_z end latitude = y_domain(target_grid) @@ -203,7 +203,7 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; Nλ = Int[Nλ..., Nλt] Nφ = Int[Nφ..., Nφt] - old_h = native_h + old_h = native_z TX, TY, _ = topology(target_grid) for pass = 1:passes - 1 @@ -223,55 +223,55 @@ function interpolate_bathymetry_in_passes(native_h, target_grid; old_h = new_h end - target_h = Field{Center, Center, Nothing}(target_grid) - interpolate!(target_h, old_h) + target_z = Field{Center, Center, Nothing}(target_grid) + interpolate!(target_z, old_h) - h_data = Array(interior(target_h, :, :, 1)) + z_data = Array(interior(target_z, :, :, 1)) if minimum_depth > 0 - shallow_ocean = h_data .> - minimum_depth - h_data[shallow_ocean] .= 0 + shallow_ocean = z_data .> - minimum_depth + z_data[shallow_ocean] .= 0 end - h_data = remove_lakes!(h_data; connected_regions_allowed) - set!(target_h, h_data) - fill_halo_regions!(target_h) + z_data = remove_lakes!(z_data; connected_regions_allowed) + set!(target_z, z_data) + fill_halo_regions!(target_z) - return target_h + return target_z end """ - remove_lakes!(h_data; connected_regions_allowed = Inf) + remove_lakes!(z_data; connected_regions_allowed = Inf) -Remove lakes from the bathymetry data stored in `h_data`, by identifying connected regions below sea level +Remove lakes from the bathymetry data stored in `z_data`, by identifying connected regions below sea level and removing all but the specified number of largest connected regions (which represent the ocean and other possibly disconnected regions like the Mediterranean and the Bering sea). # Arguments ============ -- `h_data`: A 2D array representing the bathymetry data. +- `z_data`: A 2D array representing the bathymetry data. - `connected_regions_allowed`: The maximum number of connected regions to keep. Default is `Inf`, which means all connected regions are kept. """ -function remove_lakes!(h_data::Field; kw...) - data = Array(interior(h_data, :, :, 1)) +function remove_lakes!(z_data::Field; kw...) + data = Array(interior(z_data, :, :, 1)) data = remove_lakes!(data; kw...) - set!(h_data, data) + set!(z_data, data) - return h_data + return z_data end -function remove_lakes!(h_data; connected_regions_allowed = Inf) +function remove_lakes!(z_data; connected_regions_allowed = Inf) if connected_regions_allowed == Inf @info "we are not removing lakes" - return h_data + return z_data end - bathtmp = deepcopy(h_data) + bathtmp = deepcopy(z_data) batneg = zeros(Bool, size(bathtmp)...) batneg[bathtmp.<0] .= true From 4f459e08fd66a76bfc1b33993af66587aa903741 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:27:43 -0400 Subject: [PATCH 568/716] add warning for longitude range --- src/Bathymetry.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 6d6ce345..290a2034 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -114,6 +114,11 @@ function regrid_bathymetry(target_grid; φ₁, φ₂ = y_domain(target_grid) λ₁, λ₂ = x_domain(target_grid) + if λ₁ < 0 || λ₂ > 360 + throw(ArgumentError("Cannot regrid bathymetry between λ₁ = $(λ₁) and λ₂ = $(λ₂). + Bathymetry data is defined on longitudes spanning λ = (0, 360).")) + end + # Calculate limiting indices on the bathymetry grid i₁ = searchsortedfirst(λ_data, λ₁) i₂ = searchsortedfirst(λ_data, λ₂) - 1 From 662552c58cffad089aed5b4c846936785874b209 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:46:40 -0400 Subject: [PATCH 569/716] small change --- src/Bathymetry.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 290a2034..2381dc4b 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -100,7 +100,7 @@ function regrid_bathymetry(target_grid; φ_data = dataset["lat"][:] λ_data = dataset["lon"][:] - z_data = convert.(FT, dataset["z"][:, :]) + z_data = convert(Array{FT}, dataset["z"][:, :]) # Convert longitude to 0 - 360? λ_data .+= 180 From baa271bde3a47f88eb2cbb14d934e520ac7caaff Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:51:49 -0400 Subject: [PATCH 570/716] change the CFL --- prototype_omip_simulation/prototype_omip_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 922177d6..066cd5f8 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -191,7 +191,7 @@ coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) run!(coupled_simulation) -wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 800, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 600, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations From 2b82a955825814057f6b42d06b2e881366212d59 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:52:46 -0400 Subject: [PATCH 571/716] comments --- prototype_omip_simulation/tripolar_specific_methods.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index 23c355fc..ee52cb3d 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -26,6 +26,9 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: extrinsic_vector, intrinsi @inline hack_cosd(φ) = cos(π * φ / 180) @inline hack_sind(φ) = sin(π * φ / 180) +# TODO: when https://github.com/CliMA/Oceananigans.jl/pull/3631 is merged, +# these functions will be transferred to OrthogonalSphericalShellGrids + # Here we assume that the tripolar grid is locally orthogonal @inline function extrinsic_vector(i, j, grid::TRG, uₒ, vₒ) From aa25de794a11ae5f45d87db75b8fd8c98ebfd955 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:54:23 -0400 Subject: [PATCH 572/716] remove zstar prototype --- zstar_prototype_omip/Project.toml | 13 - .../prototype_omip_simulation.jl | 174 ------------ zstar_prototype_omip/setup_satori.sh | 23 -- .../tripolar_specific_methods.jl | 72 ----- .../xin_kai_vertical_diffusivity.jl | 252 ------------------ 5 files changed, 534 deletions(-) delete mode 100644 zstar_prototype_omip/Project.toml delete mode 100644 zstar_prototype_omip/prototype_omip_simulation.jl delete mode 100755 zstar_prototype_omip/setup_satori.sh delete mode 100644 zstar_prototype_omip/tripolar_specific_methods.jl delete mode 100644 zstar_prototype_omip/xin_kai_vertical_diffusivity.jl diff --git a/zstar_prototype_omip/Project.toml b/zstar_prototype_omip/Project.toml deleted file mode 100644 index e8e6b41f..00000000 --- a/zstar_prototype_omip/Project.toml +++ /dev/null @@ -1,13 +0,0 @@ -[deps] -Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -CFTime = "179af706-886a-5703-950a-314cd64e0468" -ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -ClimaSeaIce = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" -JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -OrthogonalSphericalShellGrids = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" -SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40" -SurfaceFluxes = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -Thermodynamics = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" diff --git a/zstar_prototype_omip/prototype_omip_simulation.jl b/zstar_prototype_omip/prototype_omip_simulation.jl deleted file mode 100644 index 40fc5b14..00000000 --- a/zstar_prototype_omip/prototype_omip_simulation.jl +++ /dev/null @@ -1,174 +0,0 @@ -using Printf -using Oceananigans -using Oceananigans.Units -using ClimaOcean -using OrthogonalSphericalShellGrids -using Oceananigans -using Oceananigans: architecture -using ClimaOcean -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity -using Oceananigans.Coriolis: ActiveCellEnstrophyConserving -using Oceananigans.Units -using ClimaOcean.OceanSimulations -using ClimaOcean.OceanSeaIceModels -using ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: Radiation, SimilarityTheoryTurbulentFluxes -using ClimaOcean.VerticalGrids: exponential_z_faces -using ClimaOcean.JRA55 -using ClimaOcean.ECCO -using ClimaOcean.JRA55: JRA55NetCDFBackend, JRA55_prescribed_atmosphere -using ClimaOcean.ECCO: ECCO_restoring_forcing, ECCO4Monthly, ECCO2Daily, ECCOMetadata -using ClimaOcean.Bathymetry - -using CFTime -using Dates - -include("tripolar_specific_methods.jl") -include("xin_kai_vertical_diffusivity.jl") - -##### -##### Global Ocean at 1/6th of a degree -##### - -bathymetry_file = nothing # "bathymetry_tmp.jld2" - -# 60 vertical levels -z_faces = exponential_z_faces(Nz=60, depth=6500) - -Nx = 2160 -Ny = 1100 -Nz = length(z_faces) - 1 - -arch = GPU() #Distributed(GPU(), partition = Partition(2)) - -grid = TripolarGrid(arch; - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = z_faces, - north_poles_latitude = 45, - first_pole_longitude = 75) - -bottom_height = retrieve_bathymetry(grid, bathymetry_file; - minimum_depth = 10, - dir = "./", - interpolation_passes = 20, - connected_regions_allowed = 0) - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) - -using Oceananigans.Models.HydrostaticFreeSurfaceModels: generalized_spacing_grid, ZStar - -grid = generalized_spacing_grid(grid, ZStar()) - -##### -##### The Ocean component -##### - -const Lz = grid.Lz -const h = Nz / 4.5 - -@inline exponential_profile(z; Lz, h) = (exp(z / h) - exp( - Lz / h)) / (1 - exp( - Lz / h)) -@inline νz(x, y, z, t) = 1e-4 + (5e-3 - 1e-4) * exponential_profile(z; Lz, h) - -free_surface = SplitExplicitFreeSurface(grid; substeps = 75) -vertical_diffusivity = VerticalScalarDiffusivity(VerticallyImplicitTimeDiscretization(), κ = 5e-5, ν = νz) - -closure = XinKaiVerticalDiffusivity() # (RiBasedVerticalDiffusivity(), vertical_diffusivity) # - -##### -##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic -##### - -ocean = ocean_simulation(grid; free_surface, closure) -model = ocean.model - -initial_date = DateTimeProlepticGregorian(1993, 1, 1) - -set!(model, - T = ECCOMetadata(:temperature, initial_date, ECCO2Daily()), - S = ECCOMetadata(:salinity, initial_date, ECCO2Daily())) - -##### -##### The atmosphere -##### - -backend = JRA55NetCDFBackend(4) -atmosphere = JRA55_prescribed_atmosphere(arch; backend) -radiation = Radiation(arch) - -sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() - -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) - -wall_time = [time_ns()] - -function progress(sim) - u, v, w = sim.model.velocities - T, S = sim.model.tracers - - Tmax = maximum(interior(T)) - Tmin = minimum(interior(T)) - umax = maximum(interior(u)), maximum(interior(v)), maximum(interior(w)) - step_time = 1e-9 * (time_ns() - wall_time[1]) - - @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", - prettytime(sim.model.clock.time), - sim.model.clock.iteration, - prettytime(sim.Δt), - umax..., Tmax, Tmin, prettytime(step_time)) - - wall_time[1] = time_ns() -end - -ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -fluxes = (u = model.velocities.u.boundary_conditions.top.condition, - v = model.velocities.v.boundary_conditions.top.condition, - T = model.tracers.T.boundary_conditions.top.condition, - S = model.tracers.S.boundary_conditions.top.condition) - -ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, - schedule = TimeInterval(0.5days), - overwrite_existing = true, - array_type = Array{Float32}, - filename = "surface_fluxes_experimental") - -ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(0.5days), - overwrite_existing = true, - array_type = Array{Float32}, - filename = "surface_experimental", - indices = (:, :, grid.Nz)) - -ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), - schedule = TimeInterval(10days), - overwrite_existing = true, - array_type = Array{Float32}, - filename = "snapshots_experimental") - -ocean.output_writers[:checkpoint] = Checkpointer(model, - schedule = TimeInterval(60days), - overwrite_existing = true, - prefix = "checkpoint_experimental") - -# Simulation warm up! -ocean.Δt = 10 -ocean.stop_iteration = 1 -wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) - -stop_time = 10days - -coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) - -run!(coupled_simulation) - -wizard = TimeStepWizard(; cfl = 0.4, max_Δt = 800, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) - -# Let's reset the maximum number of iterations -coupled_model.ocean.stop_time = 7200days -coupled_simulation.stop_time = 7200days -coupled_model.ocean.stop_iteration = Inf -coupled_simulation.stop_iteration = Inf - -run!(coupled_simulation) diff --git a/zstar_prototype_omip/setup_satori.sh b/zstar_prototype_omip/setup_satori.sh deleted file mode 100755 index 760e4e72..00000000 --- a/zstar_prototype_omip/setup_satori.sh +++ /dev/null @@ -1,23 +0,0 @@ -# Upload modules -module purge all -module add spack -module add cuda/11.4 -module load openmpi/3.1.6-cuda-pmi-ucx-slurm-jhklron - -# MPI specific exports -export OMPI_MCA_pml=^ucx -export OMPI_MCA_osc=^ucx -export OMPI_MCA_btl_openib_allow_ib=true - -# Julia specific enviromental variables -export COMMON="/nobackup/users/ssilvest/perlmutter-test" -export JULIA="${COMMON}/julia/julia" - -export JULIA_CUDA_MEMORY_POOL=none -export JULIA_DEPOT_PATH="${COMMON}/depot" - -# Profile specific variable -export JULIA_NVTX_CALLBACKS=gc - -# Number of threads in SLURM mode -export JULIA_NUM_THREADS=${SLURM_CPUS_PER_TASK:=1} diff --git a/zstar_prototype_omip/tripolar_specific_methods.jl b/zstar_prototype_omip/tripolar_specific_methods.jl deleted file mode 100644 index 23c355fc..00000000 --- a/zstar_prototype_omip/tripolar_specific_methods.jl +++ /dev/null @@ -1,72 +0,0 @@ -using ClimaOcean -import ClimaOcean.InitialConditions: interpolate! - -using Oceananigans -using Oceananigans.Operators -using Oceananigans.BoundaryConditions -using Oceananigans.Fields: OneField -using Oceananigans.Grids: peripheral_node -using Oceananigans.Utils: launch! -using Oceananigans.Fields: instantiated_location, interior, CenterField -using Oceananigans.Architectures: architecture, device, GPU, child_architecture - -# Implementation of 3-dimensional regridding -# TODO: move all the following to Oceananigans! - -using Oceananigans.Fields: regrid!, interpolate! -using Oceananigans.Grids: cpu_face_constructor_x, - cpu_face_constructor_y, - cpu_face_constructor_z, - topology, - λnode, φnode - -using OrthogonalSphericalShellGrids: TRG -import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: extrinsic_vector, intrinsic_vector - -@inline hack_cosd(φ) = cos(π * φ / 180) -@inline hack_sind(φ) = sin(π * φ / 180) - -# Here we assume that the tripolar grid is locally orthogonal -@inline function extrinsic_vector(i, j, grid::TRG, uₒ, vₒ) - - φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) - φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) - Δyᶜᶜᵃ = Δyᶜᶜᶜ(i, j, 1, grid) - - ũ = deg2rad(φᶜᶠᵃ₊ - φᶜᶠᵃ₋) / Δyᶜᶜᵃ - - φᶠᶜᵃ₊ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) - φᶠᶜᵃ₋ = φnode(i, j, 1, grid, Face(), Center(), Center()) - Δxᶜᶜᵃ = Δxᶜᶜᶜ(i, j, 1, grid) - - ṽ = - deg2rad(φᶠᶜᵃ₊ - φᶠᶜᵃ₋) / Δxᶜᶜᵃ - - 𝒰 = sqrt(ũ^2 + ṽ^2) - - d₁ = ũ / 𝒰 - d₂ = ṽ / 𝒰 - - return uₒ * d₁ - vₒ * d₂, uₒ * d₂ + vₒ * d₁ -end - -@inline function intrinsic_vector(i, j, grid::TRG, uₒ, vₒ) - - φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) - φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) - Δyᶜᶜᵃ = Δyᶜᶜᶜ(i, j, 1, grid) - - ũ = deg2rad(φᶜᶠᵃ₊ - φᶜᶠᵃ₋) / Δyᶜᶜᵃ - - φᶠᶜᵃ₊ = φnode(i+1, j, 1, grid, Face(), Center(), Center()) - φᶠᶜᵃ₋ = φnode(i, j, 1, grid, Face(), Center(), Center()) - Δxᶜᶜᵃ = Δxᶜᶜᶜ(i, j, 1, grid) - - ṽ = - deg2rad(φᶠᶜᵃ₊ - φᶠᶜᵃ₋) / Δxᶜᶜᵃ - - 𝒰 = sqrt(ũ^2 + ṽ^2) - - d₁ = ũ / 𝒰 - d₂ = ṽ / 𝒰 - - return uₒ * d₁ + vₒ * d₂, uₒ * d₂ - vₒ * d₁ -end diff --git a/zstar_prototype_omip/xin_kai_vertical_diffusivity.jl b/zstar_prototype_omip/xin_kai_vertical_diffusivity.jl deleted file mode 100644 index fbc127a6..00000000 --- a/zstar_prototype_omip/xin_kai_vertical_diffusivity.jl +++ /dev/null @@ -1,252 +0,0 @@ -using Oceananigans -using Oceananigans.Architectures: architecture -using Oceananigans.BuoyancyModels: ∂z_b -using Oceananigans.Operators -using Oceananigans.Grids: inactive_node -using Oceananigans.Operators: ℑzᵃᵃᶜ, ℑxyᶠᶠᵃ, ℑxyᶜᶜᵃ - -using Adapt - -using KernelAbstractions: @index, @kernel -using KernelAbstractions.Extras.LoopInfo: @unroll - -using Oceananigans.TurbulenceClosures: - tapering_factorᶠᶜᶜ, - tapering_factorᶜᶠᶜ, - tapering_factorᶜᶜᶠ, - tapering_factor, - SmallSlopeIsopycnalTensor, - AbstractScalarDiffusivity, - ExplicitTimeDiscretization, - FluxTapering, - isopycnal_rotation_tensor_xz_ccf, - isopycnal_rotation_tensor_yz_ccf, - isopycnal_rotation_tensor_zz_ccf - -import Oceananigans.TurbulenceClosures: - compute_diffusivities!, - DiffusivityFields, - viscosity, - diffusivity, - getclosure, - top_buoyancy_flux, - diffusive_flux_x, - diffusive_flux_y, - diffusive_flux_z, - viscous_flux_ux, - viscous_flux_vx, - viscous_flux_uy, - viscous_flux_vy - -using Oceananigans.Utils: launch! -using Oceananigans.Coriolis: fᶠᶠᵃ -using Oceananigans.Operators -using Oceananigans.BuoyancyModels: ∂x_b, ∂y_b, ∂z_b - -using Oceananigans.TurbulenceClosures -using Oceananigans.TurbulenceClosures: HorizontalFormulation, VerticalFormulation, AbstractScalarDiffusivity -using Oceananigans.TurbulenceClosures: AbstractScalarBiharmonicDiffusivity -using Oceananigans.Operators -using Oceananigans.Operators: Δxᶜᶜᶜ, Δyᶜᶜᶜ, ℑxyᶜᶜᵃ, ζ₃ᶠᶠᶜ, div_xyᶜᶜᶜ -using Oceananigans.Operators: Δx, Δy -using Oceananigans.Operators: ℑxyz - -using Oceananigans.Operators: ℑxyzᶜᶜᶠ, ℑyzᵃᶜᶠ, ℑxzᶜᵃᶠ, Δxᶜᶜᶜ, Δyᶜᶜᶜ - -struct XinKaiVerticalDiffusivity{TD, FT} <: AbstractScalarDiffusivity{TD, VerticalFormulation, 2} - ν₀ :: FT - νˢʰ :: FT - νᶜⁿ :: FT - Cᵉⁿ :: FT - Prₜ :: FT - Riᶜ :: FT - δRi :: FT - Q₀ :: FT - δQ :: FT -end - -function XinKaiVerticalDiffusivity{TD}(ν₀ :: FT, - νˢʰ :: FT, - νᶜⁿ :: FT, - Cᵉⁿ :: FT, - Prₜ :: FT, - Riᶜ :: FT, - δRi :: FT, - Q₀ :: FT, - δQ :: FT) where {TD, FT} - - return XinKaiVerticalDiffusivity{TD, FT}(ν₀, νˢʰ, νᶜⁿ, Cᵉⁿ, Prₜ, Riᶜ, δRi, Q₀, δQ) -end - -function XinKaiVerticalDiffusivity(time_discretization = VerticallyImplicitTimeDiscretization(), - FT = Float64; - ν₀ = 1e-5, - νˢʰ = 0.0885, - νᶜⁿ = 4.3668, - Cᵉⁿ = 0.2071, - Prₜ = 1.207, - Riᶜ = - 0.21982, - δRi = 8.342e-4, - Q₀ = 0.08116, - δQ = 0.02622) - - TD = typeof(time_discretization) - - return XinKaiVerticalDiffusivity{TD}(convert(FT, ν₀), - convert(FT, νˢʰ), - convert(FT, Cᵉⁿ), - convert(FT, Cᵉⁿ), - convert(FT, Prₜ), - convert(FT, Riᶜ), - convert(FT, δRi), - convert(FT, Q₀), - convert(FT, δQ)) -end - -XinKaiVerticalDiffusivity(FT::DataType; kw...) = - XinKaiVerticalDiffusivity(VerticallyImplicitTimeDiscretization(), FT; kw...) - -Adapt.adapt_structure(to, clo::XinKaiVerticalDiffusivity{TD, FT}) where {TD, FT} = - XinKaiVerticalDiffusivity{TD, FT}(clo.ν₀, clo.νˢʰ, clo.νᶜⁿ, clo.Cᵉⁿ, clo.Prₜ, clo.Riᶜ, clo.δRi, clo.Q₀, clo.δQ) - -##### -##### Diffusivity field utilities -##### - -const RBVD = XinKaiVerticalDiffusivity -const RBVDArray = AbstractArray{<:RBVD} -const FlavorOfXKVD = Union{RBVD, RBVDArray} -const c = Center() -const f = Face() - -@inline viscosity_location(::FlavorOfXKVD) = (c, c, f) -@inline diffusivity_location(::FlavorOfXKVD) = (c, c, f) - -@inline viscosity(::FlavorOfXKVD, diffusivities) = diffusivities.κᵘ -@inline diffusivity(::FlavorOfXKVD, diffusivities, id) = diffusivities.κᶜ - -with_tracers(tracers, closure::FlavorOfXKVD) = closure - -# Note: computing diffusivities at cell centers for now. -function DiffusivityFields(grid, tracer_names, bcs, closure::FlavorOfXKVD) - κᶜ = Field((Center, Center, Face), grid) - κᵘ = Field((Center, Center, Face), grid) - Ri = Field((Center, Center, Face), grid) - return (; κᶜ, κᵘ, Ri) -end - -function compute_diffusivities!(diffusivities, closure::FlavorOfXKVD, model; parameters = :xyz) - arch = model.architecture - grid = model.grid - clock = model.clock - tracers = model.tracers - buoyancy = model.buoyancy - velocities = model.velocities - top_tracer_bcs = NamedTuple(c => tracers[c].boundary_conditions.top for c in propertynames(tracers)) - - launch!(arch, grid, parameters, - compute_ri_number!, - diffusivities, - grid, - closure, - velocities, - tracers, - buoyancy, - top_tracer_bcs, - clock) - - # Use `only_local_halos` to ensure that no communication occurs during - # this call to fill_halo_regions! - fill_halo_regions!(diffusivities.Ri; only_local_halos=true) - - launch!(arch, grid, parameters, - compute_xinkai_diffusivities!, - diffusivities, - grid, - closure, - velocities, - tracers, - buoyancy, - top_tracer_bcs, - clock) - - return nothing -end - -@inline ϕ²(i, j, k, grid, ϕ, args...) = ϕ(i, j, k, grid, args...)^2 - -@inline function shear_squaredᶜᶜᶠ(i, j, k, grid, velocities) - ∂z_u² = ℑxᶜᵃᵃ(i, j, k, grid, ϕ², ∂zᶠᶜᶠ, velocities.u) - ∂z_v² = ℑyᵃᶜᵃ(i, j, k, grid, ϕ², ∂zᶜᶠᶠ, velocities.v) - return ∂z_u² + ∂z_v² -end - -@inline function Riᶜᶜᶠ(i, j, k, grid, velocities, buoyancy, tracers) - S² = shear_squaredᶜᶜᶠ(i, j, k, grid, velocities) - N² = ∂z_b(i, j, k, grid, buoyancy, tracers) - Ri = N² / S² - - # Clip N² and avoid NaN - return ifelse(N² <= 0, zero(grid), Ri) -end - -const c = Center() -const f = Face() - -@kernel function compute_ri_number!(diffusivities, grid, closure::FlavorOfXKVD, - velocities, tracers, buoyancy, tracer_bcs, clock) - i, j, k = @index(Global, NTuple) - @inbounds diffusivities.Ri[i, j, k] = Riᶜᶜᶠ(i, j, k, grid, velocities, buoyancy, tracers) -end - -@kernel function compute_xinkai_diffusivities!(diffusivities, grid, closure::FlavorOfXKVD, - velocities, tracers, buoyancy, tracer_bcs, clock) - i, j, k = @index(Global, NTuple) - _compute_xinkai_diffusivities!(i, j, k, diffusivities, grid, closure, - velocities, tracers, buoyancy, tracer_bcs, clock) -end - - -@inline function _compute_xinkai_diffusivities!(i, j, k, diffusivities, grid, closure, - velocities, tracers, buoyancy, tracer_bcs, clock) - - # Ensure this works with "ensembles" of closures, in addition to ordinary single closures - closure_ij = getclosure(i, j, closure) - - ν₀ = closure_ij.ν₀ - νˢʰ = closure_ij.νˢʰ - νᶜⁿ = closure_ij.νᶜⁿ - Cᵉⁿ = closure_ij.Cᵉⁿ - Prₜ = closure_ij.Prₜ - Riᶜ = closure_ij.Riᶜ - δRi = closure_ij.δRi - Q₀ = closure_ij.Q₀ - δQ = closure_ij.δQ - - Qᵇ = top_buoyancy_flux(i, j, grid, buoyancy, tracer_bcs, clock, merge(velocities, tracers)) - - # Convection and entrainment - N² = ∂z_b(i, j, k, grid, buoyancy, tracers) - N²_above = ∂z_b(i, j, k+1, grid, buoyancy, tracers) - - # Conditions - convecting = N² < 0 # applies regardless of Qᵇ - entraining = (N² > 0) & (N²_above < 0) & (Qᵇ > 0) - - # (Potentially) apply a horizontal filter to the Richardson number - Ri = ℑxyᶜᶜᵃ(i, j, k, grid, ℑxyᶠᶠᵃ, diffusivities.Ri) - - # Convective adjustment diffusivity - ν_local = ifelse(convecting, - (νᶜⁿ - νˢʰ) / 2 * tanh(Ri / δRi) + νˢʰ, clamp(Riᶜ * Ri + νˢʰ + ν₀, ν₀, νˢʰ)) - - # Entrainment diffusivity - νᵉⁿ = ifelse(entraining, Cᵉⁿ * Qᵇ / N², zero(grid)) - x = Qᵇ / (N² + 1e-11) - ν_nonlocal = ifelse(entraining, Cᵉⁿ * νᶜⁿ * 0.5 * (tanh((x - Q₀) / δQ) + 1), 0) - - # Update by averaging in time - @inbounds diffusivities.κᵘ[i, j, k] = ν_local + ν_nonlocal - @inbounds diffusivities.κᶜ[i, j, k] = (ν_local + ν_nonlocal) / Prₜ - - return nothing -end From d4a2715310e074df37fc477ef5ad79bb670feed3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:58:44 -0400 Subject: [PATCH 573/716] bugfix --- test/test_jra55.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 01848b12..cea7dfef 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -37,10 +37,10 @@ include("runtests_setup.jl") rm(test_jld2_filename, force=true) @info "Testing loading preprocessed JRA55 data on $A..." - in_memory_jra55_fts = ClimaOcean.DataWrangling.reanalysis_field_time_series(test_name; - time_indices, - architecture = arch, - backend = InMemory(2)) + in_memory_jra55_fts = ClimaOcean.DataWrangling.JRA55_field_time_series(test_name; + time_indices, + architecture = arch, + backend = InMemory(2)) @test in_memory_jra55_fts isa FieldTimeSeries From 4268b5d5127c1d52ee276904277a6b56ed543cf1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 21 Jun 2024 08:49:48 -0400 Subject: [PATCH 574/716] small bugfix --- src/DataWrangling/ecco_restoring.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index addb945f..fd41560e 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -117,7 +117,8 @@ function ECCO_field_time_series(metadata::ECCOMetadata; grid = nothing) # ECCO data is too chunky to allow other backends - backend = ECCONetCDFBackend(time_indices_in_memory) + backend = ECCONetCDFBackend(time_indices_in_memory; + on_native_grid = insnothing(grid)) # Making sure all the required individual files are downloaded download_dataset!(metadata) From 3cfcf5aa48acb72965f90c28db7d6545452e8046 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 23 Jun 2024 10:42:56 -0400 Subject: [PATCH 575/716] bugfix --- .gitignore | 5 +++++ test/test_downloading.jl | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 675d9791..f46e36db 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,8 @@ docs/src/literated/ *.DS_Store *.swp *.zip + +# Report files from profiling +*.qdrep +*.nsys-rep +*.ncu-rep \ No newline at end of file diff --git a/test/test_downloading.jl b/test/test_downloading.jl index 388feb1c..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.reanalysis_field_time_series(name; time_indices=2:3) + fts = ClimaOcean.JRA55.JRA55_field_time_series(name; time_indices=2:3) end end From 122dfd3d37f8332744b57050ea25bb626a97bd52 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 23 Jun 2024 15:00:05 -0400 Subject: [PATCH 576/716] allow precompilation --- src/DataWrangling/ecco_restoring.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index fd41560e..1262752d 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -39,8 +39,6 @@ Base.summary(backend::ECCONetCDFBackend) = string("ECCONetCDFBackend(", backend. const ECCONetCDFFTS{N} = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:ECCONetCDFBackend{N}} where N new_backend(::ECCONetCDFBackend{N}, start, length) where N = ECCONetCDFBackend{N}(start, length) - -on_native_grid(::ECCONetCDFBackend{N}) where N = N on_native_grid(::ECCONetCDFBackend{N}) where N = N function set!(fts::ECCONetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts.name) From 559ab9899bf5cdf6b95d4ddd312ba23d2b24e5b4 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 23 Jun 2024 15:11:34 -0400 Subject: [PATCH 577/716] small bugfix --- src/DataWrangling/ecco_restoring.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 1262752d..d80fe78a 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -116,7 +116,7 @@ function ECCO_field_time_series(metadata::ECCOMetadata; # ECCO data is too chunky to allow other backends backend = ECCONetCDFBackend(time_indices_in_memory; - on_native_grid = insnothing(grid)) + on_native_grid = isnothing(grid)) # Making sure all the required individual files are downloaded download_dataset!(metadata) From 5582b14cab1b63d722c129deead29e55eea43673 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 23 Jun 2024 15:16:06 -0400 Subject: [PATCH 578/716] change default to ecco2daily --- docs/make.jl | 4 ++-- examples/{inspect_ecco4_data.jl => inspect_ecco_data.jl} | 0 src/DataWrangling/ecco_metadata.jl | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename examples/{inspect_ecco4_data.jl => inspect_ecco_data.jl} (100%) diff --git a/docs/make.jl b/docs/make.jl index 0bc69662..bc5ed089 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,7 +15,7 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - "inspect_ecco2_data.jl", + "inspect_ecco_data.jl", "generate_surface_fluxes.jl", "single_column_simulation.jl", # "near_global_omip_simulation.jl" @@ -47,7 +47,7 @@ pages = [ ], "Examples" => [ - "Inspect ECCO2 data" => "literated/inspect_ecco2_data.md", + "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", "Surface fluxes" => "literated/generate_surface_fluxes.md", "Single column simulation" => "literated/single_column_simulation.md", ] diff --git a/examples/inspect_ecco4_data.jl b/examples/inspect_ecco_data.jl similarity index 100% rename from examples/inspect_ecco4_data.jl rename to examples/inspect_ecco_data.jl diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index bbf33950..b742bede 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -24,10 +24,10 @@ Base.show(io::IO, metadata::ECCOMetadata) = "├── dates: $(metadata.dates)", '\n', "└── data version: $(metadata.version)") -# The default is the ECCO4Monthly dataset at 1992-01-01. +# The default is the ECCO2Daily dataset at 1993-01-01. function ECCOMetadata(name::Symbol; - date = DateTimeProlepticGregorian(1992, 1, 1), - version = ECCO4Monthly()) + date = DateTimeProlepticGregorian(1993, 1, 1), + version = ECCO2Daily()) return ECCOMetadata(name, date, version) end From 6559e967a51061766368df6b4754cd6cb4a01a45 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Sun, 23 Jun 2024 15:45:25 -0400 Subject: [PATCH 579/716] correct JRA55 --- test/test_jra55.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index cea7dfef..d083cdca 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -11,7 +11,7 @@ include("runtests_setup.jl") time_indices = 1:3 # This should download a file called "RYF.rsds.1990_1991.nc" - jra55_fts = ClimaOcean.DataWrangling.reanalysis_field_time_series(test_name; architecture=arch, time_indices) + jra55_fts = ClimaOcean.DataWrangling.JRA55_field_time_series(test_name; architecture=arch, time_indices) @test isfile(test_filename) @test jra55_fts isa FieldTimeSeries From 66afab0292bc683fcdc073ac962dc7b789944fd8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 24 Jun 2024 08:29:58 -0400 Subject: [PATCH 580/716] remove one division --- src/DataWrangling/ecco_restoring.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index d80fe78a..0d89a51b 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -174,14 +174,14 @@ A struct representing ECCO restoring. - `ecco_grid`: The native ECCO grid to interpolate from. - `mask`: A mask (could be a number, an array, a function or a field). - `varname`: The variable name of the variable that needs restoring. -- `λ`: The restoring timescale. +- `λ⁻¹`: The reciprocal of the restoring timescale. """ struct ECCORestoring{FTS, G, M, V, N} <: Function ecco_fts :: FTS ecco_grid :: G mask :: M varname :: V - λ :: N + λ⁻¹ :: N end Adapt.adapt_structure(to, p::ECCORestoring) = @@ -189,7 +189,7 @@ Adapt.adapt_structure(to, p::ECCORestoring) = Adapt.adapt(to, p.ecco_grid), Adapt.adapt(to, p.mask), Adapt.adapt(to, p.varname), - Adapt.adapt(to, p.λ)) + Adapt.adapt(to, p.λ⁻¹)) @inline function (p::ECCORestoring)(i, j, k, grid, clock, fields) @@ -208,7 +208,7 @@ Adapt.adapt_structure(to, p::ECCORestoring) = # Extracting the mask value at the current node mask = stateindex(p.mask, i, j, k, grid, clock.time, loc) - return 1 / p.λ * mask * (ecco_var - var) + return p.λ⁻¹ * mask * (ecco_var - var) end # Differentiating between restoring done with an ECCO FTS @@ -272,7 +272,7 @@ function ECCO_restoring_forcing(metadata::ECCOMetadata; variable_name = metadata.name field_name = oceananigans_fieldname[variable_name] - ecco_restoring = ECCORestoring(ecco_fts, ecco_grid, mask, field_name, timescale) + ecco_restoring = ECCORestoring(ecco_fts, ecco_grid, mask, field_name, 1 / timescale) # Defining the forcing that depends on the restoring field. restoring_forcing = Forcing(ecco_restoring; discrete_form = true) From 4bced960969f116d3b0405942a8897627d7dd4ab Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 24 Jun 2024 08:35:23 -0400 Subject: [PATCH 581/716] some optimizations --- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index adfe7d94..94e626df 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -277,11 +277,11 @@ end # Convert from a mass flux to a volume flux (aka velocity) # by dividing by the density of freshwater. # Also switch the sign, for some reason we are given freshwater flux as positive down. - ρᶠ = freshwater_density - ΣF = - (Mp + Mr) / ρᶠ + ρf⁻¹ = 1 / freshwater_density + ΣF = - (Mp + Mr) * ρf⁻¹ # Add the contribution from the turbulent water vapor flux - Fv = Mv / ρᶠ + Fv = Mv * ρf⁻¹ ΣF += Fv # Compute fluxes for u, v, T, S from momentum, heat, and freshwater fluxes @@ -290,12 +290,12 @@ end Jᵀ = net_tracer_fluxes.T Jˢ = net_tracer_fluxes.S - ρₒ = ocean_reference_density - cₒ = ocean_heat_capacity + ρₒ⁻¹ = ocean_reference_density + cₒ = ocean_heat_capacity - atmos_ocean_Jᵘ = τx / ρₒ - atmos_ocean_Jᵛ = τy / ρₒ - atmos_ocean_Jᵀ = ΣQ / (ρₒ * cₒ) + atmos_ocean_Jᵘ = τx * ρₒ⁻¹ + atmos_ocean_Jᵛ = τy * ρₒ⁻¹ + atmos_ocean_Jᵀ = ΣQ * ρₒ⁻¹ / cₒ atmos_ocean_Jˢ = - Sₒ * ΣF # Mask fluxes over land for convenience From e0157017438855c60e69ca97328d282795b345e8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:15:25 -0400 Subject: [PATCH 582/716] let's see if this speeds up the computation --- src/DataWrangling/ecco_restoring.jl | 34 ++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 0d89a51b..d5f86620 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -79,7 +79,7 @@ from the start time. An array of time differences in seconds. """ function ecco_times(metadata; start_time = first(metadata).dates) - times = [] + times = zeros(length(metadata)) for data in metadata date = data.dates time = date - start_time @@ -87,8 +87,6 @@ function ecco_times(metadata; start_time = first(metadata).dates) push!(times, time) end - times = tuple(times...) - return times end @@ -128,6 +126,7 @@ function ECCO_field_time_series(metadata::ECCOMetadata; ECCO_native_grid = ftmp.grid boundary_conditions = FieldBoundaryConditions(ECCO_native_grid, location) times = ecco_times(metadata) + times = on_architecture(architecture, times) fts_grid = isnothing(grid) ? ECCO_native_grid : grid @@ -229,8 +228,33 @@ end return interpolate(X, time, ecco_data, ecco_location, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) end -# Interpolating the ecco_variable in time -@inline get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) = @inbounds ecco_fts[i, j, k, time] +# Interpolating the ecco_variable in time: since the time interpolation is excessively slow, +# so slow as to be 3 times slower than the whole tendency computation, we assume that the data in +# memory contains the data we need for the interpolation (this is always the case). +# TODO: fix time interpolation in Oceananigans +@inline function get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) + + times = ecco_fts.times + + n₁ = searchsortedlast(times, time.time) + n₂ = n₁ + 1 + + t = time.time + @inbounds t₁ = times[n₁] + @inbounds t₂ = times[n₂] + + # Fractional index + ñ = (t₂ - t₁) / (n₂ - n₁) * (t - t₁) + + # Indices + n₁ = n₁ - n₀ + 1 + n₂ = n₂ - n₀ + 1 + + @inbounds e₁ = ecco_fts.data[i, j, k, n₁] + @inbounds e₂ = ecco_fts.data[i, j, k, n₂] + + return ñ * e₂ + (1 - ñ) * e₁ +end """ ECCO_restoring_forcing(metadata::ECCOMetadata; From bf340cc4e7396e083be5d14c8eb2e5e5b2c2a20f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:49:03 -0400 Subject: [PATCH 583/716] updating catke to new syntax --- src/OceanSimulations/OceanSimulations.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OceanSimulations/OceanSimulations.jl b/src/OceanSimulations/OceanSimulations.jl index c5e63065..031e3b4c 100644 --- a/src/OceanSimulations/OceanSimulations.jl +++ b/src/OceanSimulations/OceanSimulations.jl @@ -8,10 +8,10 @@ using Oceananigans.Advection: TracerAdvection using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.ImmersedBoundaries: immersed_peripheral_node, inactive_node -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, - MixingLength, - TurbulentKineticEnergyEquation + CATKEMixingLength, + CATKEEquation using SeawaterPolynomials.TEOS10: TEOS10EquationOfState @@ -23,8 +23,8 @@ using Oceananigans.Operators default_free_surface(grid) = SplitExplicitFreeSurface(grid; cfl=0.7) function default_ocean_closure() - mixing_length = MixingLength(Cᵇ=0.01) - turbulent_kinetic_energy_equation = TurbulentKineticEnergyEquation(Cᵂϵ=1.0) + mixing_length = CATKEMixingLength(Cᵇ=0.01) + turbulent_kinetic_energy_equation = CATKEEquation(Cᵂϵ=1.0) return CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) end From 00a9eccce92e5de261c4a8f6bf46365a94aaea59 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:50:19 -0400 Subject: [PATCH 584/716] also new manifest --- Manifest.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 7460e85c..7559f5f6 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "d2ec6eab3a1bcf9a6e07ba530f8c2ea9266b216c" +project_hash = "5efeaf9bde5c5f86ae2cbcee35982d263f37f70d" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -188,8 +188,8 @@ weakdeps = ["SparseArrays"] [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "0ac8d2566e8f4887896c8a03ee87050fcbbf6599" -repo-rev = "ss/new-oceananigans" +git-tree-sha1 = "be4f97676cd18dc1566637e03c189b04c3fb4c59" +repo-rev = "main" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.1.0" @@ -1001,9 +1001,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 = "994ae77f4f232940822770d8ce7c2f84e373156e" +git-tree-sha1 = "745b1c19221e09886cae331450a2a4ea73708a38" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.91.1" +version = "0.91.3" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" From d5279a1fbe3417422329e8690ef9fc579b022f08 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 11:52:09 -0400 Subject: [PATCH 585/716] add on_architecture --- src/DataWrangling/ecco_restoring.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index d5f86620..0644d029 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -1,5 +1,5 @@ using Oceananigans.Units -using Oceananigans.Grids: node +using Oceananigans.Grids: node, on_architecture using Oceananigans.Fields: interpolate!, interpolate, location, instantiated_location using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices using Oceananigans.Utils: Time From f2eca7f023d9eedb4db2540724841ac5fece8f23 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:05:57 -0400 Subject: [PATCH 586/716] the conversion is done _inside_ fts --- src/DataWrangling/ecco_restoring.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 0644d029..1cc78c95 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -126,7 +126,6 @@ function ECCO_field_time_series(metadata::ECCOMetadata; ECCO_native_grid = ftmp.grid boundary_conditions = FieldBoundaryConditions(ECCO_native_grid, location) times = ecco_times(metadata) - times = on_architecture(architecture, times) fts_grid = isnothing(grid) ? ECCO_native_grid : grid From 1f2582e61c2d7eaef79e9c89e0c0db9f309c5944 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 14:14:59 -0400 Subject: [PATCH 587/716] another try --- src/DataWrangling/ecco_restoring.jl | 38 ++++++++++++++++------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 1cc78c95..9fdd42e2 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -87,7 +87,7 @@ function ecco_times(metadata; start_time = first(metadata).dates) push!(times, time) end - return times + return tuple(times...) end """ @@ -227,33 +227,37 @@ end return interpolate(X, time, ecco_data, ecco_location, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) end +import Oceananigans.Fields: middle_point + +@inline middle_point(l, h) = Base.midpoint(l, h) + # Interpolating the ecco_variable in time: since the time interpolation is excessively slow, # so slow as to be 3 times slower than the whole tendency computation, we assume that the data in # memory contains the data we need for the interpolation (this is always the case). # TODO: fix time interpolation in Oceananigans -@inline function get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) +@inline get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) = @inbounds ecco_fts[i, j, k, time] - times = ecco_fts.times +# times = ecco_fts.times - n₁ = searchsortedlast(times, time.time) - n₂ = n₁ + 1 +# n₁ = searchsortedlast(times, time.time) +# n₂ = n₁ + 1 - t = time.time - @inbounds t₁ = times[n₁] - @inbounds t₂ = times[n₂] +# t = time.time +# @inbounds t₁ = times[n₁] +# @inbounds t₂ = times[n₂] - # Fractional index - ñ = (t₂ - t₁) / (n₂ - n₁) * (t - t₁) +# # Fractional index +# ñ = (t₂ - t₁) / (n₂ - n₁) * (t - t₁) - # Indices - n₁ = n₁ - n₀ + 1 - n₂ = n₂ - n₀ + 1 +# # Indices +# n₁ = n₁ - n₀ + 1 +# n₂ = n₂ - n₀ + 1 - @inbounds e₁ = ecco_fts.data[i, j, k, n₁] - @inbounds e₂ = ecco_fts.data[i, j, k, n₂] +# @inbounds e₁ = ecco_fts.data[i, j, k, n₁] +# @inbounds e₂ = ecco_fts.data[i, j, k, n₂] - return ñ * e₂ + (1 - ñ) * e₁ -end +# return ñ * e₂ + (1 - ñ) * e₁ +# end """ ECCO_restoring_forcing(metadata::ECCOMetadata; From 8dc34cc1bff7b182335046e0d3508778f8a92229 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 16:13:42 -0400 Subject: [PATCH 588/716] small verification --- src/DataWrangling/ecco_restoring.jl | 57 +++++++++++++++++++---------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 9fdd42e2..c7bfb47a 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -227,37 +227,54 @@ end return interpolate(X, time, ecco_data, ecco_location, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) end -import Oceananigans.Fields: middle_point - -@inline middle_point(l, h) = Base.midpoint(l, h) +using Base: midpoint + +# Same implentation as `Base.jl` (just a test for now, to remove) +@inline function search_sorted_times(v, x, lo, hi) + u = one(lo) + lo = lo - u + hi = hi + u + @inbounds while lo < hi - u + m = midpoint(lo, hi) + if lt(o, x, v[m]) + hi = m + else + lo = m + end + end + return lo +end # Interpolating the ecco_variable in time: since the time interpolation is excessively slow, # so slow as to be 3 times slower than the whole tendency computation, we assume that the data in # memory contains the data we need for the interpolation (this is always the case). # TODO: fix time interpolation in Oceananigans -@inline get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) = @inbounds ecco_fts[i, j, k, time] +@inline function get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) + + times = ecco_fts.times + t = time.time -# times = ecco_fts.times - -# n₁ = searchsortedlast(times, time.time) -# n₂ = n₁ + 1 + n₀ = ecco_fts.backend.start + nₘ = n₀ + ecco_fts.backend.length - 1 -# t = time.time -# @inbounds t₁ = times[n₁] -# @inbounds t₂ = times[n₂] + n₁ = search_sorted_times(times, t, n₀, nₘ) + n₂ = ifelse(n₁ < nₘ, n₂ + 1, n₁) -# # Fractional index -# ñ = (t₂ - t₁) / (n₂ - n₁) * (t - t₁) + @inbounds t₁ = times[n₁] + @inbounds t₂ = times[n₂] + + # Fractional index + ñ = ifelse(n₁ == n₂, zero(grid), (t₂ - t₁) / (n₂ - n₁) * (t - t₁)) -# # Indices -# n₁ = n₁ - n₀ + 1 -# n₂ = n₂ - n₀ + 1 + # Indices + n₁ = n₁ - n₀ + 1 + n₂ = n₂ - n₀ + 1 -# @inbounds e₁ = ecco_fts.data[i, j, k, n₁] -# @inbounds e₂ = ecco_fts.data[i, j, k, n₂] + @inbounds e₁ = ecco_fts.data[i, j, k, n₁] + @inbounds e₂ = ecco_fts.data[i, j, k, n₂] -# return ñ * e₂ + (1 - ñ) * e₁ -# end + return ñ * e₂ + (1 - ñ) * e₁ +end """ ECCO_restoring_forcing(metadata::ECCOMetadata; From d5e079777ad309469eb76979cc859419a78400ac Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 17:05:48 -0400 Subject: [PATCH 589/716] fix a typo --- src/DataWrangling/ecco_restoring.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index c7bfb47a..81d5d774 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -236,7 +236,7 @@ using Base: midpoint hi = hi + u @inbounds while lo < hi - u m = midpoint(lo, hi) - if lt(o, x, v[m]) + if lt(lo, x, v[m]) hi = m else lo = m From e91d270093b60d7e5864e118bb5b77107b78d7e4 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 17:22:40 -0400 Subject: [PATCH 590/716] typo --- src/DataWrangling/ecco_restoring.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 81d5d774..fc6523b6 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -227,7 +227,7 @@ end return interpolate(X, time, ecco_data, ecco_location, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) end -using Base: midpoint +using Base: midpoint, lt # Same implentation as `Base.jl` (just a test for now, to remove) @inline function search_sorted_times(v, x, lo, hi) From 819868996219521c2a18b8220264ffd89b5170e6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 17:58:59 -0400 Subject: [PATCH 591/716] last try --- src/DataWrangling/ecco_restoring.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index fc6523b6..c3f968a5 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -5,6 +5,7 @@ using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBac using Oceananigans.Utils: Time using CUDA: @allowscalar +using Base using NCDatasets using JLD2 @@ -227,16 +228,14 @@ end return interpolate(X, time, ecco_data, ecco_location, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) end -using Base: midpoint, lt - # Same implentation as `Base.jl` (just a test for now, to remove) @inline function search_sorted_times(v, x, lo, hi) u = one(lo) lo = lo - u hi = hi + u @inbounds while lo < hi - u - m = midpoint(lo, hi) - if lt(lo, x, v[m]) + m = Base.midpoint(lo, hi) + if Base.lt(lo, x, v[m]) hi = m else lo = m From 8c5ce3f2866f90e0cb9bb8dda0d908d00b3ca5da Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 25 Jun 2024 18:13:54 -0400 Subject: [PATCH 592/716] another bugfix --- src/DataWrangling/ecco_restoring.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index c3f968a5..cb1829a5 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -235,7 +235,7 @@ end hi = hi + u @inbounds while lo < hi - u m = Base.midpoint(lo, hi) - if Base.lt(lo, x, v[m]) + if x < v[m] hi = m else lo = m From 2bb12b427b97113f9c2c5fbe10714899b10abea7 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 25 Jun 2024 20:05:37 -0400 Subject: [PATCH 593/716] another bugfix --- src/DataWrangling/ecco_restoring.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index cb1829a5..7294370a 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -257,7 +257,7 @@ end nₘ = n₀ + ecco_fts.backend.length - 1 n₁ = search_sorted_times(times, t, n₀, nₘ) - n₂ = ifelse(n₁ < nₘ, n₂ + 1, n₁) + n₂ = ifelse(n₁ < nₘ, n₁ + 1, n₁) @inbounds t₁ = times[n₁] @inbounds t₂ = times[n₂] From 4089fdc9b3411e952140a60b4084738ba475c012 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 25 Jun 2024 21:14:54 -0400 Subject: [PATCH 594/716] fix back --- src/DataWrangling/ecco_restoring.jl | 40 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 7294370a..e13c23e9 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -81,11 +81,11 @@ An array of time differences in seconds. """ function ecco_times(metadata; start_time = first(metadata).dates) times = zeros(length(metadata)) - for data in metadata + for (t, data) in enumerate(metadata) date = data.dates time = date - start_time time = Second(time).value - push!(times, time) + times[t] = time end return tuple(times...) @@ -248,32 +248,32 @@ end # so slow as to be 3 times slower than the whole tendency computation, we assume that the data in # memory contains the data we need for the interpolation (this is always the case). # TODO: fix time interpolation in Oceananigans -@inline function get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) +@inline get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) = @inbounds ecco_fts[i, j, k, time] - times = ecco_fts.times - t = time.time +# times = ecco_fts.times +# t = time.time - n₀ = ecco_fts.backend.start - nₘ = n₀ + ecco_fts.backend.length - 1 +# n₀ = ecco_fts.backend.start +# nₘ = n₀ + ecco_fts.backend.length - 1 - n₁ = search_sorted_times(times, t, n₀, nₘ) - n₂ = ifelse(n₁ < nₘ, n₁ + 1, n₁) +# n₁ = search_sorted_times(times, t, n₀, nₘ) +# n₂ = ifelse(n₁ < nₘ, n₁ + 1, n₁) - @inbounds t₁ = times[n₁] - @inbounds t₂ = times[n₂] +# @inbounds t₁ = times[n₁] +# @inbounds t₂ = times[n₂] - # Fractional index - ñ = ifelse(n₁ == n₂, zero(grid), (t₂ - t₁) / (n₂ - n₁) * (t - t₁)) +# # Fractional index +# ñ = ifelse(n₁ == n₂, zero(grid), (t₂ - t₁) / (n₂ - n₁) * (t - t₁)) - # Indices - n₁ = n₁ - n₀ + 1 - n₂ = n₂ - n₀ + 1 +# # Indices +# n₁ = n₁ - n₀ + 1 +# n₂ = n₂ - n₀ + 1 - @inbounds e₁ = ecco_fts.data[i, j, k, n₁] - @inbounds e₂ = ecco_fts.data[i, j, k, n₂] +# @inbounds e₁ = ecco_fts.data[i, j, k, n₁] +# @inbounds e₂ = ecco_fts.data[i, j, k, n₂] - return ñ * e₂ + (1 - ñ) * e₁ -end +# return ñ * e₂ + (1 - ñ) * e₁ +# end """ ECCO_restoring_forcing(metadata::ECCOMetadata; From 2e2ea63b5d66beb1b2784cc37a1c8e2645475738 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 25 Jun 2024 21:19:54 -0400 Subject: [PATCH 595/716] back to square one. Still very slow --- src/DataWrangling/ecco_restoring.jl | 45 ----------------------------- 1 file changed, 45 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index e13c23e9..098a915f 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -228,52 +228,7 @@ end return interpolate(X, time, ecco_data, ecco_location, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) end -# Same implentation as `Base.jl` (just a test for now, to remove) -@inline function search_sorted_times(v, x, lo, hi) - u = one(lo) - lo = lo - u - hi = hi + u - @inbounds while lo < hi - u - m = Base.midpoint(lo, hi) - if x < v[m] - hi = m - else - lo = m - end - end - return lo -end - -# Interpolating the ecco_variable in time: since the time interpolation is excessively slow, -# so slow as to be 3 times slower than the whole tendency computation, we assume that the data in -# memory contains the data we need for the interpolation (this is always the case). -# TODO: fix time interpolation in Oceananigans @inline get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) = @inbounds ecco_fts[i, j, k, time] - -# times = ecco_fts.times -# t = time.time - -# n₀ = ecco_fts.backend.start -# nₘ = n₀ + ecco_fts.backend.length - 1 - -# n₁ = search_sorted_times(times, t, n₀, nₘ) -# n₂ = ifelse(n₁ < nₘ, n₁ + 1, n₁) - -# @inbounds t₁ = times[n₁] -# @inbounds t₂ = times[n₂] - -# # Fractional index -# ñ = ifelse(n₁ == n₂, zero(grid), (t₂ - t₁) / (n₂ - n₁) * (t - t₁)) - -# # Indices -# n₁ = n₁ - n₀ + 1 -# n₂ = n₂ - n₀ + 1 - -# @inbounds e₁ = ecco_fts.data[i, j, k, n₁] -# @inbounds e₂ = ecco_fts.data[i, j, k, n₂] - -# return ñ * e₂ + (1 - ñ) * e₁ -# end """ ECCO_restoring_forcing(metadata::ECCOMetadata; From 3add47302bee2099854e48fbb73cb1b31b484c27 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 25 Jun 2024 21:39:02 -0400 Subject: [PATCH 596/716] switching to an array --- src/DataWrangling/ecco_restoring.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 098a915f..cbb24a30 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -88,7 +88,7 @@ function ecco_times(metadata; start_time = first(metadata).dates) times[t] = time end - return tuple(times...) + return times end """ From dfe9ba642524b73014fd828b1e6a95d159783c17 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 25 Jun 2024 22:22:35 -0400 Subject: [PATCH 597/716] some changes to the docstring --- src/DataWrangling/ecco_restoring.jl | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index cbb24a30..07fa75f7 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -95,7 +95,8 @@ end ECCO_field_time_series(metadata::ECCOMetadata; architecture = CPU(), time_indices_in_memory = 2, - time_indexing = Cyclical()) + time_indexing = Cyclical(), + grid = nothing) Create a field time series object for ECCO data. @@ -106,6 +107,7 @@ Create a field time series object for ECCO data. - architecture: The architecture to use for computations (default: CPU()). - time_indices_in_memory: The number of time indices to keep in memory (default: 2). - time_indexing: The time indexing scheme to use (default: Cyclical()). +- grid: if not a `nothing`, the ECCO data is directly interpolated on the `grid`, """ function ECCO_field_time_series(metadata::ECCOMetadata; architecture = CPU(), @@ -238,17 +240,20 @@ end mask = 1, timescale = 5days) -Create a restoring forcing term for ECCO field time series. +Create a restoring forcing term that restores to values stored in an ECCO field time series. # Arguments: +============= - `metadata`: The metadata for the ECCO field time series. # Keyword Arguments: -- `architecture`: The architecture. -- `backend`: The backend. -- `time_indexing`: The time indexing. -- `mask`: The mask value. -- `timescale`: The timescale. +==================== +- `architecture`: The architecture. Typically `CPU` or `GPU` +- `time_indices_in_memory`: The number of time indices to keep in memory. trade-off between performance + and memory footprint. +- `time_indexing`: The time indexing scheme for the field time series, see [`FieldTimeSeries`](@ref) +- `mask`: The mask value. Can be a function of `(x, y, z, time)`, an array or a number +- `timescale`: The restoring timescale. """ function ECCO_restoring_forcing(variable_name::Symbol, version=ECCO4Monthly(); kw...) metadata = ECCOMetadata(variable_name, all_ecco_dates(version), version) From c6a726dc7cc043ffd165aa6d801c2f8a61c74b25 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 26 Jun 2024 00:06:02 -0400 Subject: [PATCH 598/716] bug with reciprocal of rho --- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index 94e626df..b1d4dfba 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -290,7 +290,7 @@ end Jᵀ = net_tracer_fluxes.T Jˢ = net_tracer_fluxes.S - ρₒ⁻¹ = ocean_reference_density + ρₒ⁻¹ = 1 / ocean_reference_density cₒ = ocean_heat_capacity atmos_ocean_Jᵘ = τx * ρₒ⁻¹ From 7fc95547928890e6835ae853b3ce2b581cb37ab5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 26 Jun 2024 00:40:28 -0400 Subject: [PATCH 599/716] more fixes --- prototype_omip_simulation/tripolar_specific_methods.jl | 4 ++-- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/prototype_omip_simulation/tripolar_specific_methods.jl b/prototype_omip_simulation/tripolar_specific_methods.jl index ee52cb3d..0e3e342d 100644 --- a/prototype_omip_simulation/tripolar_specific_methods.jl +++ b/prototype_omip_simulation/tripolar_specific_methods.jl @@ -30,7 +30,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: extrinsic_vector, intrinsi # these functions will be transferred to OrthogonalSphericalShellGrids # Here we assume that the tripolar grid is locally orthogonal -@inline function extrinsic_vector(i, j, grid::TRG, uₒ, vₒ) +@inline function extrinsic_vector(i, j, k, grid::TRG, uₒ, vₒ) φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) @@ -52,7 +52,7 @@ import ClimaOcean.OceanSeaIceModels.CrossRealmFluxes: extrinsic_vector, intrinsi return uₒ * d₁ - vₒ * d₂, uₒ * d₂ + vₒ * d₁ end -@inline function intrinsic_vector(i, j, grid::TRG, uₒ, vₒ) +@inline function intrinsic_vector(i, j, k, grid::TRG, uₒ, vₒ) φᶜᶠᵃ₊ = φnode(i, j+1, 1, grid, Center(), Face(), Center()) φᶜᶠᵃ₋ = φnode(i, j, 1, grid, Center(), Face(), Center()) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index b1d4dfba..50a46cd8 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -209,7 +209,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert back from a zonal - meridional flux to the frame of # reference of the native ocean grid - τˣ, τʸ = intrinsic_vector(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) + τˣ, τʸ = extrinsic_vector(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) @inbounds begin # +0: cooling, -0: heating From aa17c4e4d121e4fcc1360b2344c0a7db8f5c2226 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 26 Jun 2024 08:37:55 -0400 Subject: [PATCH 600/716] switch reference frames --- .../CrossRealmFluxes/atmosphere_ocean_fluxes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index 50a46cd8..e9118ae0 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -147,7 +147,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert the native grid velocities to a zonal - meridional # frame of reference (assuming the frame of reference is # latitude - longitude here, we might want to change it) - uₒ, vₒ = intrinsic_vector(i, j, kᴺ, grid, uₒ, vₒ) + uₒ, vₒ = extrinsic_vector(i, j, kᴺ, grid, uₒ, vₒ) @inbounds begin # Atmos state, which is _assumed_ to exist at location = (c, c, nothing) @@ -209,7 +209,7 @@ limit_fluxes_over_sea_ice!(args...) = nothing # Convert back from a zonal - meridional flux to the frame of # reference of the native ocean grid - τˣ, τʸ = extrinsic_vector(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) + τˣ, τʸ = intrinsic_vector(i, j, kᴺ, grid, turbulent_fluxes.x_momentum, turbulent_fluxes.y_momentum) @inbounds begin # +0: cooling, -0: heating From 1a460b25184adce970fafc327f9fdd7b2b57901e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:53:55 -0400 Subject: [PATCH 601/716] try fixing tests with secret tokens --- .buildkite/pipeline.yml | 6 + examples/generate_atmos_dataset.jl | 6 +- examples/inspect_JRA55_data.jl | 4 +- prototype_omip_simulation/Manifest.toml | 368 +++++++++--------- .../prototype_omip_simulation.jl | 24 +- src/ClimaOcean.jl | 2 +- src/DataWrangling/ECCO.jl | 6 +- test/runtests_setup.jl | 4 + test/test_ecco.jl | 45 ++- test/test_jra55.jl | 12 +- 10 files changed, 238 insertions(+), 239 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 31cc46be..2c86683f 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -22,6 +22,8 @@ steps: slurm_cpus_per_task: 8 env: JULIA_NUM_PRECOMPILE_TASKS: 8 + ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} + ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} - wait @@ -38,6 +40,8 @@ steps: env: CUDA_VISIBLE_DEVICES: "-1" TEST_GROUP: "ecco" + ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} + ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} commands: - "julia --project -e 'using Pkg; Pkg.test()'" @@ -46,6 +50,8 @@ steps: env: CUDA_VISIBLE_DEVICES: "-1" TEST_GROUP: "fluxes" + ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} + ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} commands: - "julia --project -e 'using Pkg; Pkg.test()'" diff --git a/examples/generate_atmos_dataset.jl b/examples/generate_atmos_dataset.jl index b4e395bd..24ef1cc0 100644 --- a/examples/generate_atmos_dataset.jl +++ b/examples/generate_atmos_dataset.jl @@ -4,9 +4,9 @@ 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) +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]) diff --git a/examples/inspect_JRA55_data.jl b/examples/inspect_JRA55_data.jl index 1c1f0ccb..37403da3 100644 --- a/examples/inspect_JRA55_data.jl +++ b/examples/inspect_JRA55_data.jl @@ -5,8 +5,8 @@ using Oceananigans.Units using Printf time_indices = Colon() -Qswt = ClimaOcean.JRA55.jra55_field_time_series(:downwelling_shortwave_radiation; time_indices) -rht = ClimaOcean.JRA55.jra55_field_time_series(:relative_humidity; time_indices) +Qswt = ClimaOcean.JRA55.JRA55_field_time_series(:downwelling_shortwave_radiation; time_indices) +rht = ClimaOcean.JRA55.JRA55_field_time_series(:relative_humidity; time_indices) function lonlat2xyz(lons::AbstractVector, lats::AbstractVector) x = [cosd(lat) * cosd(lon) for lon in lons, lat in lats] diff --git a/prototype_omip_simulation/Manifest.toml b/prototype_omip_simulation/Manifest.toml index c3888f00..585caec3 100644 --- a/prototype_omip_simulation/Manifest.toml +++ b/prototype_omip_simulation/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.3" +julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "ad94f0873a50599743724c16c7dfb94779a2964d" +project_hash = "1cab777b23bf99dac075dcd3cc1d9faf7933f586" [[deps.ANSIColoredPrinters]] git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" @@ -62,9 +62,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "133a240faec6e074e07c31ee75619c90544179cf" +git-tree-sha1 = "ed2ec3c9b483842ae59cd273834e5b46206d6dda" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.10.0" +version = "7.11.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -107,9 +107,9 @@ version = "0.5.0" uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" [[deps.BitFlags]] -git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.8" +version = "0.1.9" [[deps.BitTwiddlingConvenienceFunctions]] deps = ["Static"] @@ -142,50 +142,55 @@ version = "0.1.3" [[deps.CPUSummary]] deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" +git-tree-sha1 = "585a387a490f1c4bd88be67eea15b93da5e85db7" uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.4" +version = "0.2.5" [[deps.CUDA]] deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics"] -git-tree-sha1 = "dd1c682b372b6791b69f6823afe364fc92a0146c" +git-tree-sha1 = "6e945e876652f2003e6ca74e19a3c45017d3e9f6" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.3.1" -weakdeps = ["ChainRulesCore", "SpecialFunctions"] +version = "5.4.2" [deps.CUDA.extensions] ChainRulesCoreExt = "ChainRulesCore" + EnzymeCoreExt = "EnzymeCore" SpecialFunctionsExt = "SpecialFunctions" + [deps.CUDA.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "dc172b558adbf17952001e15cf0d6364e6d78c2f" +git-tree-sha1 = "c48f9da18efd43b6b7adb7ee1f93fe5f2926c339" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.8.1+0" +version = "0.9.0+0" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] -git-tree-sha1 = "38f830504358e9972d2a0c3e5d51cb865e0733df" +git-tree-sha1 = "f3b237289a5a77c759b2dd5d4c2ff641d67c4030" uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.2.4" +version = "0.3.4" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "4ca7d6d92075906c2ce871ea8bba971fff20d00c" +git-tree-sha1 = "bcba305388e16aa5c879e896726db9e71b4942c6" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.12.1+0" +version = "0.14.0+1" [[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" +git-tree-sha1 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.0+1" +version = "1.18.0+2" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +git-tree-sha1 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.23.0" +version = "1.24.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -199,7 +204,7 @@ version = "0.2.0" [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "e25e43451edd449c3dcc899bd447983d7b76a59f" +git-tree-sha1 = "be4f97676cd18dc1566637e03c189b04c3fb4c59" repo-rev = "main" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" @@ -241,15 +246,15 @@ weakdeps = ["SpecialFunctions"] [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.10" +version = "0.12.11" [[deps.CommonDataModel]] deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "d7d7b58e149f19c322840a50d1bc20e8c23addb4" +git-tree-sha1 = "d6fb5bf939a2753c74984b11434ea25d6c397a58" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.5" +version = "0.3.6" [[deps.CommonSolve]] git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" @@ -264,9 +269,9 @@ version = "0.3.0" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.14.0" +version = "4.15.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -277,15 +282,6 @@ deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "1.1.1+0" -[[deps.CompositionsBase]] -git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" -uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" -version = "0.1.2" -weakdeps = ["InverseFunctions"] - - [deps.CompositionsBase.extensions] - CompositionsBaseInverseFunctionsExt = "InverseFunctions" - [[deps.CompositionsBase]] git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" @@ -411,9 +407,9 @@ version = "0.8.6" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] -git-tree-sha1 = "f15a91e6e3919055efa4f206f942a73fedf5dfe6" +git-tree-sha1 = "5461b2a67beb9089980e2f8f25145186b6d34f91" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.4.0" +version = "1.4.1" [[deps.DocumenterTools]] deps = ["Base64", "DocStringExtensions", "LibGit2"] @@ -439,9 +435,9 @@ version = "0.1.10" [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +git-tree-sha1 = "1c6317308b9dc757616f0b5cb379db10494443a7" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.5.0+0" +version = "2.6.2+0" [[deps.ExprTools]] git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" @@ -483,15 +479,15 @@ uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FixedPointNumbers]] deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" +version = "0.8.5" [[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.93+0" +version = "2.13.96+0" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] @@ -505,15 +501,15 @@ weakdeps = ["StaticArrays"] [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +git-tree-sha1 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.1+0" +version = "2.13.2+0" [[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.10+0" +version = "1.0.14+0" [[deps.Future]] deps = ["Random"] @@ -526,9 +522,9 @@ version = "6.2.1+6" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "68e8ff56a4a355a85d2784b94614491f8c900cde" +git-tree-sha1 = "c154546e322a9c73364e8a60430b0f79b812d320" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "10.1.0" +version = "10.2.0" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -538,9 +534,9 @@ version = "0.1.6" [[deps.GPUCompiler]] deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] -git-tree-sha1 = "1600477fba37c9fc067b9be21f5e8101f24a8865" +git-tree-sha1 = "518ebd058c9895de468a8c255797b0c53fdb44dd" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.26.4" +version = "0.26.5" [[deps.Gettext_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] @@ -562,9 +558,9 @@ 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" +git-tree-sha1 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.0+0" +version = "2.80.2+0" [[deps.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" @@ -591,9 +587,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 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +git-tree-sha1 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.5" +version = "1.10.8" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -615,9 +611,9 @@ version = "2.10.0+0" [[deps.IOCapture]] deps = ["Logging", "Random"] -git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c" +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.4" +version = "0.2.5" [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" @@ -644,15 +640,21 @@ version = "0.2.1" [[deps.InlineStrings]] deps = ["Parsers"] -git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +git-tree-sha1 = "86356004f30f8e737eff143d57d41bd580e437aa" uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.0" +version = "1.4.1" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +git-tree-sha1 = "be50fe8df3acbffa0274a744f1a99d29c45a57f4" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.0.2+0" +version = "2024.1.0+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -660,9 +662,9 @@ uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[deps.InverseFunctions]] deps = ["Test"] -git-tree-sha1 = "896385798a8d49a255c398bd49162062e4a4c435" +git-tree-sha1 = "e7cbed5032c4c397a6ac23d1493f3289e01231c4" uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.13" +version = "0.1.14" weakdeps = ["Dates"] [deps.InverseFunctions.extensions] @@ -690,10 +692,10 @@ 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" +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] +git-tree-sha1 = "bdbe8222d2f5703ad6a7019277d149ec6d78c301" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.46" +version = "0.4.48" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -715,9 +717,9 @@ version = "1.13.2" [[deps.JuliaInterpreter]] deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] -git-tree-sha1 = "e9648d90370e2d0317f9518c9c6e0841db54a90b" +git-tree-sha1 = "a6adc2dcfe4187c40dc7c2c9d2128e326360e90a" uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.9.31" +version = "0.9.32" [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -727,9 +729,9 @@ version = "0.2.1+0" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "Requires", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "db02395e4c374030c53dc28f3c1d33dec35f7272" +git-tree-sha1 = "b8fcefe4418e4a7a2c3aaac883fecddd8efbe286" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.19" +version = "0.9.21" [deps.KernelAbstractions.extensions] EnzymeExt = "EnzymeCore" @@ -738,16 +740,16 @@ version = "0.9.19" EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" [[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.1+0" +version = "3.100.2+0" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "839c82932db86740ae729779e610f07a1640be9a" +git-tree-sha1 = "389aea28d882a40b5e1747069af71bdbd47a1cae" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "6.6.3" +version = "7.2.1" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -780,10 +782,10 @@ weakdeps = ["Serialization"] SerializationExt = ["Serialization"] [[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.1+0" +version = "2.10.2+0" [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" @@ -839,16 +841,16 @@ 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" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll"] +git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.7+0" +version = "1.8.11+0" [[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.42.0+0" +version = "1.49.0+0" [[deps.Libiconv_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -858,15 +860,15 @@ version = "1.17.0+0" [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +git-tree-sha1 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.39.3+0" +version = "2.40.1+0" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.39.3+1" +version = "2.40.1+0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -874,9 +876,9 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.27" +version = "0.3.28" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -899,9 +901,9 @@ version = "1.0.3" [[deps.LoopVectorization]] deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "a13f3be5d84b9c95465d743c82af0b094ef9c2e2" +git-tree-sha1 = "8f6786d8b2b3248d79db3ad359ce95382d5a6df8" uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.169" +version = "0.12.170" weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] [deps.LoopVectorization.extensions] @@ -910,9 +912,9 @@ weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] [[deps.LoweredCodeUtils]] deps = ["JuliaInterpreter"] -git-tree-sha1 = "31e27f0b0bf0df3e3e951bfcc43fe8c730a219f6" +git-tree-sha1 = "c6a36b22d2cca0e1a903f00f600991f97bf5f426" uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" -version = "2.4.5" +version = "2.4.6" [[deps.Lz4_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -921,10 +923,10 @@ 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" +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "80b2833b56d466b3858d565adcd16a4a05f2089b" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.0.0+0" +version = "2024.1.0+0" [[deps.MPI]] deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] @@ -942,21 +944,21 @@ version = "0.20.16" [[deps.MPICH_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "656036b9ed6f942d35e536e249600bc31d0f9df8" +git-tree-sha1 = "4099bb6809ac109bfc17d521dad33763bcf026b7" uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.2.0+0" +version = "4.2.1+1" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] -git-tree-sha1 = "8f6af051b9e8ec597fa09d8885ed79fd582f33c9" +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.10" +version = "0.1.11" [[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "77c3bd69fdb024d75af38713e883d0f249ce19c2" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "8c35d5420193841b2f367e658540e8d9e0601ed0" uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.3.2+0" +version = "5.4.0+0" [[deps.MacroTools]] deps = ["Markdown", "Random"] @@ -1022,9 +1024,9 @@ version = "2023.1.10" [[deps.NCDatasets]] deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "d40d24d12f710c39d3a66be99c567ce0032f28a7" +git-tree-sha1 = "a640912695952b074672edb5f9aaee2f7f9fd59a" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.3" +version = "0.14.4" [[deps.NVTX]] deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] @@ -1062,11 +1064,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 = "82eddd14528a13419be8b75da9daa23fb2a14363" -repo-rev = "main" +git-tree-sha1 = "48e53265f2a67554497efd193ac7864385316aa7" +repo-rev = "ss/times-on-gpu" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.90.12" +version = "0.91.3" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -1100,22 +1102,22 @@ 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" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] +git-tree-sha1 = "a9de2f1fc98b92f8856c640bf4aec1ac9b2a0d86" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.2+0" +version = "5.0.3+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +git-tree-sha1 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.2" +version = "1.4.3" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.13+1" +version = "3.0.14+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1135,10 +1137,10 @@ uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" version = "1.6.3" [[deps.OrthogonalSphericalShellGrids]] -deps = ["CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays", "Printf"] -git-tree-sha1 = "ad2ad883a638e387818d0e2b270c67fd4dcea89f" +deps = ["Adapt", "CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays", "Printf"] +git-tree-sha1 = "1a31c10d9eeec98bfdbb66282b39be643db31fea" repo-rev = "main" -repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl" +repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl.git" uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" version = "0.1.0" @@ -1153,12 +1155,6 @@ deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" version = "10.42.0+1" -[[deps.PMIx_jll]] -deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "Libdl", "Zlib_jll", "libevent_jll"] -git-tree-sha1 = "360f48126b5f2c2f0c833be960097f7c62705976" -uuid = "32165bc3-0280-59bc-8c0b-c33b6203efab" -version = "4.2.9+0" - [[deps.PackageExtensionCompat]] git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" @@ -1179,15 +1175,17 @@ version = "2.8.1" [[deps.PencilArrays]] deps = ["Adapt", "JSON3", "LinearAlgebra", "MPI", "OffsetArrays", "Random", "Reexport", "StaticArrayInterface", "StaticArrays", "StaticPermutations", "Strided", "TimerOutputs", "VersionParsing"] -git-tree-sha1 = "6510e851700a851944f7ffa5cd990cced4802ad2" +git-tree-sha1 = "fa85ac32172d96cfdb91dbc53e8e57007e5a2b5a" uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.3" +version = "0.19.5" [deps.PencilArrays.extensions] + PencilArraysAMDGPUExt = ["AMDGPU"] PencilArraysDiffEqExt = ["DiffEqBase"] PencilArraysHDF5Ext = ["HDF5"] [deps.PencilArrays.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" @@ -1199,9 +1197,9 @@ version = "0.15.1" [[deps.Pixman_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +git-tree-sha1 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.42.2+0" +version = "0.43.4+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] @@ -1240,9 +1238,9 @@ version = "1.4.3" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +git-tree-sha1 = "66b20dd35966a748321d3b2537c4584cf40387c7" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.3.1" +version = "2.3.2" [[deps.Printf]] deps = ["Unicode"] @@ -1341,9 +1339,9 @@ version = "2.1.5" [[deps.Rotations]] deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "2a0a5d8569f481ff8840e3b7c84bbf188db6a3fe" +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.0" +version = "1.7.1" weakdeps = ["RecipesBase"] [deps.Rotations.extensions] @@ -1377,9 +1375,9 @@ version = "0.3.4" [[deps.SentinelArrays]] deps = ["Dates", "Random"] -git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +git-tree-sha1 = "90b4f68892337554d31cdcdbe19e48989f26c7e6" uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.1" +version = "1.4.3" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -1405,9 +1403,9 @@ version = "1.10.0" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +git-tree-sha1 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.1" +version = "2.4.0" weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] @@ -1438,9 +1436,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +git-tree-sha1 = "6e00379a24597be4ae1ee6b2d882e15392040132" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.3" +version = "1.9.5" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -1448,9 +1446,9 @@ weakdeps = ["ChainRulesCore", "Statistics"] StaticArraysStatisticsExt = "Statistics" [[deps.StaticArraysCore]] -git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.2" +version = "1.4.3" [[deps.StaticPermutations]] git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" @@ -1470,15 +1468,15 @@ version = "1.7.0" [[deps.Strided]] deps = ["LinearAlgebra", "StridedViews", "TupleTools"] -git-tree-sha1 = "40c69be0e1b72ee2f42923b7d1ff13e0b04e675c" +git-tree-sha1 = "bd9bd1c70cfc115cc3a30213fc725125a6b43652" uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" -version = "2.0.4" +version = "2.1.0" [[deps.StridedViews]] deps = ["LinearAlgebra", "PackageExtensionCompat"] -git-tree-sha1 = "5b765c4e401693ab08981989f74a36a010aa1d8e" +git-tree-sha1 = "2917996ce0fa6b8a3a85240a5e9ff930e2aeaa43" uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" -version = "0.2.2" +version = "0.3.1" weakdeps = ["CUDA"] [deps.StridedViews.extensions] @@ -1520,17 +1518,15 @@ 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" +git-tree-sha1 = "89c701c87f378ce95e7ddbcd69b8f1106ba8b968" uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.9.2" +version = "0.11.0" [deps.SurfaceFluxes.extensions] - CreateParametersExt = "CLIMAParameters" + CreateParametersExt = "ClimaParams" [deps.SurfaceFluxes.weakdeps] - CLIMAParameters = "6eacf6c3-8458-43b9-ae03-caf5306d3d53" + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" [[deps.TOML]] deps = ["Dates"] @@ -1578,11 +1574,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "48098ebfee40374b8415b602163e02aa7c43d32b" -repo-rev = "glw/density-example" -repo-url = "https://github.com/glwagner/Thermodynamics.jl.git" +git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.12.5" +version = "0.12.6" [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" @@ -1604,14 +1598,14 @@ version = "0.5.0" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] -git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +git-tree-sha1 = "5a13ae8a41237cff5ecf34f73eb1b8f42fff6531" uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" -version = "0.5.23" +version = "0.5.24" [[deps.TranscodingStreams]] -git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +git-tree-sha1 = "d73336d81cafdc277ff45558bb7eaa2b04a8e472" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.7" +version = "0.10.10" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] @@ -1646,15 +1640,15 @@ version = "0.2.1" [[deps.UnsafeAtomicsLLVM]] deps = ["LLVM", "UnsafeAtomics"] -git-tree-sha1 = "323e3d0acf5e78a56dfae7bd8928c989b4f3083e" +git-tree-sha1 = "d9f5962fecd5ccece07db1ff006fb0b5271bdfdd" uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" -version = "0.1.3" +version = "0.1.4" [[deps.VectorizationBase]] deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "ac377f0a248753a1b1d58bbc92a64f5a726dfb71" +git-tree-sha1 = "e863582a41c5731f51fd050563ae91eb33cf09be" uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.66" +version = "0.21.68" [[deps.VersionParsing]] git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" @@ -1663,9 +1657,9 @@ version = "1.3.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +git-tree-sha1 = "52ff2af32e591541550bd753c0da8b9bc92bb9d9" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.12.6+0" +version = "2.12.7+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] @@ -1698,16 +1692,16 @@ 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" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.4+4" +version = "1.3.6+0" [[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.10+4" +version = "0.9.11+0" [[deps.Xorg_libpthread_stubs_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1745,10 +1739,10 @@ uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" version = "1.1.2+0" [[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.4.0+0" +version = "3.9.0+0" [[deps.libass_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] @@ -1761,12 +1755,6 @@ 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" @@ -1796,17 +1784,17 @@ deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" version = "1.52.0+1" +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2021.12.0+0" + [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" -[[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/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 066cd5f8..28ed9dae 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -6,7 +6,6 @@ using OrthogonalSphericalShellGrids using Oceananigans using Oceananigans: architecture using Oceananigans.Grids: on_architecture -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units using ClimaOcean @@ -35,13 +34,13 @@ include("tripolar_specific_methods.jl") bathymetry_file = nothing # "bathymetry_tmp.jld2" # 60 vertical levels -z_faces = exponential_z_faces(Nz=60, depth=6000) +z_faces = exponential_z_faces(Nz=20, depth=6000) -Nx = 1440 -Ny = 720 +Nx = 200 +Ny = 100 Nz = length(z_faces) - 1 -arch = GPU() #Distributed(GPU(), partition = Partition(2)) +arch = CPU() #Distributed(GPU(), partition = Partition(2)) grid = TripolarGrid(arch; size = (Nx, Ny, Nz), @@ -94,10 +93,13 @@ const c₂⁻ = c⁺[2] const c₃⁻ = - c⁺[3] const c₄⁻ = c⁺[4] -@inline mask(λ, φ, z, t) = ifelse(φ >= 70, c₁⁺ * φ^3 + c₂⁺ * φ^2 + c₃⁺ * φ + c₄⁺, - ifelse(φ <= -70, c₁⁻ * φ^3 + c₂⁻ * φ^2 + c₃⁻ * φ + c₄⁻, 0)) +@inline mask_f(λ, φ, z) = ifelse(φ >= 70, c₁⁺ * φ^3 + c₂⁺ * φ^2 + c₃⁺ * φ + c₄⁺, + ifelse(φ <= -70, c₁⁻ * φ^3 + c₂⁻ * φ^2 + c₃⁻ * φ + c₄⁻, zero(eltype(φ)))) -dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) +mask = CenterField(grid) +set!(mask, mask_f) + +dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 10, 1) temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) @@ -107,7 +109,7 @@ FS = ECCO_restoring_forcing(salinity; mask, grid, architecture = arch, timesc forcing = (; T = FT, S = FS) -ocean = ocean_simulation(grid; free_surface, forcing) +ocean = ocean_simulation(grid; free_surface, forcing, closure = nothing) model = ocean.model initial_date = dates[1] @@ -148,7 +150,7 @@ function progress(sim) wall_time[1] = time_ns() end -ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) +ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) fluxes = (u = model.velocities.u.boundary_conditions.top.condition, v = model.velocities.v.boundary_conditions.top.condition, @@ -182,7 +184,7 @@ ocean.output_writers[:checkpoint] = Checkpointer(model, # Simulation warm up! ocean.Δt = 10 ocean.stop_iteration = 1 -wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 1, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) stop_time = 15days diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index c5f3cf41..671a2a53 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -14,7 +14,7 @@ export exponential_z_faces, PowerLawStretching, LinearStretching, exponential_z_faces, - jra55_field_time_series, + JRA55_field_time_series, ecco_field, ECCOMetadata, ocean_simulation, initialize! diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index 38558078..8e530cd5 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -131,9 +131,9 @@ The data is either: (3) filled from `user_data` if `user_data` is provided. """ function ecco_field(metadata::ECCOMetadata; - architecture = CPU(), - horizontal_halo = (3, 3), - filename = file_name(metadata)) + architecture = CPU(), + horizontal_halo = (3, 3), + filename = file_name(metadata)) shortname = short_name(metadata) diff --git a/test/runtests_setup.jl b/test/runtests_setup.jl index 83e3f1d9..8bf96303 100644 --- a/test/runtests_setup.jl +++ b/test/runtests_setup.jl @@ -3,6 +3,10 @@ using Oceananigans using CUDA using Test +using ClimaOcean.DataWrangling +using ClimaOcean.ECCO +using ClimaOcean.JRA55 + using Oceananigans.Architectures: architecture using Oceananigans.OutputReaders: interpolate! diff --git a/test/test_ecco.jl b/test/test_ecco.jl index ce28bc14..4c060e8b 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -2,42 +2,41 @@ include("runtests_setup.jl") using ClimaOcean using ClimaOcean.ECCO +using ClimaOcean.ECCO: ecco_field, file_name using Oceananigans.Grids: topology +using CFTime +using Dates + @testset "ECCO fields utilities" begin for arch in test_architectures A = typeof(arch) @info "Testing ecco_field on $A..." - temperature_filename = ECCO.ecco_file_names[:temperature] - ecco_temperature = ECCO.ecco_field(:temperature; architecture=arch) - - @test isfile(temperature_filename) - rm(temperature_filename) + start_date = DateTimeProlepticGregorian(1993, 1, 1) + end_date = DateTimeProlepticGregorian(1993, 4, 1) + dates = start_date : Month(1) : end_date - @test ecco_temperature isa Field - @test ecco_temperature.grid isa LatitudeLongitudeGrid - @test topology(ecco_temperature.grid) == (Periodic, Bounded, Bounded) + temperature = ECCOMetadata(:temperature, dates, ECCO2Daily()) + t_restoring = ECCO_restoring_forcing(temperature; timescale = 10days) - Nx, Ny, Nz = size(ecco_temperature) - @test Nx == 1440 - @test Ny == 720 - @test Nz == 50 + ecco_fts = t_restoring.func.ecco_fts - ice_thickness_filename = ECCO.ecco_file_names[:sea_ice_thickness] - ecco_ice_thickness = ECCO.ecco_field(:sea_ice_thickness; architecture=arch) + for metadata in temperature + temperature_filename = file_name(metadata) + @test isfile(temperature_filename) + end - @test isfile(ice_thickness_filename) - rm(ice_thickness_filename) + @test ecco_fts isa FieldTimeSeries + @test ecco_fts.grid isa LatitudeLongitudeGrid + @test topology(ecco_fts.grid) == (Periodic, Bounded, Bounded) - @test ecco_ice_thickness isa Field - @test ecco_ice_thickness.grid isa LatitudeLongitudeGrid - @test topology(ecco_ice_thickness.grid) == (Periodic, Bounded, Flat) + Nx, Ny, Nz, Nt = size(ecco_fts.data) - Nx, Ny, Nz = size(ecco_ice_thickness) - @test Nx == 1440 - @test Ny == 720 - @test Nz == 1 + @test Nx == size(temperature[1])[1] + @test Ny == size(temperature[1])[2] + @test Nz == size(temperature[1])[3] + @test Nt == size(temperature[1])[3] end end diff --git a/test/test_jra55.jl b/test/test_jra55.jl index d083cdca..12155f47 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -11,7 +11,7 @@ include("runtests_setup.jl") time_indices = 1:3 # This should download a file called "RYF.rsds.1990_1991.nc" - jra55_fts = ClimaOcean.DataWrangling.JRA55_field_time_series(test_name; architecture=arch, time_indices) + jra55_fts = JRA55_field_time_series(test_name; architecture=arch, time_indices) @test isfile(test_filename) @test jra55_fts isa FieldTimeSeries @@ -37,10 +37,10 @@ include("runtests_setup.jl") rm(test_jld2_filename, force=true) @info "Testing loading preprocessed JRA55 data on $A..." - in_memory_jra55_fts = ClimaOcean.DataWrangling.JRA55_field_time_series(test_name; - time_indices, - architecture = arch, - backend = InMemory(2)) + in_memory_jra55_fts = JRA55_field_time_series(test_name; + time_indices, + architecture = arch, + backend = InMemory(2)) @test in_memory_jra55_fts isa FieldTimeSeries @@ -75,7 +75,7 @@ include("runtests_setup.jl") # Random regression test CUDA.@allowscalar begin - @test target_fts[1, 1, 1, 1] == 222.243136478611 + @test target_fts[1, 1, 1, 1] == 222.243136478611 # Only include this if we are filling halo regions within # interpolate_field_time_series From 65327db58a395b9786dd5f99774e917bf88acb81 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:55:42 -0400 Subject: [PATCH 602/716] take ecco 4 monthly --- test/test_ecco.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_ecco.jl b/test/test_ecco.jl index 4c060e8b..7ebf6acc 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -17,7 +17,7 @@ using Dates end_date = DateTimeProlepticGregorian(1993, 4, 1) dates = start_date : Month(1) : end_date - temperature = ECCOMetadata(:temperature, dates, ECCO2Daily()) + temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) t_restoring = ECCO_restoring_forcing(temperature; timescale = 10days) ecco_fts = t_restoring.func.ecco_fts From 35a086c4486337198e80c4974889bf16e8202095 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:02:46 -0400 Subject: [PATCH 603/716] maybe here it will work? --- .buildkite/pipeline.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 2c86683f..ced1dab9 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -7,6 +7,9 @@ env: JULIA_LOAD_PATH: "${JULIA_LOAD_PATH}:${BUILDKITE_BUILD_CHECKOUT_PATH}/.buildkite" OPENBLAS_NUM_THREADS: 1 OMPI_MCA_opal_warn_on_missing_libcuda: 0 + ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} + ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} + steps: - label: "initialize" @@ -22,8 +25,6 @@ steps: slurm_cpus_per_task: 8 env: JULIA_NUM_PRECOMPILE_TASKS: 8 - ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} - ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} - wait @@ -40,8 +41,6 @@ steps: env: CUDA_VISIBLE_DEVICES: "-1" TEST_GROUP: "ecco" - ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} - ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} commands: - "julia --project -e 'using Pkg; Pkg.test()'" @@ -50,8 +49,6 @@ steps: env: CUDA_VISIBLE_DEVICES: "-1" TEST_GROUP: "fluxes" - ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} - ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} commands: - "julia --project -e 'using Pkg; Pkg.test()'" From e8b33967ea7edf909e85af913965adf5e77c86fd Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:58:55 -0400 Subject: [PATCH 604/716] userame and password in docs --- .buildkite/pipeline.yml | 4 ++-- .github/workflows/Documenter.yml | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index ced1dab9..f2afb414 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -7,8 +7,8 @@ env: JULIA_LOAD_PATH: "${JULIA_LOAD_PATH}:${BUILDKITE_BUILD_CHECKOUT_PATH}/.buildkite" OPENBLAS_NUM_THREADS: 1 OMPI_MCA_opal_warn_on_missing_libcuda: 0 - ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} - ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} + ECCO_USERNAME: "${{ secrets.ECCO_USERNAME }}" + ECCO_PASSWORD: "${{ secrets.ECCO_PASSWORD }}" steps: diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 1eb5ef50..4f48b2b1 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -30,5 +30,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key - JULIA_DEBUG: Documenter + JULIA_DEBUG: Documenter + ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} # To download ECCO data from the podaac website + ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} # To download ECCO data from the podaac website run: julia --color=yes --project=docs/ docs/make.jl From 738aac073992cf4ea49af5692ad2be90f8719a6e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 3 Jul 2024 13:04:04 -0400 Subject: [PATCH 605/716] ecco secrets in ci --- .buildkite/pipeline.yml | 3 --- .github/workflows/ci.yml | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index f2afb414..31cc46be 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -7,9 +7,6 @@ env: JULIA_LOAD_PATH: "${JULIA_LOAD_PATH}:${BUILDKITE_BUILD_CHECKOUT_PATH}/.buildkite" OPENBLAS_NUM_THREADS: 1 OMPI_MCA_opal_warn_on_missing_libcuda: 0 - ECCO_USERNAME: "${{ secrets.ECCO_USERNAME }}" - ECCO_PASSWORD: "${{ secrets.ECCO_PASSWORD }}" - steps: - label: "initialize" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 101e062c..0bc5604c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,6 +53,8 @@ jobs: julia --color=yes --project -e 'using Pkg; Pkg.test()' env: TEST_GROUP: "downloading" + ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} # To download ECCO data from the podaac website + ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} # To download ECCO data from the podaac website - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v3 with: From ac428481d32169b7fbcf8738d945c826a2607a6a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 3 Jul 2024 17:18:14 -0400 Subject: [PATCH 606/716] remove all ECCO2 from examples --- examples/generate_surface_fluxes.jl | 10 +-- examples/single_column_simulation.jl | 6 +- examples/surface_flux_computation.jl | 101 --------------------------- src/DataWrangling/ECCO.jl | 3 + 4 files changed, 11 insertions(+), 109 deletions(-) delete mode 100644 examples/surface_flux_computation.jl diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index 859c4c6f..e97b7574 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -10,7 +10,7 @@ # We also need Oceananigans for the ImmersedBoundaryGrid and Field utilities, and CairoMakie to plot. using ClimaOcean -using ClimaOcean.ECCO2 +using ClimaOcean.ECCO using ClimaOcean.JRA55 using ClimaOcean.OceanSimulations using Oceananigans @@ -23,7 +23,7 @@ using CairoMakie # We can use this mask as an immersed boundary for our grid. # Let's create the grid and visualize the mask. -mask = ecco2_center_mask() +mask = ecco_mask(:temperature) grid = mask.grid grid = ImmersedBoundaryGrid(grid, GridFittedBoundary(mask)) @@ -65,14 +65,14 @@ ocean = ocean_simulation(grid; momentum_advection = nothing, # Now that we have an atmosphere and a container for the ocean, we need to populate # our ocean with initial conditions. To do this, we can use the ECCO2 dataset by -# `set!`ting the model with the `ECCO2Metadata`. If no date is specified, +# `set!`ting the model with the `ECCOMetadata`. If no date is specified, # the fields corresponding to January 1st, 1992 (the first available date in # ECCO2) are used. # This command will download the fields to the local machine. set!(ocean.model; - T = ECCO2Metadata(:temperature), - S = ECCO2Metadata(:salinity)) + T = ECCOMetadata(:temperature), + S = ECCOMetadata(:salinity)) # The final step is to construct a coupled model. # The coupled model requires an ocean, which we have just constructed and initialized, diff --git a/examples/single_column_simulation.jl b/examples/single_column_simulation.jl index 2e850592..6c5a7501 100644 --- a/examples/single_column_simulation.jl +++ b/examples/single_column_simulation.jl @@ -20,7 +20,7 @@ using Oceananigans.BuoyancyModels: buoyancy_frequency using Oceananigans.Units: Time using ClimaOcean -using ClimaOcean.ECCO2: ECCO2Metadata +using ClimaOcean.ECCO using ClimaOcean.OceanSimulations using CairoMakie @@ -64,8 +64,8 @@ model = ocean.model start_time = time_ns() # Initial conditions -set!(ocean.model, T = ECCO2Metadata(:temperature), - S = ECCO2Metadata(:salinity), +set!(ocean.model, T = ECCOMetadata(:temperature), + S = ECCOMetadata(:salinity), e = 1e-6) elapsed = time_ns() - start_time diff --git a/examples/surface_flux_computation.jl b/examples/surface_flux_computation.jl deleted file mode 100644 index 9b786df6..00000000 --- a/examples/surface_flux_computation.jl +++ /dev/null @@ -1,101 +0,0 @@ - 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/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index 8e530cd5..f5010ea4 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -211,6 +211,9 @@ function ecco_mask(metadata, architecture = CPU(); return mask end +# Default +ecco_mask() = ecco_mask(ECCOMetadata(:temperature)) + """ inpainted_ecco_field(variable_name; architecture = CPU(), From a297bf9688f3fa75fa5f14a0ccc299a46123e802 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 3 Jul 2024 17:36:23 -0400 Subject: [PATCH 607/716] more verbose error --- src/DataWrangling/ecco_metadata.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index b742bede..82a2171e 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -152,8 +152,8 @@ function download_dataset!(metadata::ECCOMetadata; if !isfile(filename) - isnothing(username) && throw(ArgumentError("Please provide a username in the ECCO_USERNAME environment variable!")) - isnothing(password) && throw(ArgumentError("Please provide a password in the ECCO_PASSWORD environment variable!")) + isnothing(username) && throw(ArgumentError("Could not find the username for $(url). Please provide a username in the ECCO_USERNAME environment variable.")) + isnothing(password) && throw(ArgumentError("Could not find the username for $(url). Please provide a password in the ECCO_PASSWORD environment variable.")) # Version specific download file url if data.version isa ECCO2Monthly || data.version isa ECCO2Daily From d691f3b4b03c8a5394abcbe6d0fc5adac129c7f0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 3 Jul 2024 18:08:21 -0400 Subject: [PATCH 608/716] test new buildkite env variables --- .buildkite/pipeline.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 31cc46be..bc7ab6fa 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -49,16 +49,5 @@ steps: commands: - "julia --project -e 'using Pkg; Pkg.test()'" - # - label: "documentation" - # env: - # JULIA_DEBUG: "Documenter" - # commands: - # - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" - # - "julia --color=yes --project=docs/ docs/make.jl" - # agents: - # slurm_mem: 120G - # slurm_ntasks: 1 - # slurm_gpus_per_task: 1 - - wait: ~ continue_on_failure: true From da0aeabee9b85fe370324f70cb453986eef45377 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 3 Jul 2024 18:32:49 -0400 Subject: [PATCH 609/716] fix tests --- test/runtests_setup.jl | 1 + test/test_ecco.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/runtests_setup.jl b/test/runtests_setup.jl index 8bf96303..b1d897e8 100644 --- a/test/runtests_setup.jl +++ b/test/runtests_setup.jl @@ -6,6 +6,7 @@ using Test using ClimaOcean.DataWrangling using ClimaOcean.ECCO using ClimaOcean.JRA55 +using ClimaOcean.JRA55: JRA55_field_time_series using Oceananigans.Architectures: architecture using Oceananigans.OutputReaders: interpolate! diff --git a/test/test_ecco.jl b/test/test_ecco.jl index 7ebf6acc..f91d5004 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -18,7 +18,7 @@ using Dates dates = start_date : Month(1) : end_date temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) - t_restoring = ECCO_restoring_forcing(temperature; timescale = 10days) + t_restoring = ECCO_restoring_forcing(temperature; timescale = 1000.0) ecco_fts = t_restoring.func.ecco_fts From 98881ff3f7e48df204adadfd10509e116929ca4c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 4 Jul 2024 10:09:08 -0400 Subject: [PATCH 610/716] fix tests --- test/test_ecco.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test_ecco.jl b/test/test_ecco.jl index f91d5004..eb01829c 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -31,12 +31,13 @@ using Dates @test ecco_fts.grid isa LatitudeLongitudeGrid @test topology(ecco_fts.grid) == (Periodic, Bounded, Bounded) - Nx, Ny, Nz, Nt = size(ecco_fts.data) + Nx, Ny, Nz = size(interior(ecco_fts)) + Nt = length(ecco_fts.times) @test Nx == size(temperature[1])[1] @test Ny == size(temperature[1])[2] @test Nz == size(temperature[1])[3] - @test Nt == size(temperature[1])[3] + @test Nt == size(temperature[1])[4] end end From ecdad342238c8fd5a141163231dc0aad0d1dbba4 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 4 Jul 2024 13:24:37 -0400 Subject: [PATCH 611/716] fix tests --- test/test_ecco.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_ecco.jl b/test/test_ecco.jl index eb01829c..0c3d85a2 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -34,10 +34,10 @@ using Dates Nx, Ny, Nz = size(interior(ecco_fts)) Nt = length(ecco_fts.times) - @test Nx == size(temperature[1])[1] - @test Ny == size(temperature[1])[2] - @test Nz == size(temperature[1])[3] - @test Nt == size(temperature[1])[4] + @test Nx == size(temperature)[1] + @test Ny == size(temperature)[2] + @test Nz == size(temperature)[3] + @test Nt == size(temperature)[4] end end From 039214523c86bd7e9ceb5fa560c96a038de69179 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 5 Jul 2024 09:20:45 -0400 Subject: [PATCH 612/716] some fixes --- examples/generate_surface_fluxes.jl | 2 +- src/DataWrangling/ECCO.jl | 3 +++ test/test_ecco.jl | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index e97b7574..1f54ba95 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -23,7 +23,7 @@ using CairoMakie # We can use this mask as an immersed boundary for our grid. # Let's create the grid and visualize the mask. -mask = ecco_mask(:temperature) +mask = ecco_mask() grid = mask.grid grid = ImmersedBoundaryGrid(grid, GridFittedBoundary(mask)) diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index f5010ea4..6aace6dc 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -175,6 +175,9 @@ function ecco_field(metadata::ECCOMetadata; return field end +# Fallback +ecco_field(var_name::Symbol; kw...) = ecco_field(ECCOMetadata(var_name); kw...) + @kernel function _set_ecco2_mask!(mask, Tᵢ, minimum_value, maximum_value) i, j, k = @index(Global, NTuple) @inbounds mask[i, j, k] = (Tᵢ[i, j, k] < minimum_value) | (Tᵢ[i, j, k] > maximum_value) diff --git a/test/test_ecco.jl b/test/test_ecco.jl index 0c3d85a2..4eab9267 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -43,7 +43,7 @@ end @testset "setting a field with ECCO" begin for arch in test_architectures - grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (-5, 5), z = (-200, 0)) + grid = LatitudeLongitudeGrid(size = (10, 10, 10), latitude = (-60, -40), longitude = (10, 15), z = (-200, 0)) field = CenterField(grid) set!(field, ECCOMetadata(:temperature)) set!(field, ECCOMetadata(:salinity)) From 0796fab4371588086acd2e31d86ef9f1f3665c22 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 8 Jul 2024 06:42:27 -0400 Subject: [PATCH 613/716] the simulation that is running --- .../prototype_omip_simulation.jl | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/prototype_omip_simulation/prototype_omip_simulation.jl b/prototype_omip_simulation/prototype_omip_simulation.jl index 28ed9dae..90833c65 100644 --- a/prototype_omip_simulation/prototype_omip_simulation.jl +++ b/prototype_omip_simulation/prototype_omip_simulation.jl @@ -34,13 +34,13 @@ include("tripolar_specific_methods.jl") bathymetry_file = nothing # "bathymetry_tmp.jld2" # 60 vertical levels -z_faces = exponential_z_faces(Nz=20, depth=6000) +z_faces = exponential_z_faces(Nz=60, depth=6000) -Nx = 200 -Ny = 100 +Nx = 2160 +Ny = 1080 Nz = length(z_faces) - 1 -arch = CPU() #Distributed(GPU(), partition = Partition(2)) +arch = GPU() #Distributed(GPU(), partition = Partition(2)) grid = TripolarGrid(arch; size = (Nx, Ny, Nz), @@ -61,7 +61,7 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_ ##### The Ocean component ##### -free_surface = SplitExplicitFreeSurface(grid; substeps = 75) +free_surface = SplitExplicitFreeSurface(grid; cfl = 0.75, fixed_Δt = 600) ##### ##### Add restoring to ECCO fields for temperature and salinity in the artic and antarctic @@ -99,7 +99,7 @@ const c₄⁻ = c⁺[4] mask = CenterField(grid) set!(mask, mask_f) -dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 10, 1) +dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(2003, 12, 1) temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) @@ -109,15 +109,11 @@ FS = ECCO_restoring_forcing(salinity; mask, grid, architecture = arch, timesc forcing = (; T = FT, S = FS) -ocean = ocean_simulation(grid; free_surface, forcing, closure = nothing) +ocean = ocean_simulation(grid; free_surface, forcing) model = ocean.model initial_date = dates[1] -set!(model, - T = ECCOMetadata(:temperature, initial_date, ECCO2Daily()), - S = ECCOMetadata(:salinity, initial_date, ECCO2Daily())) - ##### ##### The atmosphere ##### @@ -150,7 +146,7 @@ function progress(sim) wall_time[1] = time_ns() end -ocean.callbacks[:progress] = Callback(progress, IterationInterval(1)) +ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) fluxes = (u = model.velocities.u.boundary_conditions.top.condition, v = model.velocities.v.boundary_conditions.top.condition, @@ -159,20 +155,20 @@ fluxes = (u = model.velocities.u.boundary_conditions.top.condition, ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes, schedule = TimeInterval(0.5days), - overwrite_existing = true, + overwrite_existing = false, array_type = Array{Float32}, filename = "surface_fluxes") ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), schedule = TimeInterval(0.5days), - overwrite_existing = true, + overwrite_existing = false, array_type = Array{Float32}, filename = "surface", indices = (:, :, grid.Nz)) ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities), schedule = TimeInterval(10days), - overwrite_existing = true, + overwrite_existing = false, array_type = Array{Float32}, filename = "snapshots") @@ -181,17 +177,29 @@ ocean.output_writers[:checkpoint] = Checkpointer(model, overwrite_existing = true, prefix = "checkpoint") -# Simulation warm up! +restart = nothing + +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) ocean.Δt = 10 -ocean.stop_iteration = 1 -wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 1, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -stop_time = 15days +if isnothing(restart) -coupled_simulation = Simulation(coupled_model; Δt=1, stop_time) + # Set simulation from ECCO2 fields + set!(ocean.model, + T = ECCOMetadata(:temperature, initial_date, ECCO2Daily()), + S = ECCOMetadata(:salinity, initial_date, ECCO2Daily())) + + # Simulation warm up! + wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 1.5minutes, max_change = 1.1) + ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) -run!(coupled_simulation) + stop_time = 25days + + run!(coupled_simulation) +else + # Set the ocean from the restart file + set!(ocean.model, restart) +end wizard = TimeStepWizard(; cfl = 0.3, max_Δt = 600, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) From e84613bf32b8e73628c66e2ac5e55c2b016f880c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:02:55 -0400 Subject: [PATCH 614/716] name changes --- .gitignore | 2 ++ prototype_omip_simulation/Manifest.toml | 32 ++++--------------------- src/DataWrangling/ECCO.jl | 8 +++---- src/DataWrangling/ecco_metadata.jl | 6 ++--- src/DataWrangling/ecco_restoring.jl | 8 +++---- test/test_ecco.jl | 4 ++-- 6 files changed, 19 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index 7d71b99c..a9fdf43b 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ docs/src/literated/ *.qdrep *.nsys-rep *.ncu-rep +*.sq +*.sqlite \ No newline at end of file diff --git a/prototype_omip_simulation/Manifest.toml b/prototype_omip_simulation/Manifest.toml index 585caec3..9ec3daf5 100644 --- a/prototype_omip_simulation/Manifest.toml +++ b/prototype_omip_simulation/Manifest.toml @@ -197,7 +197,7 @@ weakdeps = ["SparseArrays"] ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.ClimaOcean]] -deps = ["Adapt", "CFTime", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "FFMPEG", "ImageMorphology", "JLD2", "JSON3", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "Revise", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +deps = ["Adapt", "CFTime", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "ImageMorphology", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "Scratch", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] path = ".." uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" version = "0.2.0" @@ -216,12 +216,6 @@ git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" version = "0.1.12" -[[deps.CodeTracking]] -deps = ["InteractiveUtils", "UUIDs"] -git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386" -uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" -version = "1.3.5" - [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" @@ -715,12 +709,6 @@ git-tree-sha1 = "95220473901735a0f4df9d1ca5b171b568b2daa3" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" version = "1.13.2" -[[deps.JuliaInterpreter]] -deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] -git-tree-sha1 = "a6adc2dcfe4187c40dc7c2c9d2128e326360e90a" -uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.9.32" - [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" @@ -910,12 +898,6 @@ weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] SpecialFunctionsExt = "SpecialFunctions" -[[deps.LoweredCodeUtils]] -deps = ["JuliaInterpreter"] -git-tree-sha1 = "c6a36b22d2cca0e1a903f00f600991f97bf5f426" -uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" -version = "2.4.6" - [[deps.Lz4_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" @@ -1064,11 +1046,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 = "48e53265f2a67554497efd193ac7864385316aa7" -repo-rev = "ss/times-on-gpu" +git-tree-sha1 = "f5005c8637ebbc10dbbec3b3732cca11d39249ce" +repo-rev = "main" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.91.3" +version = "0.91.4" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -1307,12 +1289,6 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" -[[deps.Revise]] -deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"] -git-tree-sha1 = "12aa2d7593df490c407a3bbd8b86b8b515017f3e" -uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" -version = "3.5.14" - [[deps.RootSolvers]] deps = ["ForwardDiff"] git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" diff --git a/src/DataWrangling/ECCO.jl b/src/DataWrangling/ECCO.jl index 6aace6dc..7f09808f 100644 --- a/src/DataWrangling/ECCO.jl +++ b/src/DataWrangling/ECCO.jl @@ -121,7 +121,7 @@ end horizontal_halo = (1, 1), user_data = nothing, url = ecco_urls[variable_name], - filename = ecco_file_names[variable_name], + filename = ecco_metadata_filenames[variable_name], short_name = ecco_short_names[variable_name]) Retrieve the ecco field corresponding to `variable_name`. @@ -133,7 +133,7 @@ The data is either: function ecco_field(metadata::ECCOMetadata; architecture = CPU(), horizontal_halo = (3, 3), - filename = file_name(metadata)) + filename = metadata_filename(metadata)) shortname = short_name(metadata) @@ -199,7 +199,7 @@ A boolean field where `true` represents a missing value in the ECCO dataset. function ecco_mask(metadata, architecture = CPU(); minimum_value = Float32(-1e5), maximum_value = Float32(1e5), - filename = file_name(metadata)) + filename = metadata_filename(metadata)) field = ecco_field(metadata; architecture, filename) mask = Field{location(field)...}(field.grid, Bool) @@ -246,7 +246,7 @@ Keyword Arguments: """ function inpainted_ecco_field(metadata::ECCOMetadata; architecture = CPU(), - filename = file_name(metadata), + filename = metadata_filename(metadata), mask = ecco_mask(metadata, architecture), maxiter = Inf, kw...) diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index 82a2171e..654a415b 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -60,14 +60,14 @@ all_ecco_dates(::ECCO2Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month( all_ecco_dates(::ECCO2Daily) = DateTimeProlepticGregorian(1992, 1, 4) : Day(1) : DateTimeProlepticGregorian(2023, 12, 31) # File name generation specific to each Dataset version -function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) +function metadata_filename(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) shortname = short_name(metadata) yearstr = string(Dates.year(metadata.dates)) monthstr = string(Dates.month(metadata.dates), pad=2) return shortname * "_" * yearstr * "_" * monthstr * ".nc" end -function file_name(metadata::ECCOMetadata{<:AbstractCFDateTime}) +function metadata_filename(metadata::ECCOMetadata{<:AbstractCFDateTime}) shortname = short_name(metadata) yearstr = string(Dates.year(metadata.dates)) monthstr = string(Dates.month(metadata.dates), pad=2) @@ -147,7 +147,7 @@ function download_dataset!(metadata::ECCOMetadata; url = urls(metadata)) for data in metadata - filename = file_name(data) + filename = metadata_filename(data) shortname = short_name(data) if !isfile(filename) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 07fa75f7..3f063fef 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -174,14 +174,14 @@ A struct representing ECCO restoring. - `ecco_fts`: The ECCO FTS on the native ECCO grid. - `ecco_grid`: The native ECCO grid to interpolate from. - `mask`: A mask (could be a number, an array, a function or a field). -- `varname`: The variable name of the variable that needs restoring. +- `variable_name`: The variable name of the variable that needs restoring. - `λ⁻¹`: The reciprocal of the restoring timescale. """ struct ECCORestoring{FTS, G, M, V, N} <: Function ecco_fts :: FTS ecco_grid :: G mask :: M - varname :: V + variable_name :: V λ⁻¹ :: N end @@ -189,7 +189,7 @@ Adapt.adapt_structure(to, p::ECCORestoring) = ECCORestoring(Adapt.adapt(to, p.ecco_fts), Adapt.adapt(to, p.ecco_grid), Adapt.adapt(to, p.mask), - Adapt.adapt(to, p.varname), + Adapt.adapt(to, p.variable_name), Adapt.adapt(to, p.λ⁻¹)) @inline function (p::ECCORestoring)(i, j, k, grid, clock, fields) @@ -199,7 +199,7 @@ Adapt.adapt_structure(to, p::ECCORestoring) = loc = location(p.ecco_fts) # Retrieve the variable to force - @inbounds var = fields[i, j, k, p.varname] + @inbounds var = fields[i, j, k, p.variable_name] ecco_backend = p.ecco_fts.backend native_grid = on_native_grid(ecco_backend) diff --git a/test/test_ecco.jl b/test/test_ecco.jl index 4eab9267..ee59de09 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -2,7 +2,7 @@ include("runtests_setup.jl") using ClimaOcean using ClimaOcean.ECCO -using ClimaOcean.ECCO: ecco_field, file_name +using ClimaOcean.ECCO: ecco_field, metadata_filename using Oceananigans.Grids: topology using CFTime @@ -23,7 +23,7 @@ using Dates ecco_fts = t_restoring.func.ecco_fts for metadata in temperature - temperature_filename = file_name(metadata) + temperature_filename = metadata_filename(metadata) @test isfile(temperature_filename) end From 0d601f4970dbd9682ebfd184980cc8b5ae2a8d2d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:15:22 -0400 Subject: [PATCH 615/716] some changes to the simulation --- ...rranean_simulation_with_ecco_restoring.jl} | 127 +++++++++--------- 1 file changed, 65 insertions(+), 62 deletions(-) rename examples/{ecco_restoring_mediterranean.jl => mediterranean_simulation_with_ecco_restoring.jl} (53%) diff --git a/examples/ecco_restoring_mediterranean.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl similarity index 53% rename from examples/ecco_restoring_mediterranean.jl rename to examples/mediterranean_simulation_with_ecco_restoring.jl index 31ca625e..c5e37945 100644 --- a/examples/ecco_restoring_mediterranean.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -1,35 +1,48 @@ +# # Mediterranean simulation with restoring to ECCO +# +# This Julia script is a comprehensive example of setting up and running a high-resolution ocean simulation for the Mediterranean Sea using +# the Oceananigans and ClimaOcean packages, with a focus on restoring temperature and salinity fields from the +# ECCO (Estimating the Circulation and Climate of the Ocean) dataset. +# +# The script is divided into several sections, each handling a specific part of the simulation setup and execution process. +# + +# ## Initial Setup with Package Imports +# +# The script begins by importing necessary Julia packages for visualization (GLMakie), +# ocean modeling (Oceananigans, ClimaOcean), and handling of dates and times (CFTime, Dates). +# These packages provide the foundational tools for creating the simulation environment, +# including grid setup, physical processes modeling, and data visualization. + using GLMakie using Oceananigans using Oceananigans: architecture using ClimaOcean using ClimaOcean.ECCO using ClimaOcean.ECCO: ECCO4Monthly -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity -using Oceananigans.Coriolis: ActiveCellEnstrophyConserving using Oceananigans.Units using Printf using CFTime using Dates -##### -##### Regional Mediterranean grid -##### - -# Domain and Grid size +# ## Grid Configuration for the Mediterranean Sea # -# We construct a grid that represents the Mediterranean sea, -# with a resolution of 1/10th of a degree (roughly 10 km resolution) +# The script defines a high-resolution grid to represent the Mediterranean Sea, specifying the domain in terms of longitude (λ₁, λ₂), +# latitude (φ₁, φ₂), and a stretched vertical grid to capture the depth variation (z_faces). +# The grid resolution is set to approximately 1/15th of a degree, which translates to a spatial resolution of about 7 km. +# This section demonstrates the use of the LatitudeLongitudeGrid function to create a grid that matches the +# Mediterranean's geographical and bathymetric features. + λ₁, λ₂ = ( 0, 42) # domain in longitude φ₁, φ₂ = (30, 45) # domain in latitude -# A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters z_faces = stretched_vertical_faces(depth = 5000, - surface_layer_Δz = 2.5, - stretching = PowerLawStretching(1.070), - surface_layer_height = 50) + surface_layer_Δz = 2.5, + stretching = PowerLawStretching(1.070), + surface_layer_height = 50) -Nx = 4 * 42 # 1 / 4th of a degree resolution -Ny = 4 * 15 # 1 / 4th of a degree resolution +Nx = 15 * 42 # 1 / 15th of a degree resolution +Ny = 15 * 15 # 1 / 15th of a degree resolution Nz = length(z_faces) - 1 grid = LatitudeLongitudeGrid(CPU(); @@ -39,25 +52,25 @@ grid = LatitudeLongitudeGrid(CPU(); z = z_faces, halo = (7, 7, 7)) -# Interpolating the bathymetry onto the grid +# ### Bathymetry Interpolation # -# We regrid the bathymetry onto the grid. -# we allow a minimum depth of 10 meters (all shallower regions are -# considered land) and we use 25 intermediate grids (interpolation_passes = 25) -# Note that more interpolation passes will smooth the bathymetry +# The script interpolates bathymetric data onto the grid, ensuring that the model accurately represents +# the sea floor's topography. Parameters such as `minimum_depth` and `interpolation_passes` +# are adjusted to refine the bathymetry representation. + bottom_height = regrid_bathymetry(grid, height_above_water = 1, minimum_depth = 10, interpolation_passes = 25, connected_regions_allowed = 1) -# Let's use an active cell map to elide computation in inactive cells grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) -# Correct oceananigans -import Oceananigans.Advection: nothing_to_default - -nothing_to_default(user_value; default) = isnothing(user_value) ? default : user_value +# ## Downloading ECCO data +# +# The model is initialized with temperature and salinity fields from the ECCO dataset, +# using the function `ECCO_restoring_forcing` to apply restoring forcings for these tracers. +# This allows us to nudge the model towards realistic temperature and salinity profiles. dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) @@ -67,31 +80,20 @@ salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) FT = ECCO_restoring_forcing(temperature; timescale = 2days) FS = ECCO_restoring_forcing(salinity; timescale = 2days) -# Constructing the model +# Constructing the Simulation # -# We construct a model that evolves two tracers, temperature (:T), salinity (:S) -# We do not have convection since the simulation is just slumping to equilibrium so we do not need a turbulence closure -# We select a linear equation of state for buoyancy calculation, and WENO schemes for both tracer and momentum advection. -# The free surface utilizes a split-explicit formulation with a barotropic CFL of 0.75 based on wave speed. -model = HydrostaticFreeSurfaceModel(; grid, - momentum_advection = WENOVectorInvariant(), - tracer_advection = WENO(grid; order = 7), - free_surface = SplitExplicitFreeSurface(grid; cfl = 0.75), - buoyancy = SeawaterBuoyancy(), - tracers = (:T, :S, :c), - # forcing = (T = FT, S = FS), - coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) +# We construct an ocean simulation that evolves two tracers, temperature (:T), salinity (:S) +# and we pass the previously defined forcing that nudge these tracers + +ocean = ocean_simulation(grid; forcing = (T = FT, S = FS)) # Initializing the model # # the model can be initialized with custom values or with ecco fields. # In this case, our ECCO dataset has access to a temperature and a salinity # field, so we initialize T and S from ECCO. -# We initialize our passive tracer with a surface blob near to the coasts of Libia -@info "initializing model" -libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 -set!(model, c = libia_blob, T = temperature[1], S = salinity[1]) +set!(ocean.model, T = temperature[1], S = salinity[1]) fig = Figure() ax = Axis(fig[1, 1]) @@ -99,8 +101,6 @@ heatmap!(ax, interior(model.tracers.T, :, :, Nz), colorrange = (10, 20), colorma ax = Axis(fig[1, 2]) heatmap!(ax, interior(model.tracers.S, :, :, Nz), colorrange = (35, 40), colormap = :haline) -simulation = Simulation(model, Δt = 10minutes, stop_time = 10*365days) - function progress(sim) u, v, w = sim.model.velocities T, S = sim.model.tracers @@ -113,37 +113,39 @@ function progress(sim) maximum(abs, T), maximum(abs, S)) end -simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) -# Simulation warm up! +# ## Simulation warm up! # -# We have regridded from a coarse solution (1/4er of a degree) to a -# fine grid (1/15th of a degree). Also, the bathymetry has little mismatches -# that might crash our simulation. We warm up the simulation with a little -# time step for few iterations to allow the solution to adjust to the new_grid +# We have regridded from the coarse solution of the ECCO dataset (half of a degree) to a +# fine grid (1/15th of a degree). The bathymetry might also have little mismatches +# that might crash the simulation. We warm up the simulation with a little +# time step for few iterations to allow the solution to adjust to the new grid # bathymetry -simulation.Δt = 10 -simulation.stop_iteration = 1000 -run!(simulation) -# Run the real simulation +ocean.Δt = 10 +ocean.stop_iteration = 1000 +run!(ocean) + +# ## Run the real simulation # # Now that the solution has adjusted to the bathymetry we can ramp up the time # step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.2 + wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 10minutes, max_change = 1.1) -simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +coean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations -simulation.stop_iteration = Inf +ocean.stop_iteration = Inf -simulation.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); - indices = (:, :, Nz), - schedule = TimeInterval(1days), - overwrite_existing = true, - filename = "med_surface_field") +ocean.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); + indices = (:, :, Nz), + schedule = TimeInterval(1days), + overwrite_existing = true, + filename = "med_surface_field") -run!(simulation) +run!(ocean) # Record a video # @@ -152,6 +154,7 @@ run!(simulation) # (2) Meridional velocity (v) # (3) Temperature (T) # (4) Salinity (S) + u_series = FieldTimeSeries("med_surface_field.jld2", "u") v_series = FieldTimeSeries("med_surface_field.jld2", "v") T_series = FieldTimeSeries("med_surface_field.jld2", "T") From fb99d65465f764fd43279c916bb547d79220650f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:36:25 -0400 Subject: [PATCH 616/716] try it out --- .buildkite/documentation_nightly.yml | 38 ++++++++++++++++++++++++++++ .buildkite/pipeline.yml | 1 + .github/workflows/Documenter.yml | 2 +- docs/make.jl | 5 +++- docs/make_without_examples.jl | 10 +++++++- 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 .buildkite/documentation_nightly.yml diff --git a/.buildkite/documentation_nightly.yml b/.buildkite/documentation_nightly.yml new file mode 100644 index 00000000..cabb2b92 --- /dev/null +++ b/.buildkite/documentation_nightly.yml @@ -0,0 +1,38 @@ +agents: + queue: new-central + slurm_mem: 8G + modules: climacommon/2024_05_27 + +env: + JULIA_LOAD_PATH: "${JULIA_LOAD_PATH}:${BUILDKITE_BUILD_CHECKOUT_PATH}/.buildkite" + OPENBLAS_NUM_THREADS: 1 + OMPI_MCA_opal_warn_on_missing_libcuda: 0 + +steps: + - label: "initialize" + key: "init" + command: + - "echo '--- Instantiate project'" + - "julia --project -e 'using Pkg; Pkg.instantiate(; verbose=true); Pkg.precompile(; strict=true)'" + # force the initialization of the CUDA runtime as it is lazily loaded by default + - "julia --project -e 'using CUDA; CUDA.precompile_runtime()'" + + agents: + slurm_mem: 32G + slurm_gpus: 1 + slurm_cpus_per_task: 8 + env: + JULIA_NUM_PRECOMPILE_TASKS: 8 + + - wait + + - label: "Run documentation" + key: "Build documentation" + env: + CUDA_VISIBLE_DEVICES: "0" + commands: + - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" + - "julia --color=yes --project=docs/ docs/make.jl" + + - wait: ~ + continue_on_failure: true diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index bc7ab6fa..9c265599 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -19,6 +19,7 @@ steps: agents: slurm_mem: 32G + slurm_gpus: 1 slurm_cpus_per_task: 8 env: JULIA_NUM_PRECOMPILE_TASKS: 8 diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 4f48b2b1..95ea069f 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -33,4 +33,4 @@ jobs: JULIA_DEBUG: Documenter ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} # To download ECCO data from the podaac website ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} # To download ECCO data from the podaac website - run: julia --color=yes --project=docs/ docs/make.jl + run: julia --color=yes --project=docs/ docs/make_without_examples.jl diff --git a/docs/make.jl b/docs/make.jl index bc5ed089..e6384b26 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -18,7 +18,8 @@ to_be_literated = [ "inspect_ecco_data.jl", "generate_surface_fluxes.jl", "single_column_simulation.jl", - # "near_global_omip_simulation.jl" + "mediterranean_simulation_with_ecco_restoring.jl", + "near_global_omip_simulation.jl" ] for file in to_be_literated @@ -50,6 +51,8 @@ pages = [ "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", "Surface fluxes" => "literated/generate_surface_fluxes.md", "Single column simulation" => "literated/single_column_simulation.md", + "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", + "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", ] ] diff --git a/docs/make_without_examples.jl b/docs/make_without_examples.jl index 9724e318..a75ebf5f 100644 --- a/docs/make_without_examples.jl +++ b/docs/make_without_examples.jl @@ -15,7 +15,9 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - "inspect_ecco2_data.jl", + "inspect_ecco_data.jl", + "generate_surface_fluxes.jl", + "single_column_simulation.jl", ] for file in to_be_literated @@ -42,6 +44,12 @@ pages = [ "Private" => "library/internals.md", "Function index" => "library/function_index.md", ], + + "Examples" => [ + "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + "Surface fluxes" => "literated/generate_surface_fluxes.md", + "Single column simulation" => "literated/single_column_simulation.md", + ] ] makedocs( From 7dec068e535e4df165a84c561820425af76c1423 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 10:22:00 -0400 Subject: [PATCH 617/716] test documentation on GPU --- docs/make_without_examples.jl | 24 ------------------------ examples/near_global_omip_simulation.jl | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/docs/make_without_examples.jl b/docs/make_without_examples.jl index a75ebf5f..a550d989 100644 --- a/docs/make_without_examples.jl +++ b/docs/make_without_examples.jl @@ -7,24 +7,6 @@ using ENV["DATADEPS_ALWAYS_ACCEPT"] = "true" -##### -##### Generate examples -##### - -const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") -const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") - -to_be_literated = [ - "inspect_ecco_data.jl", - "generate_surface_fluxes.jl", - "single_column_simulation.jl", -] - -for file in to_be_literated - filepath = joinpath(EXAMPLES_DIR, file) - Literate.markdown(filepath, OUTPUT_DIR; flavor = Literate.DocumenterFlavor()) -end - ##### ##### Build and deploy docs ##### @@ -44,12 +26,6 @@ pages = [ "Private" => "library/internals.md", "Function index" => "library/function_index.md", ], - - "Examples" => [ - "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - "Surface fluxes" => "literated/generate_surface_fluxes.md", - "Single column simulation" => "literated/single_column_simulation.md", - ] ] makedocs( diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index eca17321..4925f941 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -15,6 +15,7 @@ using Dates ##### # 40 vertical levels + z_faces = exponential_z_faces(Nz=40, depth=6000) Nx = 1440 @@ -35,6 +36,7 @@ grid = LatitudeLongitudeGrid(arch; # We retrieve the bathymetry from the ETOPO1 data by ensuring a # minimum depth of 10 meters (everyhting shallower is considered land) # and removing all connected regions (inland lakes) + bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, dir = "./", @@ -42,6 +44,7 @@ bottom_height = retrieve_bathymetry(grid; connected_regions_allowed = 0) # An immersed boundary using a staircase representation of bathymetry + grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) ##### @@ -56,6 +59,7 @@ date = DateTimeProlepticGregorian(1993, 1, 1) # We interpolate the initial conditions from the ECCO2 dataset # (for the moment these are both 1st January 1993) + set!(model, T = ECCO2Metadata(:temperature, date, ECCO2Daily()), S = ECCO2Metadata(:salinity, date, ECCO2Daily())) @@ -66,11 +70,13 @@ set!(model, # The whole prescribed atmosphere is loaded in memory # 4 snapshots at the time. + backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) # Tabulated ocean albedo from Payne (1982) # ocean emissivity is the default 0.97 + radiation = Radiation(arch) ##### @@ -79,9 +85,11 @@ radiation = Radiation(arch) # Simplistic sea ice that ensure "no-cooling-fluxes" where `T < T_minimum` # to change with a thermodynamic sea-ice model + sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() # The complete coupled model + coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) wall_time = [time_ns()] @@ -89,6 +97,7 @@ wall_time = [time_ns()] # We define a progress function that # shows the maximum values of velocity and temperature # to make sure everything proceedes as planned + function progress(sim) u, v, w = sim.model.velocities T = sim.model.tracers.T @@ -119,6 +128,7 @@ output_kwargs = (; overwrite_existing = true, array_type = Array{Float32}) # We add a couple of outputs: the surface state every 12 hours, the surface fluxes # every 12 hours, and the whole state every ten days + ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; schedule = TimeInterval(0.5days), overwrite_existing = true, @@ -148,12 +158,14 @@ ocean.output_writers[:checkpoint] = Checkpointer(model; # warm up the simulation to ensure that the model adapts # to the interpolated initial conditions without crashing + ocean.Δt = 10 ocean.stop_iteration = 1 wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) # Finally, the coupled simulation! + coupled_simulation = Simulation(coupled_model; Δt=1, stop_time = 20days) run!(coupled_simulation) @@ -193,3 +205,9 @@ heatmap!(ax, interior(T, :, :, grid.Nz), colorrange = (-1, 30), colormap = :magm ax = Axis(fig[2, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") heatmap!(ax, interior(e, :, :, grid.Nz), colorrange = (0, 1e-3), colormap = :solar) + +save("near_global_ocean_surface.png", fig) +nothing #hide + +# ![](near_global_ocean_surface.png) + From d4d9c2f94c664033e2ba077cbb1f7f1b5c515db7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 10:48:29 -0400 Subject: [PATCH 618/716] correct docs key --- .buildkite/documentation_nightly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/documentation_nightly.yml b/.buildkite/documentation_nightly.yml index cabb2b92..e7aecfaf 100644 --- a/.buildkite/documentation_nightly.yml +++ b/.buildkite/documentation_nightly.yml @@ -18,7 +18,7 @@ steps: - "julia --project -e 'using CUDA; CUDA.precompile_runtime()'" agents: - slurm_mem: 32G + slurm_mem: 80G slurm_gpus: 1 slurm_cpus_per_task: 8 env: @@ -27,7 +27,7 @@ steps: - wait - label: "Run documentation" - key: "Build documentation" + key: "build_documentation" env: CUDA_VISIBLE_DEVICES: "0" commands: From b09c83530757cd7749f114eaf1a9d8ab15397106 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:10:02 -0400 Subject: [PATCH 619/716] timeout the docs after 24 hours instead of the default 2 --- .buildkite/documentation_nightly.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.buildkite/documentation_nightly.yml b/.buildkite/documentation_nightly.yml index e7aecfaf..e8c2403e 100644 --- a/.buildkite/documentation_nightly.yml +++ b/.buildkite/documentation_nightly.yml @@ -8,6 +8,8 @@ env: OPENBLAS_NUM_THREADS: 1 OMPI_MCA_opal_warn_on_missing_libcuda: 0 +timeout_in_minutes: 1440 + steps: - label: "initialize" key: "init" From 34137215e84a0d0beb5026b089221f9440413e67 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:11:32 -0400 Subject: [PATCH 620/716] med example on the GPU --- examples/mediterranean_simulation_with_ecco_restoring.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/mediterranean_simulation_with_ecco_restoring.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl index c5e37945..d3217576 100644 --- a/examples/mediterranean_simulation_with_ecco_restoring.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -45,7 +45,7 @@ Nx = 15 * 42 # 1 / 15th of a degree resolution Ny = 15 * 15 # 1 / 15th of a degree resolution Nz = length(z_faces) - 1 -grid = LatitudeLongitudeGrid(CPU(); +grid = LatitudeLongitudeGrid(GPU(); size = (Nx, Ny, Nz), latitude = (φ₁, φ₂), longitude = (λ₁, λ₂), @@ -138,6 +138,7 @@ coean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations ocean.stop_iteration = Inf +ocean.stop_time = 200days ocean.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); indices = (:, :, Nz), From 841e48792cd78323cc90b7e055fb11ab7f6a96b9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:53:44 -0400 Subject: [PATCH 621/716] update Oceananigans --- docs/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Project.toml b/docs/Project.toml index d7cbe6e6..7331d2d9 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" +Oceananigans = "0.91.4" From 13cc2f86e5c40baefe35f0ee1d784fb44888f1b2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:55:52 -0400 Subject: [PATCH 622/716] namechange to pipeline --- .buildkite/{documentation_nightly.yml => run_examples.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .buildkite/{documentation_nightly.yml => run_examples.yml} (100%) diff --git a/.buildkite/documentation_nightly.yml b/.buildkite/run_examples.yml similarity index 100% rename from .buildkite/documentation_nightly.yml rename to .buildkite/run_examples.yml From ddbe363425ff51931b8c70771e471e277f724d6b Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:58:58 -0400 Subject: [PATCH 623/716] rename the examples build --- .buildkite/{run_examples.yml => examples_build.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .buildkite/{run_examples.yml => examples_build.yml} (100%) diff --git a/.buildkite/run_examples.yml b/.buildkite/examples_build.yml similarity index 100% rename from .buildkite/run_examples.yml rename to .buildkite/examples_build.yml From 5ef6fa7e0b53ba4f6169ef82f0658e29e19d6bf2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:14:41 -0400 Subject: [PATCH 624/716] remove size threshold --- docs/make.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index e6384b26..d9c8bdcb 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -32,9 +32,10 @@ end ##### format = Documenter.HTML( - collapselevel = 2, - prettyurls = get(ENV, "CI", nothing) == "true", - canonical = "https://clima.github.io/ClimaOceanDocumentation/dev/", + collapselevel = 2, + size_threshold = nothing, + prettyurls = get(ENV, "CI", nothing) == "true", + canonical = "https://clima.github.io/ClimaOceanDocumentation/dev/", ) pages = [ From 68bc957f96f4048d1cd6359ee81a8cfb81a48802 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 17:17:57 -0400 Subject: [PATCH 625/716] GLMakie -> CairoMakie --- examples/freely_decaying_mediterranean.jl | 4 ++-- examples/generate_bathymetry.jl | 2 +- examples/inspect_JRA55_data.jl | 2 +- examples/mediterranean_simulation_with_ecco_restoring.jl | 6 +++--- experiments/freely_decaying_regional_simulation.jl | 2 +- .../inspect_one_degree_near_global_simulation.jl | 2 +- experiments/plot_freely_decaying_simulation.jl | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl index 2a05e79b..90b1664a 100644 --- a/examples/freely_decaying_mediterranean.jl +++ b/examples/freely_decaying_mediterranean.jl @@ -1,4 +1,4 @@ -using GLMakie +using CairoMakie using Oceananigans using Oceananigans: architecture using ClimaOcean @@ -183,7 +183,7 @@ heatmap!(S) ax = Axis(fig[2, 3], title = "passive tracer -") heatmap!(c) -GLMakie.record(fig, "mediterranean_video.mp4", 1:length(u_series.times); framerate = 5) do i +CairoMakie.record(fig, "mediterranean_video.mp4", 1:length(u_series.times); framerate = 5) do i @info "recording iteration $i" iter[] = i end \ No newline at end of file diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 4db9c54b..f98ac860 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -1,4 +1,4 @@ -using GLMakie +using CairoMakie using Oceananigans using ClimaOcean.Bathymetry: regrid_bathymetry diff --git a/examples/inspect_JRA55_data.jl b/examples/inspect_JRA55_data.jl index 37403da3..23445799 100644 --- a/examples/inspect_JRA55_data.jl +++ b/examples/inspect_JRA55_data.jl @@ -1,5 +1,5 @@ using ClimaOcean -using GLMakie +using CairoMakie using Oceananigans using Oceananigans.Units using Printf diff --git a/examples/mediterranean_simulation_with_ecco_restoring.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl index d3217576..526213c2 100644 --- a/examples/mediterranean_simulation_with_ecco_restoring.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -9,12 +9,12 @@ # ## Initial Setup with Package Imports # -# The script begins by importing necessary Julia packages for visualization (GLMakie), +# The script begins by importing necessary Julia packages for visualization (CairoMakie), # ocean modeling (Oceananigans, ClimaOcean), and handling of dates and times (CFTime, Dates). # These packages provide the foundational tools for creating the simulation environment, # including grid setup, physical processes modeling, and data visualization. -using GLMakie +using CairoMakie using Oceananigans using Oceananigans: architecture using ClimaOcean @@ -201,7 +201,7 @@ heatmap!(S) ax = Axis(fig[2, 3], title = "passive tracer -") heatmap!(c) -GLMakie.record(fig, "mediterranean_video.mp4", 1:length(u_series.times); framerate = 5) do i +CairoMakie.record(fig, "mediterranean_video.mp4", 1:length(u_series.times); framerate = 5) do i @info "recording iteration $i" iter[] = i end \ No newline at end of file diff --git a/experiments/freely_decaying_regional_simulation.jl b/experiments/freely_decaying_regional_simulation.jl index 6130064e..fb22ead0 100644 --- a/experiments/freely_decaying_regional_simulation.jl +++ b/experiments/freely_decaying_regional_simulation.jl @@ -9,7 +9,7 @@ using ClimaOcean.OceanSeaIceModels: Radiation using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere using ClimaOcean.DataWrangling.ECCO: ecco_field -# using GLMakie +# using CairoMakie using Printf using Dates 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 13654f4e..092d5399 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 @@ -2,7 +2,7 @@ using Oceananigans using Oceananigans.BuoyancyModels: ∂z_b, buoyancy_perturbation using SeawaterPolynomials.TEOS10: TEOS10EquationOfState using JLD2 -using GLMakie +using CairoMakie using Printf dir = "../data" #/storage1/greg" diff --git a/experiments/plot_freely_decaying_simulation.jl b/experiments/plot_freely_decaying_simulation.jl index 9238a70f..935035c8 100644 --- a/experiments/plot_freely_decaying_simulation.jl +++ b/experiments/plot_freely_decaying_simulation.jl @@ -1,4 +1,4 @@ -using GLMakie +using CairoMakie using Oceananigans using JLD2 From 03c90389bf0821ace4fe4ee0bb74f80ad52f81ac Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:23:57 -0400 Subject: [PATCH 626/716] add GPUs --- .buildkite/examples_build.yml | 13 ++++++++++--- .gitignore | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index e8c2403e..c4c67433 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -20,7 +20,7 @@ steps: - "julia --project -e 'using CUDA; CUDA.precompile_runtime()'" agents: - slurm_mem: 80G + slurm_mem: 120G slurm_gpus: 1 slurm_cpus_per_task: 8 env: @@ -30,11 +30,18 @@ steps: - label: "Run documentation" key: "build_documentation" - env: - CUDA_VISIBLE_DEVICES: "0" commands: - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" - "julia --color=yes --project=docs/ docs/make.jl" + agents: + slurm_mem: 120G + slurm_gpus: 1 + slurm_cpus_per_task: 8 + slurm_ntasks: 1 + slurm_gpus_per_task: 1 + env: + JULIA_NUM_PRECOMPILE_TASKS: 8 + - wait: ~ continue_on_failure: true diff --git a/.gitignore b/.gitignore index a9fdf43b..b7bcfef8 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ deps/src/ docs/build/ docs/site/ docs/src/literated/ +docs/Manifest.toml # Output files *.nc From 97c6661012acd8793bdde40f7db3f8e2ce466b54 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 20:48:42 -0400 Subject: [PATCH 627/716] yet another bugfix --- examples/mediterranean_simulation_with_ecco_restoring.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/mediterranean_simulation_with_ecco_restoring.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl index 526213c2..3f7eec70 100644 --- a/examples/mediterranean_simulation_with_ecco_restoring.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -77,8 +77,8 @@ dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGre temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) -FT = ECCO_restoring_forcing(temperature; timescale = 2days) -FS = ECCO_restoring_forcing(salinity; timescale = 2days) +FT = ECCO_restoring_forcing(temperature; architecture = arch, timescale = 2days) +FS = ECCO_restoring_forcing(salinity; architecture = arch, timescale = 2days) # Constructing the Simulation # From 6406bbcae5ad7e117b843070078f3f897ac8603d Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Wed, 24 Jul 2024 21:44:24 -0400 Subject: [PATCH 628/716] yet another bugfix --- examples/mediterranean_simulation_with_ecco_restoring.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/mediterranean_simulation_with_ecco_restoring.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl index 3f7eec70..e5f790ef 100644 --- a/examples/mediterranean_simulation_with_ecco_restoring.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -77,8 +77,8 @@ dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGre temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) -FT = ECCO_restoring_forcing(temperature; architecture = arch, timescale = 2days) -FS = ECCO_restoring_forcing(salinity; architecture = arch, timescale = 2days) +FT = ECCO_restoring_forcing(temperature; architecture = GPU(), timescale = 2days) +FS = ECCO_restoring_forcing(salinity; architecture = GPU(), timescale = 2days) # Constructing the Simulation # From 2a9d613ae96273aac19d975576da117329fffd4c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 06:51:23 -0400 Subject: [PATCH 629/716] test on Oceananigans#main --- Manifest.toml | 151 +++++++++++++++++++++----------------------------- 1 file changed, 64 insertions(+), 87 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 5ba3dd0f..aba8f91e 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.4" manifest_format = "2.0" -project_hash = "086b5c52c3f2a61f133762647db63128f8714c56" +project_hash = "2d55e37361bb1470f75342d3cff1fb1d8891fe98" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -17,9 +17,9 @@ weakdeps = ["ChainRulesCore", "Test"] [[deps.Accessors]] deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] -git-tree-sha1 = "c0d491ef0b135fd7d63cbc6404286bc633329425" +git-tree-sha1 = "f61b15be1d76846c0ce31d3fcfac5380ae53db6a" uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.36" +version = "0.1.37" [deps.Accessors.extensions] AccessorsAxisKeysExt = "AxisKeys" @@ -52,9 +52,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "ed2ec3c9b483842ae59cd273834e5b46206d6dda" +git-tree-sha1 = "5c9b74c973181571deb6442d41e5c902e6b9f38e" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.11.0" +version = "7.12.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -138,9 +138,9 @@ version = "0.2.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", "StaticArrays", "Statistics"] -git-tree-sha1 = "6e945e876652f2003e6ca74e19a3c45017d3e9f6" +git-tree-sha1 = "fdd9dfb67dfefd548f51000cc400bb51003de247" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.4.2" +version = "5.4.3" [deps.CUDA.extensions] ChainRulesCoreExt = "ChainRulesCore" @@ -154,9 +154,9 @@ version = "5.4.2" [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "c48f9da18efd43b6b7adb7ee1f93fe5f2926c339" +git-tree-sha1 = "97df9d4d6be8ac6270cb8fd3b8fc413690820cbd" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.9.0+0" +version = "0.9.1+1" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] @@ -166,9 +166,9 @@ version = "0.3.4" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "bcba305388e16aa5c879e896726db9e71b4942c6" +git-tree-sha1 = "afea94249b821dc754a8ca6695d3daed851e1f5a" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.14.0+1" +version = "0.14.1+0" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] @@ -192,12 +192,6 @@ git-tree-sha1 = "05ba0d07cd4fd8b7a39541e31a7b0254704ea581" uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" version = "0.1.13" -[[deps.CodeTracking]] -deps = ["InteractiveUtils", "UUIDs"] -git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386" -uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" -version = "1.3.5" - [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] git-tree-sha1 = "b8fe8546d52ca154ac556809e10c75e6e7430ac8" @@ -261,7 +255,7 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.5+1" +version = "1.1.1+0" [[deps.CompositionsBase]] git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" @@ -274,15 +268,15 @@ weakdeps = ["InverseFunctions"] [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" +git-tree-sha1 = "ea32b83ca4fefa1768dc84e504cc0a94fb1ab8d1" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.4.1" +version = "2.4.2" [[deps.ConstructionBase]] deps = ["LinearAlgebra"] -git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +git-tree-sha1 = "d8a9c0b6ac2d9081bf76324b39c78ca3ce4f0c98" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.5" +version = "1.5.6" [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" @@ -455,9 +449,9 @@ version = "6.2.1+6" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "5c9de6d5af87acd2cf719e214ed7d51e14017b7a" +git-tree-sha1 = "a74c3f1cf56a3dfcdef0605f8cdb7015926aae30" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "10.2.2" +version = "10.3.0" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -466,10 +460,10 @@ uuid = "46192b85-c4d5-4398-a991-12ede77f4527" version = "0.1.6" [[deps.GPUCompiler]] -deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Scratch", "TimerOutputs", "UUIDs"] -git-tree-sha1 = "518ebd058c9895de468a8c255797b0c53fdb44dd" +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Preferences", "Scratch", "Serialization", "TOML", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "ab29216184312f99ff957b32cd63c2fe9c928b91" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.26.5" +version = "0.26.7" [[deps.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" @@ -502,9 +496,9 @@ version = "0.1.17" [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1d334207121865ac8c1c97eb7f42d0339e4635bf" +git-tree-sha1 = "5e19e1e4fa3e71b774ce746274364aef0234634e" uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.11.0+0" +version = "2.11.1+0" [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" @@ -530,22 +524,23 @@ uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" version = "0.2.1" [[deps.InlineStrings]] -deps = ["Parsers"] -git-tree-sha1 = "86356004f30f8e737eff143d57d41bd580e437aa" +git-tree-sha1 = "45521d31238e87ee9f9732561bfee12d4eebd52d" uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.1" +version = "1.4.2" [deps.InlineStrings.extensions] ArrowTypesExt = "ArrowTypes" + ParsersExt = "Parsers" [deps.InlineStrings.weakdeps] ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "be50fe8df3acbffa0274a744f1a99d29c45a57f4" +git-tree-sha1 = "14eb2b542e748570b56446f4c50fbfb2306ebc45" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.1.0+0" +version = "2024.2.0+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -553,9 +548,9 @@ uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[deps.InverseFunctions]] deps = ["Test"] -git-tree-sha1 = "e7cbed5032c4c397a6ac23d1493f3289e01231c4" +git-tree-sha1 = "18c59411ece4838b18cd7f537e56cf5e41ce5bfd" uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.14" +version = "0.1.15" weakdeps = ["Dates"] [deps.InverseFunctions.extensions] @@ -584,9 +579,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "Pkg", "PrecompileTools", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] -git-tree-sha1 = "bdbe8222d2f5703ad6a7019277d149ec6d78c301" +git-tree-sha1 = "5fe858cb863e211c6dedc8cce2dc0752d4ab6e2b" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.48" +version = "0.4.50" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -606,12 +601,6 @@ version = "1.14.0" [deps.JSON3.weakdeps] ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" -[[deps.JuliaInterpreter]] -deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] -git-tree-sha1 = "e9648d90370e2d0317f9518c9c6e0841db54a90b" -uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.9.31" - [[deps.JuliaNVTXCallbacks_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" @@ -632,9 +621,9 @@ version = "0.9.22" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "389aea28d882a40b5e1747069af71bdbd47a1cae" +git-tree-sha1 = "020abd49586480c1be84f57da0017b5d3db73f7c" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "7.2.1" +version = "8.0.0" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -642,9 +631,9 @@ weakdeps = ["BFloat16s"] [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "88b916503aac4fb7f701bb625cd84ca5dd1677bc" +git-tree-sha1 = "c2636c264861edc6d305e6b4d528f09566d24c5e" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.29+0" +version = "0.0.30+0" [[deps.LLVMLoopInfo]] git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" @@ -754,12 +743,6 @@ weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] SpecialFunctionsExt = "SpecialFunctions" -[[deps.LoweredCodeUtils]] -deps = ["JuliaInterpreter"] -git-tree-sha1 = "c6a36b22d2cca0e1a903f00f600991f97bf5f426" -uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" -version = "2.4.6" - [[deps.Lz4_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" @@ -768,9 +751,9 @@ version = "1.9.4+0" [[deps.MKL_jll]] deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] -git-tree-sha1 = "80b2833b56d466b3858d565adcd16a4a05f2089b" +git-tree-sha1 = "f046ccd0c6db2832a9f639e2c669c6fe867e5f4f" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.1.0+0" +version = "2024.2.0+0" [[deps.MPI]] deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] @@ -788,9 +771,9 @@ version = "0.20.16" [[deps.MPICH_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "4099bb6809ac109bfc17d521dad33763bcf026b7" +git-tree-sha1 = "19d4bd098928a3263693991500d05d74dbdc2004" uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.2.1+1" +version = "4.2.2+0" [[deps.MPIPreferences]] deps = ["Libdl", "Preferences"] @@ -902,9 +885,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 = "745b1c19221e09886cae331450a2a4ea73708a38" +git-tree-sha1 = "942c78ad3c95e47bcbab3eeacb0b8a846bcfb33b" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.91.3" +version = "0.91.4" [deps.Oceananigans.extensions] OceananigansEnzymeExt = "Enzyme" @@ -913,9 +896,9 @@ version = "0.91.3" Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" [[deps.OffsetArrays]] -git-tree-sha1 = "e64b4f5ea6b7389f6f046d13d4896a8f9c1ba71e" +git-tree-sha1 = "1a27764e945a152f7ca7efa04de513d473e9542e" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.14.0" +version = "1.14.1" weakdeps = ["Adapt"] [deps.OffsetArrays.extensions] @@ -924,7 +907,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"] @@ -933,9 +916,9 @@ version = "0.8.1+2" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] -git-tree-sha1 = "a9de2f1fc98b92f8856c640bf4aec1ac9b2a0d86" +git-tree-sha1 = "2f0a1d8c79bc385ec3fcda12830c9d0e72b30e71" uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.3+0" +version = "5.0.4+0" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] @@ -1106,12 +1089,6 @@ git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" version = "1.3.0" -[[deps.Revise]] -deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"] -git-tree-sha1 = "12aa2d7593df490c407a3bbd8b86b8b515017f3e" -uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" -version = "3.5.14" - [[deps.RootSolvers]] deps = ["ForwardDiff"] git-tree-sha1 = "a87fd671f7a298de98f2f3c5a9cd9890714eb9dd" @@ -1120,9 +1097,9 @@ version = "0.4.2" [[deps.Roots]] deps = ["Accessors", "ChainRulesCore", "CommonSolve", "Printf"] -git-tree-sha1 = "1ab580704784260ee5f45bffac810b152922747b" +git-tree-sha1 = "3484138c9fa4296a0cf46a74ca3f97b59d12b1d0" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.1.5" +version = "2.1.6" [deps.Roots.extensions] RootsForwardDiffExt = "ForwardDiff" @@ -1174,9 +1151,9 @@ version = "0.3.4" [[deps.SentinelArrays]] deps = ["Dates", "Random"] -git-tree-sha1 = "90b4f68892337554d31cdcdbe19e48989f26c7e6" +git-tree-sha1 = "ff11acffdb082493657550959d4feb4b6149e73a" uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.3" +version = "1.4.5" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -1218,9 +1195,9 @@ version = "0.1.1" [[deps.Static]] deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] -git-tree-sha1 = "0bbff21027dd8a107551847528127b62a35f7594" +git-tree-sha1 = "87d51a3ee9a4b0d2fe054bdd3fc2436258db2603" uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.1.0" +version = "1.1.1" [[deps.StaticArrayInterface]] deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] @@ -1235,9 +1212,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "20833c5b7f7edf0e5026f23db7f268e4f23ec577" +git-tree-sha1 = "eeafab08ae20c62c44c8399ccb9354a04b80db50" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.6" +version = "1.9.7" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -1339,10 +1316,10 @@ uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" version = "1.0.1" [[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.1" +version = "1.12.0" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -1373,9 +1350,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "deac04ad36638b10fde82470d5f128419f627e9a" +git-tree-sha1 = "80b13ddc5ae7b8605ef5a055e7f23c5b5f4775cf" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.12.6" +version = "0.12.7" [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" @@ -1402,9 +1379,9 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.24" [[deps.TranscodingStreams]] -git-tree-sha1 = "d73336d81cafdc277ff45558bb7eaa2b04a8e472" +git-tree-sha1 = "96612ac5365777520c3c5396314c8cf7408f436a" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.10" +version = "0.11.1" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] From 00b55711d0dcec0488a79a68f9742d91e31d6e82 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 06:56:05 -0400 Subject: [PATCH 630/716] test on Oceananigans#main --- .gitignore | 1 - docs/Manifest.toml | 2284 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2284 insertions(+), 1 deletion(-) create mode 100644 docs/Manifest.toml diff --git a/.gitignore b/.gitignore index b7bcfef8..a9fdf43b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,6 @@ deps/src/ docs/build/ docs/site/ docs/src/literated/ -docs/Manifest.toml # Output files *.nc diff --git a/docs/Manifest.toml b/docs/Manifest.toml new file mode 100644 index 00000000..b3a44c64 --- /dev/null +++ b/docs/Manifest.toml @@ -0,0 +1,2284 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.4" +manifest_format = "2.0" +project_hash = "eb12d5bbef057241b99255438a09412ef57e1d2c" + +[[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.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[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 = "5c9b74c973181571deb6442d41e5c902e6b9f38e" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.12.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = "CUDSS" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "0.1.0" + +[[deps.Automa]] +deps = ["PrecompileTools", "TranscodingStreams"] +git-tree-sha1 = "014bc22d6c400a7703c0f5dc1fdc302440cf88be" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "1.0.4" + +[[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 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[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 = "fdd9dfb67dfefd548f51000cc400bb51003de247" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.4.3" + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + EnzymeCoreExt = "EnzymeCore" + SpecialFunctionsExt = "SpecialFunctions" + + [deps.CUDA.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "97df9d4d6be8ac6270cb8fd3b8fc413690820cbd" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.9.1+1" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "f3b237289a5a77c759b2dd5d4c2ff641d67c4030" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.3.4" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "afea94249b821dc754a8ca6695d3daed851e1f5a" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.14.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 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+2" + +[[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 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.24.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "b8fe8546d52ca154ac556809e10c75e6e7430ac8" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.5" + +[[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 = "b5278586822443594ff615963b0c09755771b3e0" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.26.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.5" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.11" + +[[deps.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 = "d6fb5bf939a2753c74984b11434ea25d6c397a58" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.6" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.CommonWorldInvalidations]] +git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" +uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" +version = "1.0.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.15.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.1+0" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "ea32b83ca4fefa1768dc84e504cc0a94fb1ab8d1" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.4.2" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d8a9c0b6ac2d9081bf76324b39c78ca3ce4f0c98" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.6" +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 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.20" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.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 = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "9c405847cc7ecda2dc921ccf18b47ca150d7317e" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.109" + + [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 = "76deb8c15f37a3853f13ea2226b8f2577652de05" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "1.5.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 = "1c6317308b9dc757616f0b5cb379db10494443a7" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.6.2+0" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.Extents]] +git-tree-sha1 = "94997910aca72897524d2237c41eb852153b0f65" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.3" + +[[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 = "0653c0a2396a6da5bc4766c43041ef5fd3efbe57" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.11.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 = "2de436b72c3422940cbe1367611d137008af7ec3" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.23.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 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.96+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 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.2+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "2493cdfd0740015955a8e46de4ef28f49460d8bc" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.3" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.14+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 = "a74c3f1cf56a3dfcdef0605f8cdb7015926aae30" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "10.3.0" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Preferences", "Scratch", "Serialization", "TOML", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "ab29216184312f99ff957b32cd63c2fe9c928b91" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.26.7" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "9fff8990361d5127b770e3454488360443019bb3" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.5" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "b62f2b2d76cee0d61a2ef2b3118cd2a3215d3134" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.11" + +[[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 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.2+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 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.8" + +[[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 = "5e19e1e4fa3e71b774ce746274364aef0234634e" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.11.1+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 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.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 = "437abb322a41d527c197fa800455f79d414f0a3c" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.8" + +[[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 = "0936ba688c6d201805a83da835b55c61a180db52" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.11+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 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.InlineStrings]] +git-tree-sha1 = "45521d31238e87ee9f9732561bfee12d4eebd52d" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.2" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + ParsersExt = "Parsers" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" + +[[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 = "14eb2b542e748570b56446f4c50fbfb2306ebc45" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.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 = "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", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] +git-tree-sha1 = "5fe858cb863e211c6dedc8cce2dc0752d4ab6e2b" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.50" + +[[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 = "c84a835e1a09b289ffcd2271bf2a337bbdda6637" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.3+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 = "d0448cebd5919e06ca5edc7a264631790de810ec" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.22" + + [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 = "7d703202e65efa1369de1279c162b915e245eed1" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.9" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.2+0" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] +git-tree-sha1 = "020abd49586480c1be84f57da0017b5d3db73f7c" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "8.0.0" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "c2636c264861edc6d305e6b4d528f09566d24c5e" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.30+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"] +git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.2+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"] +git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.11+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.49.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 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.40.1+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.40.1+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 = "eef2e1fc1dc38af90a18eb16e519e06d1fd10c2a" +uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" +version = "2.19.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.28" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.0.3" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.9.4+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "f046ccd0c6db2832a9f639e2c669c6fe867e5f4f" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.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", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "19d4bd098928a3263693991500d05d74dbdc2004" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.2.2+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.11" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "8c35d5420193841b2f367e658540e8d9e0601ed0" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.4.0+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.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 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.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 = "a640912695952b074672edb5f9aaee2f7f9fd59a" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.4" + +[[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 = "937a5ba25152cbcd0b74e66d21ce931a620a6cc4" +repo-rev = "main" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.91.4" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "1a27764e945a152f7ca7efa04de513d473e9542e" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.14.1" +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 = "8292dd5c8a38257111ada2174000a33745b06d4e" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.2.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", "TOML", "Zlib_jll"] +git-tree-sha1 = "2f0a1d8c79bc385ec3fcda12830c9d0e72b30e71" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.4+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.3" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.14+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.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.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 = "cb5a2ab6763464ae0f19c86c56c63d4a2b0f5bda" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.52.2+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 = "fa85ac32172d96cfdb91dbc53e8e57007e5a2b5a" +uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" +version = "0.19.5" + + [deps.PencilArrays.extensions] + PencilArraysAMDGPUExt = ["AMDGPU"] + PencilArraysDiffEqExt = ["DiffEqBase"] + PencilArraysHDF5Ext = ["HDF5"] + + [deps.PencilArrays.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" + HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" + +[[deps.PencilFFTs]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" +uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" +version = "0.15.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "4ca430561cf37c75964c8478eddae2d79e96ca9b" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.21" + +[[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 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.43.4+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", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "1a9cfb2dc2c2f1bd63f1906d72af39a79b49b736" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.11" + + [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 = "66b20dd35966a748321d3b2537c4584cf40387c7" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.2" + +[[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 = "8f6bc219586aef8baf0ff9a5fe16ee9c70cb65e4" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.10.2" + +[[deps.PtrArrays]] +git-tree-sha1 = "f011fbb92c4d401059b2212c05c0601b70f8b759" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.2.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"] +git-tree-sha1 = "d483cd324ce5cf5d61b77930f0bbd6cb61927d21" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.2+0" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.1" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.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.SIMD]] +deps = ["PrecompileTools"] +git-tree-sha1 = "2803cab51702db743f3fda07dd1745aadfbf43bd" +uuid = "fdea26ae-647d-5447-a871-4b548cad5224" +version = "3.5.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 = "ff11acffdb082493657550959d4feb4b6149e73a" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.5" + +[[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 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.4.0" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableHashTraits]] +deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "a58e0d86783226378a6857f2de26d3314107e3ac" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.2.0" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] +git-tree-sha1 = "87d51a3ee9a4b0d2fe054bdd3fc2436258db2603" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.1.1" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "8963e5a083c837531298fc41599182a759a87a6d" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.5.1" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "eeafab08ae20c62c44c8399ccb9354a04b80db50" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.7" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.StaticPermutations]] +git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" +uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" +version = "0.3.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.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 = "bd9bd1c70cfc115cc3a30213fc725125a6b43652" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "2.1.0" + +[[deps.StridedViews]] +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "2917996ce0fa6b8a3a85240a5e9ff930e2aeaa43" +uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" +version = "0.3.1" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.18" +weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = "GPUArraysCore" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.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", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.12.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 = "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", "SIMD", "UUIDs"] +git-tree-sha1 = "bc7fd5c91041f44636b2c134041f7e5263ce58ae" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.10.0" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "5a13ae8a41237cff5ecf34f73eb1b8f42fff6531" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.24" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "96612ac5365777520c3c5396314c8cf7408f436a" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.1" +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 = "bf2c553f25e954a9b38c9c0593a59bb13113f9e5" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.5" + +[[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 = "d9717ce3518dc68a99e6b96300813760d887a01d" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.13.1+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "a54ee957f4c86b526460a720dbc882fa5edcbefc" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.41+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", "Xorg_libX11_jll"] +git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.6+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.11+0" + +[[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 = "bcd466676fef0878338c61e655629fa7bbc69d8e" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.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"] +git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.9.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 = "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 = "490376214c4721cdaca654041f635213c6165cb3" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+2" + +[[deps.libzip_jll]] +deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "3282b7d16ae7ac3e57ec2f3fa8fafb564d8f9f7f" +uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" +version = "1.10.1+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2021.12.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[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 a8da3c7a10a4db9d335f3383d7c9bc71ae0e2be0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 07:17:27 -0400 Subject: [PATCH 631/716] instantiate first --- .buildkite/examples_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index c4c67433..0c4dc8f7 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -31,7 +31,7 @@ steps: - label: "Run documentation" key: "build_documentation" commands: - - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" + - "julia --color=yes --project=docs/ -e 'using Pkg; Pkg.instantiate(); Pkg.develop(PackageSpec(path=pwd()))'" - "julia --color=yes --project=docs/ docs/make.jl" agents: From f1d6dc98e42ee46ec0df1da220a3a4d2c3b73f9a Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 08:09:43 -0400 Subject: [PATCH 632/716] Oceananigans#main --- Manifest.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index aba8f91e..65a8c4e0 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -885,7 +885,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 = "942c78ad3c95e47bcbab3eeacb0b8a846bcfb33b" +git-tree-sha1 = "937a5ba25152cbcd0b74e66d21ce931a620a6cc4" +repo-rev = "main" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.91.4" From 2e7d15b060f7ad0fc1e2dac017879af5d437d229 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:49:51 -0400 Subject: [PATCH 633/716] smooth out a couple of bugs --- examples/freely_decaying_mediterranean.jl | 189 ------------------ ...erranean_simulation_with_ecco_restoring.jl | 7 +- examples/near_global_omip_simulation.jl | 4 +- 3 files changed, 4 insertions(+), 196 deletions(-) delete mode 100644 examples/freely_decaying_mediterranean.jl diff --git a/examples/freely_decaying_mediterranean.jl b/examples/freely_decaying_mediterranean.jl deleted file mode 100644 index 90b1664a..00000000 --- a/examples/freely_decaying_mediterranean.jl +++ /dev/null @@ -1,189 +0,0 @@ -using CairoMakie -using Oceananigans -using Oceananigans: architecture -using ClimaOcean -using ClimaOcean.ECCO -using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: CATKEVerticalDiffusivity -using Oceananigans.Coriolis: ActiveCellEnstrophyConserving -using Oceananigans.Units -using Printf - -##### -##### Regional Mediterranean grid -##### - -# Domain and Grid size -# -# We construct a grid that represents the Mediterranean sea, -# with a resolution of 1/10th of a degree (roughly 10 km resolution) -λ₁, λ₂ = ( 0, 42) # domain in longitude -φ₁, φ₂ = (30, 45) # domain in latitude -# A stretched vertical grid with a Δz of 1.5 meters in the first 50 meters -z_faces = stretched_vertical_faces(depth = 5000, - surface_layer_Δz = 2.5, - stretching = PowerLawStretching(1.070), - surface_layer_height = 50) - -Nx = 15 * 42 # 1 / 15th of a degree resolution -Ny = 15 * 15 # 1 / 15th of a degree resolution -Nz = length(z_faces) - 1 - -grid = LatitudeLongitudeGrid(CPU(); - size = (Nx, Ny, Nz), - latitude = (φ₁, φ₂), - longitude = (λ₁, λ₂), - z = z_faces, - halo = (7, 7, 7)) - -# Interpolating the bathymetry onto the grid -# -# We regrid the bathymetry onto the grid. -# we allow a minimum depth of 10 meters (all shallower regions are -# considered land) and we use 25 intermediate grids (interpolation_passes = 25) -# Note that more interpolation passes will smooth the bathymetry -bottom_height = regrid_bathymetry(grid, - height_above_water = 1, - minimum_depth = 10, - interpolation_passes = 25) - -# Let's use an active cell map to elide computation in inactive cells -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) - -# Correct oceananigans -import Oceananigans.Advection: nothing_to_default - -nothing_to_default(user_value; default) = isnothing(user_value) ? default : user_value - -# Constructing the model -# -# We construct a model that evolves two tracers, temperature (:T), salinity (:S) -# We do not have convection since the simulation is just slumping to equilibrium so we do not need a turbulence closure -# We select a linear equation of state for buoyancy calculation, and WENO schemes for both tracer and momentum advection. -# The free surface utilizes a split-explicit formulation with a barotropic CFL of 0.75 based on wave speed. -model = HydrostaticFreeSurfaceModel(; grid, - momentum_advection = WENOVectorInvariant(), - tracer_advection = WENO(grid; order = 7), - free_surface = SplitExplicitFreeSurface(; cfl = 0.75, grid), - buoyancy = SeawaterBuoyancy(), - tracers = (:T, :S, :c), - coriolis = HydrostaticSphericalCoriolis(scheme = ActiveCellEnstrophyConserving())) - -# Initializing the model -# -# the model can be initialized with custom values or with ecco fields. -# In this case, our ECCO dataset has access to a temperature and a salinity -# field, so we initialize T and S from ECCO. -# We initialize our passive tracer with a surface blob near to the coasts of Libia -@info "initializing model" -libia_blob(x, y, z) = z > -20 || (x - 15)^2 + (y - 34)^2 < 1.5 ? 1 : 0 - -set!(model, T = ECCOMetadata(:temperature), S = ECCOMetadata(:salinity), c = libia_blob) - -fig = Figure() -ax = Axis(fig[1, 1]) -heatmap!(ax, interior(model.tracers.T, :, :, Nz), colorrange = (10, 20), colormap = :thermal) -ax = Axis(fig[1, 2]) -heatmap!(ax, interior(model.tracers.S, :, :, Nz), colorrange = (35, 40), colormap = :haline) - -simulation = Simulation(model, Δt = 10minutes, stop_time = 10*365days) - -function progress(sim) - u, v, w = sim.model.velocities - T, S = sim.model.tracers - - @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(T, S): %.2f, %.2f\n", - prettytime(sim.model.clock.time), - sim.model.clock.iteration, - prettytime(sim.Δt), - maximum(abs, u), maximum(abs, v), maximum(abs, w), - maximum(abs, T), maximum(abs, S)) -end - -simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) - -# Simulation warm up! -# -# We have regridded from a coarse solution (1/4er of a degree) to a -# fine grid (1/15th of a degree). Also, the bathymetry has little mismatches -# that might crash our simulation. We warm up the simulation with a little -# time step for few iterations to allow the solution to adjust to the new_grid -# bathymetry -simulation.Δt = 10 -simulation.stop_iteration = 1000 -run!(simulation) - -# Run the real simulation -# -# Now that the solution has adjusted to the bathymetry we can ramp up the time -# step size. We use a `TimeStepWizard` to automatically adapt to a cfl of 0.2 -wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 10minutes, max_change = 1.1) - -simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) - -# Let's reset the maximum number of iterations -simulation.stop_iteration = Inf - -simulation.output_writers[:surface_fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers); - indices = (:, :, Nz), - schedule = TimeInterval(1day), - overwrite_existing = true, - filename = "med_surface_field") - -run!(simulation) - -# Record a video -# -# Let's read the data and record a video of the Mediterranean Sea's surface -# (1) Zonal velocity (u) -# (2) Meridional velocity (v) -# (3) Temperature (T) -# (4) Salinity (S) -u_series = FieldTimeSeries("med_surface_field.jld2", "u") -v_series = FieldTimeSeries("med_surface_field.jld2", "v") -T_series = FieldTimeSeries("med_surface_field.jld2", "T") -S_series = FieldTimeSeries("med_surface_field.jld2", "S") -c_series = FieldTimeSeries("med_surface_field.jld2", "c") -iter = Observable(1) - -u = @lift begin - f = interior(u_series[$iter], :, :, 1) - f[f .== 0] .= NaN - f -end -v = @lift begin - f = interior(v_series[$iter], :, :, 1) - f[f .== 0] .= NaN - f -end -T = @lift begin - f = interior(T_series[$iter], :, :, 1) - f[f .== 0] .= NaN - f -end -S = @lift begin - f = interior(S_series[$iter], :, :, 1) - f[f .== 0] .= NaN - f -end -c = @lift begin - f = interior(c_series[$iter], :, :, 1) - f[f .== 0] .= NaN - f -end - -fig = Figure() -ax = Axis(fig[1, 1], title = "surface zonal velocity ms⁻¹") -heatmap!(u) -ax = Axis(fig[1, 2], title = "surface meridional velocity ms⁻¹") -heatmap!(v) -ax = Axis(fig[2, 1], title = "surface temperature ᵒC") -heatmap!(T) -ax = Axis(fig[2, 2], title = "surface salinity psu") -heatmap!(S) -ax = Axis(fig[2, 3], title = "passive tracer -") -heatmap!(c) - -CairoMakie.record(fig, "mediterranean_video.mp4", 1:length(u_series.times); framerate = 5) do i - @info "recording iteration $i" - iter[] = i -end \ No newline at end of file diff --git a/examples/mediterranean_simulation_with_ecco_restoring.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl index e5f790ef..5ff30d45 100644 --- a/examples/mediterranean_simulation_with_ecco_restoring.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -75,17 +75,14 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_ dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) -salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) - FT = ECCO_restoring_forcing(temperature; architecture = GPU(), timescale = 2days) -FS = ECCO_restoring_forcing(salinity; architecture = GPU(), timescale = 2days) # Constructing the Simulation # # We construct an ocean simulation that evolves two tracers, temperature (:T), salinity (:S) # and we pass the previously defined forcing that nudge these tracers -ocean = ocean_simulation(grid; forcing = (T = FT, S = FS)) +ocean = ocean_simulation(grid; forcing = (; T = FT)) # Initializing the model # @@ -134,7 +131,7 @@ run!(ocean) wizard = TimeStepWizard(; cfl = 0.2, max_Δt = 10minutes, max_change = 1.1) -coean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) # Let's reset the maximum number of iterations ocean.stop_iteration = Inf diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 4925f941..4287a8ec 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -61,8 +61,8 @@ date = DateTimeProlepticGregorian(1993, 1, 1) # (for the moment these are both 1st January 1993) set!(model, - T = ECCO2Metadata(:temperature, date, ECCO2Daily()), - S = ECCO2Metadata(:salinity, date, ECCO2Daily())) + T = ECCOMetadata(:temperature, date, ECCO2Daily()), + S = ECCOMetadata(:salinity, date, ECCO2Daily())) ##### ##### The atmosphere From 565f4b3518ffa1dea98f8fe069cf24376cbb1a29 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 11:03:51 -0400 Subject: [PATCH 634/716] remove Oceananigans from docs Project.toml --- Manifest.toml | 4 - docs/Manifest.toml | 2284 ----------------------- docs/Project.toml | 2 - examples/near_global_omip_simulation.jl | 6 +- 4 files changed, 1 insertion(+), 2295 deletions(-) delete mode 100644 docs/Manifest.toml diff --git a/Manifest.toml b/Manifest.toml index 68879497..65a8c4e0 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -885,13 +885,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"] -<<<<<<< HEAD git-tree-sha1 = "937a5ba25152cbcd0b74e66d21ce931a620a6cc4" repo-rev = "main" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" -======= -git-tree-sha1 = "942c78ad3c95e47bcbab3eeacb0b8a846bcfb33b" ->>>>>>> origin/main uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.91.4" diff --git a/docs/Manifest.toml b/docs/Manifest.toml deleted file mode 100644 index b3a44c64..00000000 --- a/docs/Manifest.toml +++ /dev/null @@ -1,2284 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.4" -manifest_format = "2.0" -project_hash = "eb12d5bbef057241b99255438a09412ef57e1d2c" - -[[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.AliasTables]] -deps = ["PtrArrays", "Random"] -git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" -uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" -version = "1.1.3" - -[[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 = "5c9b74c973181571deb6442d41e5c902e6b9f38e" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.12.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = "CUDSS" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" - -[[deps.Atomix]] -deps = ["UnsafeAtomics"] -git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" -uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" -version = "0.1.0" - -[[deps.Automa]] -deps = ["PrecompileTools", "TranscodingStreams"] -git-tree-sha1 = "014bc22d6c400a7703c0f5dc1fdc302440cf88be" -uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "1.0.4" - -[[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 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.9" - -[[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 = "fdd9dfb67dfefd548f51000cc400bb51003de247" -uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.4.3" - - [deps.CUDA.extensions] - ChainRulesCoreExt = "ChainRulesCore" - EnzymeCoreExt = "EnzymeCore" - SpecialFunctionsExt = "SpecialFunctions" - - [deps.CUDA.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.CUDA_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "97df9d4d6be8ac6270cb8fd3b8fc413690820cbd" -uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.9.1+1" - -[[deps.CUDA_Runtime_Discovery]] -deps = ["Libdl"] -git-tree-sha1 = "f3b237289a5a77c759b2dd5d4c2ff641d67c4030" -uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.3.4" - -[[deps.CUDA_Runtime_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "afea94249b821dc754a8ca6695d3daed851e1f5a" -uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.14.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 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" -uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.0+2" - -[[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 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.24.0" -weakdeps = ["SparseArrays"] - - [deps.ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "b8fe8546d52ca154ac556809e10c75e6e7430ac8" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.5" - -[[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 = "b5278586822443594ff615963b0c09755771b3e0" -uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.26.0" - -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.5" - -[[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.10.0" -weakdeps = ["SpecialFunctions"] - - [deps.ColorVectorSpace.extensions] - SpecialFunctionsExt = "SpecialFunctions" - -[[deps.Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.11" - -[[deps.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 = "d6fb5bf939a2753c74984b11434ea25d6c397a58" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.6" - -[[deps.CommonSubexpressions]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.0" - -[[deps.CommonWorldInvalidations]] -git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" -uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" -version = "1.0.0" - -[[deps.Compat]] -deps = ["TOML", "UUIDs"] -git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.15.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.1+0" - -[[deps.ConcurrentUtilities]] -deps = ["Serialization", "Sockets"] -git-tree-sha1 = "ea32b83ca4fefa1768dc84e504cc0a94fb1ab8d1" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.4.2" - -[[deps.ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d8a9c0b6ac2d9081bf76324b39c78ca3ce4f0c98" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.6" -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 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.20" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.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 = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "9c405847cc7ecda2dc921ccf18b47ca150d7317e" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.109" - - [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 = "76deb8c15f37a3853f13ea2226b8f2577652de05" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.5.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 = "1c6317308b9dc757616f0b5cb379db10494443a7" -uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.6.2+0" - -[[deps.ExprTools]] -git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" -uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.10" - -[[deps.Extents]] -git-tree-sha1 = "94997910aca72897524d2237c41eb852153b0f65" -uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.3" - -[[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 = "0653c0a2396a6da5bc4766c43041ef5fd3efbe57" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.11.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 = "2de436b72c3422940cbe1367611d137008af7ec3" -uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.23.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 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" - -[[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] -git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" -uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.96+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 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" -uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.2+0" - -[[deps.FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] -git-tree-sha1 = "2493cdfd0740015955a8e46de4ef28f49460d8bc" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.3" - -[[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" -uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.14+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 = "a74c3f1cf56a3dfcdef0605f8cdb7015926aae30" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "10.3.0" - -[[deps.GPUArraysCore]] -deps = ["Adapt"] -git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" -uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.1.6" - -[[deps.GPUCompiler]] -deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Preferences", "Scratch", "Serialization", "TOML", "TimerOutputs", "UUIDs"] -git-tree-sha1 = "ab29216184312f99ff957b32cd63c2fe9c928b91" -uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.26.7" - -[[deps.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "9fff8990361d5127b770e3454488360443019bb3" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.5" - -[[deps.GeometryBasics]] -deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "b62f2b2d76cee0d61a2ef2b3118cd2a3215d3134" -uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.4.11" - -[[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 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" -uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.2+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 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.8" - -[[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 = "5e19e1e4fa3e71b774ce746274364aef0234634e" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.11.1+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 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" -uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.5" - -[[deps.IfElse]] -git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" -uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" -version = "0.1.1" - -[[deps.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 = "437abb322a41d527c197fa800455f79d414f0a3c" -uuid = "82e4d734-157c-48bb-816b-45c225c6df19" -version = "0.6.8" - -[[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 = "0936ba688c6d201805a83da835b55c61a180db52" -uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" -version = "3.1.11+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 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.5" - -[[deps.InlineStrings]] -git-tree-sha1 = "45521d31238e87ee9f9732561bfee12d4eebd52d" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.2" - - [deps.InlineStrings.extensions] - ArrowTypesExt = "ArrowTypes" - ParsersExt = "Parsers" - - [deps.InlineStrings.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" - -[[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 = "14eb2b542e748570b56446f4c50fbfb2306ebc45" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.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 = "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", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] -git-tree-sha1 = "5fe858cb863e211c6dedc8cce2dc0752d4ab6e2b" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.50" - -[[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 = "c84a835e1a09b289ffcd2271bf2a337bbdda6637" -uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.0.3+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 = "d0448cebd5919e06ca5edc7a264631790de810ec" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.22" - - [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 = "7d703202e65efa1369de1279c162b915e245eed1" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.9" - -[[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" -uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.2+0" - -[[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "020abd49586480c1be84f57da0017b5d3db73f7c" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "8.0.0" -weakdeps = ["BFloat16s"] - - [deps.LLVM.extensions] - BFloat16sExt = "BFloat16s" - -[[deps.LLVMExtra_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "c2636c264861edc6d305e6b4d528f09566d24c5e" -uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.30+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"] -git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" -uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.2+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"] -git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" -uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.11+0" - -[[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" -uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.49.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 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" -uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.40.1+0" - -[[deps.Libuuid_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" -uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.40.1+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 = "eef2e1fc1dc38af90a18eb16e519e06d1fd10c2a" -uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -version = "2.19.0" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.28" - - [deps.LogExpFunctions.extensions] - LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" - LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" - LogExpFunctionsInverseFunctionsExt = "InverseFunctions" - - [deps.LogExpFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - -[[deps.Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[deps.LoggingExtras]] -deps = ["Dates", "Logging"] -git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" -uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.0.3" - -[[deps.Lz4_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6c26c5e8a4203d43b5497be3ec5d4e0c3cde240a" -uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" -version = "1.9.4+0" - -[[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] -git-tree-sha1 = "f046ccd0c6db2832a9f639e2c669c6fe867e5f4f" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.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", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "19d4bd098928a3263693991500d05d74dbdc2004" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.2.2+0" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.11" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "8c35d5420193841b2f367e658540e8d9e0601ed0" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.4.0+0" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.13" - -[[deps.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 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.2.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 = "a640912695952b074672edb5f9aaee2f7f9fd59a" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.4" - -[[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 = "937a5ba25152cbcd0b74e66d21ce931a620a6cc4" -repo-rev = "main" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" -uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.91.4" - - [deps.Oceananigans.extensions] - OceananigansEnzymeExt = "Enzyme" - - [deps.Oceananigans.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - -[[deps.OffsetArrays]] -git-tree-sha1 = "1a27764e945a152f7ca7efa04de513d473e9542e" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.14.1" -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 = "8292dd5c8a38257111ada2174000a33745b06d4e" -uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.2.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", "TOML", "Zlib_jll"] -git-tree-sha1 = "2f0a1d8c79bc385ec3fcda12830c9d0e72b30e71" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.4+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.3" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.14+0" - -[[deps.OpenSpecFun_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" -uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" -version = "0.5.5+0" - -[[deps.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.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 = "cb5a2ab6763464ae0f19c86c56c63d4a2b0f5bda" -uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.52.2+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 = "fa85ac32172d96cfdb91dbc53e8e57007e5a2b5a" -uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.5" - - [deps.PencilArrays.extensions] - PencilArraysAMDGPUExt = ["AMDGPU"] - PencilArraysDiffEqExt = ["DiffEqBase"] - PencilArraysHDF5Ext = ["HDF5"] - - [deps.PencilArrays.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" - HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" - -[[deps.PencilFFTs]] -deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] -git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" -uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" -version = "0.15.1" - -[[deps.Permutations]] -deps = ["Combinatorics", "LinearAlgebra", "Random"] -git-tree-sha1 = "4ca430561cf37c75964c8478eddae2d79e96ca9b" -uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" -version = "0.4.21" - -[[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 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" -uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.43.4+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", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "1a9cfb2dc2c2f1bd63f1906d72af39a79b49b736" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "4.0.11" - - [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 = "66b20dd35966a748321d3b2537c4584cf40387c7" -uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.3.2" - -[[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 = "8f6bc219586aef8baf0ff9a5fe16ee9c70cb65e4" -uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.10.2" - -[[deps.PtrArrays]] -git-tree-sha1 = "f011fbb92c4d401059b2212c05c0601b70f8b759" -uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" -version = "1.2.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"] -git-tree-sha1 = "d483cd324ce5cf5d61b77930f0bbd6cb61927d21" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.2+0" - -[[deps.Rotations]] -deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.1" -weakdeps = ["RecipesBase"] - - [deps.Rotations.extensions] - RotationsRecipesBaseExt = "RecipesBase" - -[[deps.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.SIMD]] -deps = ["PrecompileTools"] -git-tree-sha1 = "2803cab51702db743f3fda07dd1745aadfbf43bd" -uuid = "fdea26ae-647d-5447-a871-4b548cad5224" -version = "3.5.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 = "ff11acffdb082493657550959d4feb4b6149e73a" -uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.5" - -[[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 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.4.0" -weakdeps = ["ChainRulesCore"] - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - -[[deps.StableHashTraits]] -deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] -git-tree-sha1 = "a58e0d86783226378a6857f2de26d3314107e3ac" -uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" -version = "1.2.0" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.1" - -[[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] -git-tree-sha1 = "87d51a3ee9a4b0d2fe054bdd3fc2436258db2603" -uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.1.1" - -[[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] -git-tree-sha1 = "8963e5a083c837531298fc41599182a759a87a6d" -uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.5.1" -weakdeps = ["OffsetArrays", "StaticArrays"] - - [deps.StaticArrayInterface.extensions] - StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" - StaticArrayInterfaceStaticArraysExt = "StaticArrays" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "eeafab08ae20c62c44c8399ccb9354a04b80db50" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.7" -weakdeps = ["ChainRulesCore", "Statistics"] - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.3" - -[[deps.StaticPermutations]] -git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" -uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" -version = "0.3.0" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.0" - -[[deps.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 = "bd9bd1c70cfc115cc3a30213fc725125a6b43652" -uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" -version = "2.1.0" - -[[deps.StridedViews]] -deps = ["LinearAlgebra", "PackageExtensionCompat"] -git-tree-sha1 = "2917996ce0fa6b8a3a85240a5e9ff930e2aeaa43" -uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" -version = "0.3.1" -weakdeps = ["CUDA"] - - [deps.StridedViews.extensions] - StridedViewsCUDAExt = "CUDA" - -[[deps.StringManipulation]] -deps = ["PrecompileTools"] -git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" -uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.3.4" - -[[deps.StructArrays]] -deps = ["ConstructionBase", "DataAPI", "Tables"] -git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.18" -weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] - - [deps.StructArrays.extensions] - StructArraysAdaptExt = "Adapt" - StructArraysGPUArraysCoreExt = "GPUArraysCore" - StructArraysSparseArraysExt = "SparseArrays" - StructArraysStaticArraysExt = "StaticArrays" - -[[deps.StructTypes]] -deps = ["Dates", "UUIDs"] -git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" -uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" -version = "1.10.0" - -[[deps.SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" - -[[deps.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", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.12.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 = "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", "SIMD", "UUIDs"] -git-tree-sha1 = "bc7fd5c91041f44636b2c134041f7e5263ce58ae" -uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.10.0" - -[[deps.TimerOutputs]] -deps = ["ExprTools", "Printf"] -git-tree-sha1 = "5a13ae8a41237cff5ecf34f73eb1b8f42fff6531" -uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" -version = "0.5.24" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "96612ac5365777520c3c5396314c8cf7408f436a" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.11.1" -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 = "bf2c553f25e954a9b38c9c0593a59bb13113f9e5" -uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" -version = "0.1.5" - -[[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 = "d9717ce3518dc68a99e6b96300813760d887a01d" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.1+0" - -[[deps.XSLT_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "XML2_jll", "Zlib_jll"] -git-tree-sha1 = "a54ee957f4c86b526460a720dbc882fa5edcbefc" -uuid = "aed1982a-8fda-507f-9586-7b0439959a61" -version = "1.1.41+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", "Xorg_libX11_jll"] -git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" -uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.6+0" - -[[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" -uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.11+0" - -[[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 = "bcd466676fef0878338c61e655629fa7bbc69d8e" -uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.17.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"] -git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" -uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.9.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 = "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 = "490376214c4721cdaca654041f635213c6165cb3" -uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.7+2" - -[[deps.libzip_jll]] -deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "3282b7d16ae7ac3e57ec2f3fa8fafb564d8f9f7f" -uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" -version = "1.10.1+0" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" - -[[deps.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2021.12.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" - -[[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 7331d2d9..08ab7c7a 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -3,10 +3,8 @@ CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" [compat] CairoMakie = "0.10.12" DataDeps = "0.7" Documenter = "1" -Oceananigans = "0.91.4" diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 2beab806..27d3635d 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -44,10 +44,6 @@ bottom_height = retrieve_bathymetry(grid; connected_regions_allowed = 0) # An immersed boundary using a staircase representation of bathymetry -<<<<<<< HEAD - -======= ->>>>>>> origin/main grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) ##### @@ -66,7 +62,7 @@ date = DateTimeProlepticGregorian(1993, 1, 1) set!(model, T = ECCOMetadata(:temperature, date, ECCO2Daily()), S = ECCOMetadata(:salinity, date, ECCO2Daily())) - + ##### ##### The atmosphere ##### From 051e59004af6528d5414c6497d1a6675f5b7afed Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 14:51:39 -0400 Subject: [PATCH 635/716] fix gpu problem --- examples/mediterranean_simulation_with_ecco_restoring.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/mediterranean_simulation_with_ecco_restoring.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl index a794a424..f7dfec62 100644 --- a/examples/mediterranean_simulation_with_ecco_restoring.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -77,8 +77,8 @@ dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGre temperature = ECCOMetadata(:temperature, dates, ECCO4Monthly()) salinity = ECCOMetadata(:salinity, dates, ECCO4Monthly()) -FT = ECCO_restoring_forcing(temperature; timescale = 2days) -FS = ECCO_restoring_forcing(salinity; timescale = 2days) +FT = ECCO_restoring_forcing(temperature; architecture = GPU(), timescale = 2days) +FS = ECCO_restoring_forcing(salinity; architecture = GPU(), timescale = 2days) # Constructing the Simulation # From f2a741d24838d806a6735dce4952974fd145ca83 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 16:17:34 -0400 Subject: [PATCH 636/716] try only the near global at the moment --- docs/make.jl | 4 ++-- ...terranean_simulation_with_ecco_restoring.jl | 2 +- examples/near_global_omip_simulation.jl | 2 +- src/DataWrangling/JRA55.jl | 2 +- src/DataWrangling/ecco_restoring.jl | 10 +++++----- .../CrossRealmFluxes/CrossRealmFluxes.jl | 18 ++++++++++++++++++ .../atmosphere_ocean_fluxes.jl | 4 ++-- src/OceanSeaIceModels/OceanSeaIceModels.jl | 2 ++ 8 files changed, 32 insertions(+), 12 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index d9c8bdcb..8fc713bf 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -18,7 +18,7 @@ to_be_literated = [ "inspect_ecco_data.jl", "generate_surface_fluxes.jl", "single_column_simulation.jl", - "mediterranean_simulation_with_ecco_restoring.jl", + # "mediterranean_simulation_with_ecco_restoring.jl", "near_global_omip_simulation.jl" ] @@ -52,7 +52,7 @@ pages = [ "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", "Surface fluxes" => "literated/generate_surface_fluxes.md", "Single column simulation" => "literated/single_column_simulation.md", - "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", + # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", ] ] diff --git a/examples/mediterranean_simulation_with_ecco_restoring.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl index f7dfec62..6a33fb3c 100644 --- a/examples/mediterranean_simulation_with_ecco_restoring.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -64,7 +64,7 @@ bottom_height = regrid_bathymetry(grid, interpolation_passes = 25, connected_regions_allowed = 1) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) # ## Downloading ECCO data # diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 27d3635d..4a5708da 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -44,7 +44,7 @@ bottom_height = retrieve_bathymetry(grid; connected_regions_allowed = 0) # An immersed boundary using a staircase representation of bathymetry -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) ##### ##### The Ocean component diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index a7427ec7..e2149523 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -599,7 +599,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); backend = nothing, time_indexing = Cyclical(), reference_height = 10, # meters - include_rivers_and_icebergs = true, # rivers and icebergs are not needed in single column simulations + include_rivers_and_icebergs = false, # rivers and icebergs are not needed in single column simulations other_kw...) if isnothing(backend) # apply a default diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 3f063fef..b214db30 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -178,11 +178,11 @@ A struct representing ECCO restoring. - `λ⁻¹`: The reciprocal of the restoring timescale. """ struct ECCORestoring{FTS, G, M, V, N} <: Function - ecco_fts :: FTS - ecco_grid :: G - mask :: M - variable_name :: V - λ⁻¹ :: N + ecco_fts :: FTS + ecco_grid :: G + mask :: M + variable_name :: V + λ⁻¹ :: N end Adapt.adapt_structure(to, p::ECCORestoring) = diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl index 885898e5..6c479bae 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/CrossRealmFluxes.jl @@ -10,6 +10,8 @@ export Radiation, using ..OceanSeaIceModels: default_gravitational_acceleration import ..OceanSeaIceModels: surface_velocities, + surface_horizontal_velocities, + surface_active_tracers, surface_tracers import ClimaOcean: stateindex @@ -27,6 +29,14 @@ function surface_flux(f::Field) end end +function surface_horizontal_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) + return (; u, v) +end + function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) grid = ocean.model.grid Nz = size(grid, 3) @@ -36,6 +46,14 @@ function surface_velocities(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) return (; u, v, w) end +function surface_active_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + grid = ocean.model.grid + Nz = size(grid, 3) + T = view(ocean.model.tracers.T.data, :, :, Nz) + S = view(ocean.model.tracers.S.data, :, :, Nz) + return (; T, S) +end + function surface_tracers(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) grid = ocean.model.grid Nz = size(grid, 3) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl index 682b5f90..36f51782 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/atmosphere_ocean_fluxes.jl @@ -18,8 +18,8 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) clock = coupled_model.clock # Ocean, atmosphere, and sea ice state - ocean_velocities = surface_velocities(ocean) - ocean_tracers = surface_tracers(ocean) + ocean_velocities = surface_horizontal_velocities(ocean) + ocean_tracers = surface_active_tracers(ocean) # Fluxes, and flux contributors centered_velocity_fluxes = (u = coupled_model.fluxes.total.ocean.momentum.uᶜᶜᶜ, diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 7764faa2..a30c5b52 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -24,6 +24,8 @@ using KernelAbstractions.Extras.LoopInfo: @unroll function surface_velocities end function surface_tracers end +function surface_horizontal_velocities end +function surface_active_tracers end function downwelling_radiation end function freshwater_flux end function reference_density end From 57c2ca9a76b58eebdc0d0f4d9df458ebd52fd2d6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 16:21:06 -0400 Subject: [PATCH 637/716] remove reaive humidity --- src/DataWrangling/JRA55.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index e2149523..aa3a6edd 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -600,6 +600,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); time_indexing = Cyclical(), reference_height = 10, # meters include_rivers_and_icebergs = false, # rivers and icebergs are not needed in single column simulations + include_relative_humidity = false, other_kw...) if isnothing(backend) # apply a default @@ -621,13 +622,14 @@ 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...) Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) + include_relative_humidity && ra = JRA55_field_time_series(:relative_humidity; kw...) + freshwater_flux = (rain = Fra, snow = Fsn) @@ -648,9 +650,9 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); v = va) tracers = (T = Ta, - q = qa, - r = ra) + q = qa) + tracers = include_relative_humidity ? merge(tracers, (; r = ra)) : tracers pressure = pa From af4649a8cbcbe3d3cb9ee5880d0c90fb6a400d75 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 16:32:49 -0400 Subject: [PATCH 638/716] remove reative humidity cause not used --- src/DataWrangling/JRA55.jl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index aa3a6edd..a29048a6 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -600,7 +600,6 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); time_indexing = Cyclical(), reference_height = 10, # meters include_rivers_and_icebergs = false, # rivers and icebergs are not needed in single column simulations - include_relative_humidity = false, other_kw...) if isnothing(backend) # apply a default @@ -627,8 +626,6 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); 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...) - - include_relative_humidity && ra = JRA55_field_time_series(:relative_humidity; kw...) freshwater_flux = (rain = Fra, snow = Fsn) @@ -651,8 +648,6 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); tracers = (T = Ta, q = qa) - - tracers = include_relative_humidity ? merge(tracers, (; r = ra)) : tracers pressure = pa From 74d48c08d5f5d7bdd34534e9538c2f4ba83dd13f Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:24:46 -0400 Subject: [PATCH 639/716] bugfix --- examples/near_global_omip_simulation.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 4a5708da..f7173733 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -23,7 +23,7 @@ Ny = 600 Nz = length(z_faces) - 1 # Running on a GPU -arch = GPU() +arch = CPU() # A near-global grid from 75ᵒ S to 75ᵒ N grid = LatitudeLongitudeGrid(arch; @@ -165,7 +165,7 @@ ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) # Finally, the coupled simulation! -coupled_simulation = Simulation(coupled_model; Δt=1, stop_time = 20days) +coupled_simulation = Simulation(coupled_model; Δt=1, stop_iteration = 1) #stop_time = 20days) run!(coupled_simulation) @@ -178,7 +178,7 @@ using CairoMakie u, v, w = model.velocities T, S, e = model.tracers -using Oceananigans.Models.HydrostaticFreeSurfaceModel: VerticalVorticityField +using Oceananigans.Models.HydrostaticFreeSurfaceModels: VerticalVorticityField ζ = VerticalVorticityField(model) s = Field(sqrt(u^2 + v^2)) From 91dcf9d547dede11d538ecce51421970225f41a7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:02:26 -0400 Subject: [PATCH 640/716] just check the near global configuration --- docs/make.jl | 12 ++++++------ examples/near_global_omip_simulation.jl | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 8fc713bf..10344e76 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,9 +15,9 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - "inspect_ecco_data.jl", - "generate_surface_fluxes.jl", - "single_column_simulation.jl", + # "inspect_ecco_data.jl", + # "generate_surface_fluxes.jl", + # "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", "near_global_omip_simulation.jl" ] @@ -49,9 +49,9 @@ pages = [ ], "Examples" => [ - "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - "Surface fluxes" => "literated/generate_surface_fluxes.md", - "Single column simulation" => "literated/single_column_simulation.md", + # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + # "Surface fluxes" => "literated/generate_surface_fluxes.md", + # "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", ] diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index f7173733..77f9047a 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -1,7 +1,7 @@ using Printf using Oceananigans using Oceananigans.Units -using Oceananigans: architecture +using Oceananigans: architecture, on_architecture using ClimaOcean using ClimaOcean.ECCO using ClimaOcean.OceanSimulations @@ -23,7 +23,7 @@ Ny = 600 Nz = length(z_faces) - 1 # Running on a GPU -arch = CPU() +arch = GPU() # A near-global grid from 75ᵒ S to 75ᵒ N grid = LatitudeLongitudeGrid(arch; From d69ae9a1365c65d6188ca350064c5ac0da016169 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:41:27 -0400 Subject: [PATCH 641/716] try with everything together --- docs/make.jl | 6 +++--- examples/near_global_omip_simulation.jl | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 10344e76..05c13356 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,9 +15,9 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - # "inspect_ecco_data.jl", - # "generate_surface_fluxes.jl", - # "single_column_simulation.jl", + "inspect_ecco_data.jl", + "generate_surface_fluxes.jl", + "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", "near_global_omip_simulation.jl" ] diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 77f9047a..2e54c9e7 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -165,7 +165,7 @@ ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) # Finally, the coupled simulation! -coupled_simulation = Simulation(coupled_model; Δt=1, stop_iteration = 1) #stop_time = 20days) +coupled_simulation = Simulation(coupled_model; Δt=1, stop_time = 20days) run!(coupled_simulation) @@ -202,7 +202,7 @@ heatmap!(ax, interior(s, :, :, grid.Nz), colorrange = (0, 0.5), colormap = :deep ax = Axis(fig[2, 1], title = "Surface Temperature [Cᵒ]") heatmap!(ax, interior(T, :, :, grid.Nz), colorrange = (-1, 30), colormap = :magma) -ax = Axis(fig[2, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") +ax = Axis(fig[2, 2], title = "Turbulent Kinetic Energy [m²s⁻²]") heatmap!(ax, interior(e, :, :, grid.Nz), colorrange = (0, 1e-3), colormap = :solar) save("near_global_ocean_surface.png", fig) From 48269d6cdfbe11084f1519ff8573e5864371bb9e Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:41:47 -0400 Subject: [PATCH 642/716] typo --- docs/make.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 05c13356..8fc713bf 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -49,9 +49,9 @@ pages = [ ], "Examples" => [ - # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - # "Surface fluxes" => "literated/generate_surface_fluxes.md", - # "Single column simulation" => "literated/single_column_simulation.md", + "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + "Surface fluxes" => "literated/generate_surface_fluxes.md", + "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", ] From edce55fa327abc2b078637dc58eaed6cfe7325ce Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Jul 2024 12:15:40 -0400 Subject: [PATCH 643/716] try without the giba simulation --- docs/make.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index 8fc713bf..82fbab7b 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -19,7 +19,7 @@ to_be_literated = [ "generate_surface_fluxes.jl", "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", - "near_global_omip_simulation.jl" + # "near_global_omip_simulation.jl" ] for file in to_be_literated From 908066b0becdefa863911fd69404003025c56656 Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:01:34 -0400 Subject: [PATCH 644/716] simple cpu example --- docs/make.jl | 2 +- examples/near_global_omip_simulation.jl | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 82fbab7b..8fc713bf 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -19,7 +19,7 @@ to_be_literated = [ "generate_surface_fluxes.jl", "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", - # "near_global_omip_simulation.jl" + "near_global_omip_simulation.jl" ] for file in to_be_literated diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 2e54c9e7..1512aabb 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -18,12 +18,12 @@ using Dates z_faces = exponential_z_faces(Nz=40, depth=6000) -Nx = 1440 -Ny = 600 +Nx = 360 +Ny = 150 Nz = length(z_faces) - 1 # Running on a GPU -arch = GPU() +arch = CPU() # A near-global grid from 75ᵒ S to 75ᵒ N grid = LatitudeLongitudeGrid(arch; @@ -165,7 +165,7 @@ ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) # Finally, the coupled simulation! -coupled_simulation = Simulation(coupled_model; Δt=1, stop_time = 20days) +coupled_simulation = Simulation(coupled_model; Δt=1, stop_iteration=1) #stop_time = 20days) run!(coupled_simulation) From f2f9d6b928138986c02fb5e4bc36528cd688e9a0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 30 Jul 2024 13:52:31 -0400 Subject: [PATCH 645/716] adding a slurm time --- .buildkite/examples_build.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index 0c4dc8f7..243fd315 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -2,14 +2,15 @@ agents: queue: new-central slurm_mem: 8G modules: climacommon/2024_05_27 + slurm_time: 48:00:00 + +timeout_in_minutes: 1440 env: JULIA_LOAD_PATH: "${JULIA_LOAD_PATH}:${BUILDKITE_BUILD_CHECKOUT_PATH}/.buildkite" OPENBLAS_NUM_THREADS: 1 OMPI_MCA_opal_warn_on_missing_libcuda: 0 -timeout_in_minutes: 1440 - steps: - label: "initialize" key: "init" @@ -40,8 +41,10 @@ steps: slurm_cpus_per_task: 8 slurm_ntasks: 1 slurm_gpus_per_task: 1 + slurm_time: 48:00:00 env: JULIA_NUM_PRECOMPILE_TASKS: 8 + timeout_in_minutes: 1440 - wait: ~ continue_on_failure: true From d375f0bd4ecf5fa48b7d0cf68428ae1c8b4ec8b4 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 30 Jul 2024 15:15:14 -0400 Subject: [PATCH 646/716] try with SSL_no_verify --- .buildkite/examples_build.yml | 7 +++++++ docs/make.jl | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index 243fd315..bc8d40f0 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -42,8 +42,15 @@ steps: slurm_ntasks: 1 slurm_gpus_per_task: 1 slurm_time: 48:00:00 + env: JULIA_NUM_PRECOMPILE_TASKS: 8 + JULIA_DEBUG: "Documenter" + # This environment variable is needed to avoid SSL verification errors when Downloads.jl + # tries to download the bathyemtry data. It should not be required so we need to fix our certificates + # and remove this environment variable. ref: https://github.com/JuliaLang/Downloads.jl/issues/97 + JULIA_SSL_NO_VERIFY: "**" + timeout_in_minutes: 1440 - wait: ~ diff --git a/docs/make.jl b/docs/make.jl index 8fc713bf..fbff452f 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -24,7 +24,7 @@ to_be_literated = [ for file in to_be_literated filepath = joinpath(EXAMPLES_DIR, file) - Literate.markdown(filepath, OUTPUT_DIR; flavor = Literate.DocumenterFlavor()) + Literate.markdown(filepath, OUTPUT_DIR; flavor = Literate.DocumenterFlavor(), execute = true) end ##### From 7a7d0a3ce9aa2f04ae39ff000887c8092e11ce82 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 30 Jul 2024 18:40:31 -0400 Subject: [PATCH 647/716] try with wget --- src/Bathymetry.jl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index f3f479ca..422c74de 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -97,8 +97,13 @@ function regrid_bathymetry(target_grid; mkdir(dir) end - fileurl = joinpath(url, filename) - Downloads.download(fileurl, filepath; progress=download_progress, verbose=true) + try + fileurl = joinpath(url, filename) + Downloads.download(fileurl, filepath; progress=download_progress, verbose=true) + catch + cmd = `wget --no-check-certificate -O $filepath $fileurl` + run(cmd) + end end dataset = Dataset(filepath) From ef8ca0acf0537a724874e9b793610a8533ca33b6 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 30 Jul 2024 18:41:50 -0400 Subject: [PATCH 648/716] typo --- src/Bathymetry.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index 422c74de..3d0993d2 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -97,8 +97,9 @@ function regrid_bathymetry(target_grid; mkdir(dir) end + fileurl = joinpath(url, filename) + try - fileurl = joinpath(url, filename) Downloads.download(fileurl, filepath; progress=download_progress, verbose=true) catch cmd = `wget --no-check-certificate -O $filepath $fileurl` From a12ceeef550c2dcf2121607e9a560d7637d57ffd Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 30 Jul 2024 21:26:46 -0400 Subject: [PATCH 649/716] full fledged model on GPU --- examples/near_global_omip_simulation.jl | 218 ++++++++++++++---------- 1 file changed, 127 insertions(+), 91 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 1512aabb..d54c0e06 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -1,3 +1,17 @@ +# # Near-global Ocean simulation +# +# This Julia script sets up and runs a near-global ocean simulation using the Oceananigans.jl and ClimaOcean.jl packages. +# The simulation spans from 75°S to 75°N with a horizontal resolution of 1/4th of a degree and 40 vertical levels. +# +# The simulation is then ran for one year and the results are visualized using the CairoMakie.jl package. +# +# ## Initial Setup with Package Imports +# +# The script begins by importing necessary Julia packages for visualization (CairoMakie), +# ocean modeling (Oceananigans, ClimaOcean), and handling of dates and times (CFTime, Dates). +# These packages provide the foundational tools for creating the simulation environment, +# including grid setup, physical processes modeling, and data visualization. + using Printf using Oceananigans using Oceananigans.Units @@ -10,22 +24,21 @@ using ClimaOcean.OceanSeaIceModels using CFTime using Dates -##### -##### Near - Global Ocean at 1/4th of a degree -##### +# ## Grid Configuration +# +# We define a near-global grid from 75°S to 75°N with a horizontal resolution of 1/4th of a degree and 40 vertical levels. +# The grid is created using Oceananigans' `LatitudeLongitudeGrid`. We use an exponential vertical spacing to better resolve the upper ocean layers. +# The total depth of the domain is set to 6000 meters. +# Finally, we specify the architecture to be used for the simulation, which in this case is a GPU. -# 40 vertical levels +arch = GPU() z_faces = exponential_z_faces(Nz=40, depth=6000) -Nx = 360 -Ny = 150 +Nx = 1440 +Ny = 600 Nz = length(z_faces) - 1 -# Running on a GPU -arch = CPU() - -# A near-global grid from 75ᵒ S to 75ᵒ N grid = LatitudeLongitudeGrid(arch; size = (Nx, Ny, Nz), halo = (7, 7, 7), @@ -33,9 +46,12 @@ grid = LatitudeLongitudeGrid(arch; longitude = (0, 360), latitude = (-75, 75)) -# We retrieve the bathymetry from the ETOPO1 data by ensuring a -# minimum depth of 10 meters (everyhting shallower is considered land) -# and removing all connected regions (inland lakes) +# ## Bathymetry and Immersed Boundary +# +# We retrieve the bathymetry from the ETOPO1 data by ensuring a minimum depth of 10 meters (everything shallower is considered land) +# The `interpolation_passes` parameter specifies the number of passes to interpolate the bathymetry data. The larger the number, +# the smoother the bathymetry will be. We also remove all connected regions (inland lakes) from the bathymetry data by specifying +# `connected_regions_allowed = 0`. bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, @@ -43,63 +59,73 @@ bottom_height = retrieve_bathymetry(grid; interpolation_passes = 20, connected_regions_allowed = 0) -# An immersed boundary using a staircase representation of bathymetry grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) -##### -##### The Ocean component -##### +# ## Ocean Model Configuration +# +# To set the ocean simulation we use the `ocean_simulation` function from ClimaOcean.jl. This allows us to build +# an ocean simulation with default parameters and numerics. In this case, the defaults are +# - CATKE turbulence closure for vertical mixing, see [`CATKEVerticalDiffusivity`](@ref) +# - WENO-based advection scheme for momentum in the vector invariant form, see [`WENOVectorInvariant`](@ref) +# - WENO-based advection scheme for tracers, see [`WENO`](@ref) +# - `SplitExplicitFreeSurfaceSolver` with a Courant number of 0.7, see [`SplitExplicitFreeSurface`](@ref) +# - TEOS-10 equation of state, see [`TEOS10EquationOfState`](@ref) +# - Quadratic bottom drag with a drag coefficient of 0.003 +# +# The ocean model is then initialized with the ECCO2 temperature and salinity fields for January 1, 1993. -# We retain all the defaults for the ocean model ocean = ocean_simulation(grid) model = ocean.model date = DateTimeProlepticGregorian(1993, 1, 1) -# We interpolate the initial conditions from the ECCO2 dataset -# (for the moment these are both 1st January 1993) - set!(model, - T = ECCOMetadata(:temperature, date, ECCO2Daily()), - S = ECCOMetadata(:salinity, date, ECCO2Daily())) - -##### -##### The atmosphere -##### - -# The whole prescribed atmosphere is loaded in memory -# 4 snapshots at the time. + T = ECCOMetadata(:temperature; date), + S = ECCOMetadata(:salinity; date)) + +# ## Prescribed Atmosphere and Radiation +# +# The atmospheric data is prescribed using the JRA55 dataset. The dataset is loaded into memory in 4 snapshots at a time. +# The JRA55 dataset provides atmospheric data such as temperature, humidity, and wind fields to calculate turbulent fluxes +# through bulk formulae, see [`CrossRealmFluxes`](@ref) +# +# The radiation model specified an ocean albedo emissivity to compute the net radiative fluxes. +# The default ocean albedo is based on the Payne (1982) and depends on cloud cover (computed from +# the maximum possible incident solar radiation divided by the actual incident solar radiation), and the latitude. +# The ocean emissivity is set to 0.97. backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) - -# Tabulated ocean albedo from Payne (1982) -# ocean emissivity is the default 0.97 - radiation = Radiation(arch) -##### -##### The atmospheric-forced coupled ocean-seaice model -##### - -# Simplistic sea ice that ensure "no-cooling-fluxes" where `T < T_minimum` -# to change with a thermodynamic sea-ice model +# ## Sea Ice Model +# +# This simulation includes a simplified representation of an ice cover where the air-sea fluxes are shut down whenever the +# sea surface temperature is below the freezing point. Only heating fluxes are allowed. This is by no means a sea ice model +# but it allows to include atmosphere-ocean fluxes without having the temperature plummeting to - ∞. sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() -# The complete coupled model +# ## The Coupled Simulation +# +# Finally, we have everything it takes to define the coupled coupled, which includes the ocean, the atmosphere, and the radiation parameters. +# The model is constructed using the `OceanSeaIceModel` constructor. +# +# We can then construct a coupled simulation. In this case we start with a time step of 1 second and run the simulation for 720 days. +# We will eventually increase the time step size as the simulation progresses and the initialization shocks dissipate. +# +# We also define a callback function to monitor the progress of the simulation. This function prints the current time, iteration, time step, +# as well as the maximum velocities and tracers in the domain. The wall time is also printed to monitor the time taken for each iteration. -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +coupled_simulation = Simulation(coupled_model; Δt=10, stop_time = 720days) wall_time = [time_ns()] -# We define a progress function that -# shows the maximum values of velocity and temperature -# to make sure everything proceedes as planned - function progress(sim) - u, v, w = sim.model.velocities - T = sim.model.tracers.T + ocean = sim.model.ocean + u, v, w = ocean.model.velocities + T = ocean.model.tracers.T Tmax = maximum(interior(T)) Tmin = minimum(interior(T)) @@ -115,63 +141,73 @@ function progress(sim) wall_time[1] = time_ns() end -ocean.callbacks[:progress] = Callback(progress, IterationInterval(10)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) + +# ## Set up Output Writers +# +# We define output writers to save the simulation data at regular intervals. +# In this case we save the surface fluxes, the surface fields, at a fairly high frequency (half a day) +# and snapshots of the fields every 10 days. +# +# We also add a checkpoint writer to save the model state every 60 days, so that we can easily restart the simulation if needed. fluxes = (u = model.velocities.u.boundary_conditions.top.condition, v = model.velocities.v.boundary_conditions.top.condition, T = model.tracers.T.boundary_conditions.top.condition, S = model.tracers.S.boundary_conditions.top.condition) - output_kwargs = (; overwrite_existing = true, array_type = Array{Float32}) -# We add a couple of outputs: the surface state every 12 hours, the surface fluxes -# every 12 hours, and the whole state every ten days - -ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; - schedule = TimeInterval(0.5days), - overwrite_existing = true, - filename = "surface_fluxes", - output_kwargs...) - -ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); - schedule = TimeInterval(0.5days), - filename = "surface", - indices = (:, :, grid.Nz), - output_kwargs...) - -ocean.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); - schedule = TimeInterval(10days), - filename = "snapshots", - output_kwargs...) - -# Checkpointer for restarting purposes -ocean.output_writers[:checkpoint] = Checkpointer(model; - schedule = TimeInterval(60days), - overwrite_existing = true, - prefix = "checkpoint") - -##### -##### Run the simulation! -##### - -# warm up the simulation to ensure that the model adapts -# to the interpolated initial conditions without crashing - -ocean.Δt = 10 -ocean.stop_iteration = 1 +coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; + schedule = TimeInterval(0.5days), + overwrite_existing = true, + filename = "surface_fluxes", + output_kwargs...) + +coupled_simulation.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); + schedule = TimeInterval(0.5days), + filename = "surface", + indices = (:, :, grid.Nz), + output_kwargs...) + +coupled_simulation.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); + schedule = TimeInterval(10days), + filename = "snapshots", + output_kwargs...) + +coupled_simulation.output_writers[:checkpoint] = Checkpointer(model; + schedule = TimeInterval(60days), + overwrite_existing = true, + prefix = "checkpoint") + +# ## Warming up the simulation! +# +# As an initial condition we have interpolated ECCO tracer fields on our custom grid. +# Most likely the bathymetry of the original ECCO data is different than our grid, so the initialization of the velocity +# field might lead to shocks if we use a large time step. +# +# Therefore, we warm up with a small time step to ensure that the interpolated initial conditions adapt to the model numerics and +# parameterization without crashing. 30 days of integration with a maximum time step of 1.5 minutes should be enough to dissipate +# spurious initialization shocks. + +ocean.stop_time = 30days wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -# Finally, the coupled simulation! +run!(coupled_simulation) -coupled_simulation = Simulation(coupled_model; Δt=1, stop_iteration=1) #stop_time = 20days) +# ## Running the simulation +# +# Now that the simulation has been warmed up, we can run it for the full year. +# We increase the maximum time step size to 10 minutes and let the simulation run for 720 days. -run!(coupled_simulation) +ocean.stop_time = 720days +wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 10minutes, max_change = 1.1) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) -##### -##### Visualization -##### +# ## Visualizing the Results +# +# after the simulation has finished, we can visualize the results. using CairoMakie From 6d6b0cce61d4c54802bfd647270a6d14b584257d Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 30 Jul 2024 21:27:18 -0400 Subject: [PATCH 650/716] Update .buildkite/examples_build.yml Co-authored-by: Gregory L. Wagner --- .buildkite/examples_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index bc8d40f0..6f06a800 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -47,7 +47,7 @@ steps: JULIA_NUM_PRECOMPILE_TASKS: 8 JULIA_DEBUG: "Documenter" # This environment variable is needed to avoid SSL verification errors when Downloads.jl - # tries to download the bathyemtry data. It should not be required so we need to fix our certificates + # tries to download the bathymetry data. It should not be required so we need to fix our certificates. # and remove this environment variable. ref: https://github.com/JuliaLang/Downloads.jl/issues/97 JULIA_SSL_NO_VERIFY: "**" From 40f75d3c747fd363c3c3fc6bde27ef74c4aca7e5 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 30 Jul 2024 21:32:43 -0400 Subject: [PATCH 651/716] add literate debug --- docs/Manifest.toml | 2465 ++++++++++++++++++++++++++++++++++++++++++++ docs/Project.toml | 1 + docs/make.jl | 4 +- 3 files changed, 2469 insertions(+), 1 deletion(-) create mode 100644 docs/Manifest.toml diff --git a/docs/Manifest.toml b/docs/Manifest.toml new file mode 100644 index 00000000..877811df --- /dev/null +++ b/docs/Manifest.toml @@ -0,0 +1,2465 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.4" +manifest_format = "2.0" +project_hash = "c811b75e93eb191148d8009daa65c973a0ca77df" + +[[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.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] +git-tree-sha1 = "f61b15be1d76846c0ce31d3fcfac5380ae53db6a" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.37" + + [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.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[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"] +git-tree-sha1 = "8c5b39db37c1d0340bf3b14895fba160c2d6cbb5" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.14.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = "CUDSS" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysExt = "StaticArrays" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + 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 = "014bc22d6c400a7703c0f5dc1fdc302440cf88be" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "1.0.4" + +[[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 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BitTwiddlingConvenienceFunctions]] +deps = ["Static"] +git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" +uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" +version = "0.1.6" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.5+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.3" + +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] +git-tree-sha1 = "5a97e67919535d6841172016c9530fd69494e5ec" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.6" + +[[deps.CRC32c]] +uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" + +[[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 = "fdd9dfb67dfefd548f51000cc400bb51003de247" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.4.3" + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + EnzymeCoreExt = "EnzymeCore" + SpecialFunctionsExt = "SpecialFunctions" + + [deps.CUDA.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] +git-tree-sha1 = "97df9d4d6be8ac6270cb8fd3b8fc413690820cbd" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.9.1+1" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "f3b237289a5a77c759b2dd5d4c2ff641d67c4030" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.3.4" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "afea94249b821dc754a8ca6695d3daed851e1f5a" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.14.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 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+2" + +[[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 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.24.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ClimaOcean]] +deps = ["Adapt", "CFTime", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "ImageMorphology", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "Scratch", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] +path = "/Users/loaner/development/ClimaOcean.jl" +uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" +version = "0.2.0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "36752a8f020c7f1c959fea0e5a98b113d54fc74f" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.1.1" + +[[deps.CloseOpenIntervals]] +deps = ["Static", "StaticArrayInterface"] +git-tree-sha1 = "05ba0d07cd4fd8b7a39541e31a7b0254704ea581" +uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" +version = "0.1.13" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "b8fe8546d52ca154ac556809e10c75e6e7430ac8" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.5" + +[[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 = "b5278586822443594ff615963b0c09755771b3e0" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.26.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.5" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.11" + +[[deps.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 = "d6fb5bf939a2753c74984b11434ea25d6c397a58" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.6" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.CommonWorldInvalidations]] +git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" +uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" +version = "1.0.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.15.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.1+0" + +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "ea32b83ca4fefa1768dc84e504cc0a94fb1ab8d1" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.4.2" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d8a9c0b6ac2d9081bf76324b39c78ca3ce4f0c98" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.6" +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.CpuId]] +deps = ["Markdown"] +git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" +uuid = "adafc99b-e345-5852-983c-f28acb93d879" +version = "0.3.1" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] +git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.2.5" + +[[deps.CubicSplines]] +deps = ["Random", "Test"] +git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" +uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" +version = "0.2.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.20" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.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 = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "9c405847cc7ecda2dc921ccf18b47ca150d7317e" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.109" + + [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 = "76deb8c15f37a3853f13ea2226b8f2577652de05" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "1.5.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.ExactPredicates]] +deps = ["IntervalArithmetic", "Random", "StaticArrays"] +git-tree-sha1 = "b3f2ff58735b5f024c392fde763f29b057e4b025" +uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" +version = "2.2.8" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c6317308b9dc757616f0b5cb379db10494443a7" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.6.2+0" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.Extents]] +git-tree-sha1 = "94997910aca72897524d2237c41eb852153b0f65" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.3" + +[[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.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 = "0653c0a2396a6da5bc4766c43041ef5fd3efbe57" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.11.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 = "2de436b72c3422940cbe1367611d137008af7ec3" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.23.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 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.96+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 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.2+0" + +[[deps.FreeTypeAbstraction]] +deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] +git-tree-sha1 = "2493cdfd0740015955a8e46de4ef28f49460d8bc" +uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" +version = "0.10.3" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.14+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 = "a74c3f1cf56a3dfcdef0605f8cdb7015926aae30" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "10.3.0" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Preferences", "Scratch", "Serialization", "TOML", "TimerOutputs", "UUIDs"] +git-tree-sha1 = "ab29216184312f99ff957b32cd63c2fe9c928b91" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "0.26.7" + +[[deps.GeoInterface]] +deps = ["Extents"] +git-tree-sha1 = "9fff8990361d5127b770e3454488360443019bb3" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.3.5" + +[[deps.GeometryBasics]] +deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] +git-tree-sha1 = "b62f2b2d76cee0d61a2ef2b3118cd2a3215d3134" +uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" +version = "0.4.11" + +[[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 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.2+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 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.8" + +[[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.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] +git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.17" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5e19e1e4fa3e71b774ce746274364aef0234634e" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.11.1+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 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.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 = "437abb322a41d527c197fa800455f79d414f0a3c" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.8" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.9" + +[[deps.ImageMorphology]] +deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] +git-tree-sha1 = "6f0a801136cb9c229aebea0df296cdcd471dbcd1" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.4.5" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0936ba688c6d201805a83da835b55c61a180db52" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.11+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 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.InlineStrings]] +git-tree-sha1 = "45521d31238e87ee9f9732561bfee12d4eebd52d" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.2" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + ParsersExt = "Parsers" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" + +[[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 = "14eb2b542e748570b56446f4c50fbfb2306ebc45" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.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 = "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_jll", "MacroTools", "RoundingEmulator"] +git-tree-sha1 = "433b0bb201cd76cb087b017e49244f10394ebe9c" +uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +version = "0.22.14" +weakdeps = ["DiffRules", "ForwardDiff", "RecipesBase"] + + [deps.IntervalArithmetic.extensions] + IntervalArithmeticDiffRulesExt = "DiffRules" + IntervalArithmeticForwardDiffExt = "ForwardDiff" + IntervalArithmeticRecipesBaseExt = "RecipesBase" + +[[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 = "18c59411ece4838b18cd7f537e56cf5e41ce5bfd" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.15" +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", "PrecompileTools", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] +git-tree-sha1 = "67d4690d32c22e28818a434b293a374cc78473d3" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.4.51" + +[[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 = "c84a835e1a09b289ffcd2271bf2a337bbdda6637" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.3+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 = "d0448cebd5919e06ca5edc7a264631790de810ec" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.22" + + [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 = "7d703202e65efa1369de1279c162b915e245eed1" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.9" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.2+0" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] +git-tree-sha1 = "020abd49586480c1be84f57da0017b5d3db73f7c" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "8.0.0" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "c2636c264861edc6d305e6b4d528f09566d24c5e" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.30+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"] +git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.2+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LayoutPointers]] +deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "a9eaadb366f5493a5654e843864c13d8b107548c" +uuid = "10f19ff3-798f-405d-979b-55457f8fc047" +version = "0.1.17" + +[[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"] +git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.11+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.49.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 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.40.1+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.40.1+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 = "eef2e1fc1dc38af90a18eb16e519e06d1fd10c2a" +uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" +version = "2.19.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.28" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.0.3" + +[[deps.LoopVectorization]] +deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] +git-tree-sha1 = "8084c25a250e00ae427a379a5b607e7aed96a2dd" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.171" +weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7f26c8fc5229e68484e0b3447312c98e16207d11" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.10.0+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "f046ccd0c6db2832a9f639e2c669c6fe867e5f4f" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.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", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "19d4bd098928a3263693991500d05d74dbdc2004" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.2.2+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.11" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "8c35d5420193841b2f367e658540e8d9e0601ed0" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.4.0+0" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.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.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MarkdownAST]] +deps = ["AbstractTrees", "Markdown"] +git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" +uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" +version = "0.1.2" + +[[deps.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 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.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 = "a640912695952b074672edb5f9aaee2f7f9fd59a" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.4" + +[[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 = "942c78ad3c95e47bcbab3eeacb0b8a846bcfb33b" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.91.4" + + [deps.Oceananigans.extensions] + OceananigansEnzymeExt = "Enzyme" + + [deps.Oceananigans.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.OffsetArrays]] +git-tree-sha1 = "1a27764e945a152f7ca7efa04de513d473e9542e" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.14.1" +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 = "8292dd5c8a38257111ada2174000a33745b06d4e" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.2.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", "TOML", "Zlib_jll"] +git-tree-sha1 = "2f0a1d8c79bc385ec3fcda12830c9d0e72b30e71" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.4+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.3" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.14+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.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.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 = "cb5a2ab6763464ae0f19c86c56c63d4a2b0f5bda" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.52.2+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 = "fa85ac32172d96cfdb91dbc53e8e57007e5a2b5a" +uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" +version = "0.19.5" + + [deps.PencilArrays.extensions] + PencilArraysAMDGPUExt = ["AMDGPU"] + PencilArraysDiffEqExt = ["DiffEqBase"] + PencilArraysHDF5Ext = ["HDF5"] + + [deps.PencilArrays.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" + HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" + +[[deps.PencilFFTs]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] +git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" +uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" +version = "0.15.1" + +[[deps.Permutations]] +deps = ["Combinatorics", "LinearAlgebra", "Random"] +git-tree-sha1 = "4ca430561cf37c75964c8478eddae2d79e96ca9b" +uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" +version = "0.4.21" + +[[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 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.43.4+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.PolyesterWeave]] +deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] +git-tree-sha1 = "645bed98cd47f72f67316fd42fc47dee771aefcd" +uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" +version = "0.2.2" + +[[deps.PolygonOps]] +git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" +uuid = "647866c9-e3ac-4575-94e7-e3d426903924" +version = "0.1.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "RecipesBase", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "1a9cfb2dc2c2f1bd63f1906d72af39a79b49b736" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.0.11" + + [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 = "66b20dd35966a748321d3b2537c4584cf40387c7" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.2" + +[[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 = "8f6bc219586aef8baf0ff9a5fe16ee9c70cb65e4" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.10.2" + +[[deps.PtrArrays]] +git-tree-sha1 = "f011fbb92c4d401059b2212c05c0601b70f8b759" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.2.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 = "e237232771fdafbae3db5c31275303e056afaa9f" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.10.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.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"] +git-tree-sha1 = "d483cd324ce5cf5d61b77930f0bbd6cb61927d21" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.2+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 = "3484138c9fa4296a0cf46a74ca3f97b59d12b1d0" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.1.6" + + [deps.Roots.extensions] + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + + [deps.Roots.weakdeps] + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" + SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" + SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.1" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.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.SIMD]] +deps = ["PrecompileTools"] +git-tree-sha1 = "2803cab51702db743f3fda07dd1745aadfbf43bd" +uuid = "fdea26ae-647d-5447-a871-4b548cad5224" +version = "3.5.0" + +[[deps.SIMDTypes]] +git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" +uuid = "94e857df-77ce-4151-89e5-788b33177be4" +version = "0.1.0" + +[[deps.SLEEFPirates]] +deps = ["IfElse", "Static", "VectorizationBase"] +git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.43" + +[[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 = "ff11acffdb082493657550959d4feb4b6149e73a" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.5" + +[[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 = "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 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.4.0" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableHashTraits]] +deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] +git-tree-sha1 = "a58e0d86783226378a6857f2de26d3314107e3ac" +uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" +version = "1.2.0" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.1" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] +git-tree-sha1 = "87d51a3ee9a4b0d2fe054bdd3fc2436258db2603" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.1.1" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "8963e5a083c837531298fc41599182a759a87a6d" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.5.1" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "eeafab08ae20c62c44c8399ccb9354a04b80db50" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.7" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.StaticPermutations]] +git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" +uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" +version = "0.3.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.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 = "bd9bd1c70cfc115cc3a30213fc725125a6b43652" +uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" +version = "2.1.0" + +[[deps.StridedViews]] +deps = ["LinearAlgebra", "PackageExtensionCompat"] +git-tree-sha1 = "2917996ce0fa6b8a3a85240a5e9ff930e2aeaa43" +uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" +version = "0.3.1" +weakdeps = ["CUDA"] + + [deps.StridedViews.extensions] + StridedViewsCUDAExt = "CUDA" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.6.18" +weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = "GPUArraysCore" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "89c701c87f378ce95e7ddbcd69b8f1106ba8b968" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.11.0" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "ClimaParams" + + [deps.SurfaceFluxes.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.12.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 = "31834a05c8a9d52d7f56b23ae7ad1c3b72a4f1bf" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.13.2" + +[[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 = "80b13ddc5ae7b8605ef5a055e7f23c5b5f4775cf" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.7" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.ThreadingUtilities]] +deps = ["ManualMemory"] +git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" +uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" +version = "0.5.2" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "SIMD", "UUIDs"] +git-tree-sha1 = "bc7fd5c91041f44636b2c134041f7e5263ce58ae" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.10.0" + +[[deps.TiledIteration]] +deps = ["OffsetArrays", "StaticArrayInterface"] +git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" +uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" +version = "0.5.0" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "5a13ae8a41237cff5ecf34f73eb1b8f42fff6531" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.24" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "96612ac5365777520c3c5396314c8cf7408f436a" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.1" +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 = "bf2c553f25e954a9b38c9c0593a59bb13113f9e5" +uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" +version = "0.1.5" + +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "e7f5b81c65eb858bed630fe006837b935518aca5" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.70" + +[[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 = "d9717ce3518dc68a99e6b96300813760d887a01d" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.13.1+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "a54ee957f4c86b526460a720dbc882fa5edcbefc" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.41+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", "Xorg_libX11_jll"] +git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.6+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.11+0" + +[[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 = "bcd466676fef0878338c61e655629fa7bbc69d8e" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.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"] +git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.9.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 = "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 = "490376214c4721cdaca654041f635213c6165cb3" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+2" + +[[deps.libzip_jll]] +deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "3282b7d16ae7ac3e57ec2f3fa8fafb564d8f9f7f" +uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" +version = "1.10.1+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2021.12.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[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 08ab7c7a..084aad21 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,6 @@ [deps] CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" diff --git a/docs/make.jl b/docs/make.jl index fbff452f..9e50798b 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -24,7 +24,9 @@ to_be_literated = [ for file in to_be_literated filepath = joinpath(EXAMPLES_DIR, file) - Literate.markdown(filepath, OUTPUT_DIR; flavor = Literate.DocumenterFlavor(), execute = true) + withenv("JULIA_DEBUG" => "Literate") do + Literate.markdown(filepath, OUTPUT_DIR; flavor = Literate.DocumenterFlavor(), execute = true) + end end ##### From 3e9bdfc2fd9ed6e10d93c89bb3da76422dfadeda Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 30 Jul 2024 21:33:27 -0400 Subject: [PATCH 652/716] back to previous project / manifest --- docs/Manifest.toml | 2465 -------------------------------------------- docs/Project.toml | 1 - 2 files changed, 2466 deletions(-) delete mode 100644 docs/Manifest.toml diff --git a/docs/Manifest.toml b/docs/Manifest.toml deleted file mode 100644 index 877811df..00000000 --- a/docs/Manifest.toml +++ /dev/null @@ -1,2465 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.4" -manifest_format = "2.0" -project_hash = "c811b75e93eb191148d8009daa65c973a0ca77df" - -[[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.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] -git-tree-sha1 = "f61b15be1d76846c0ce31d3fcfac5380ae53db6a" -uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.37" - - [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.AliasTables]] -deps = ["PtrArrays", "Random"] -git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" -uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" -version = "1.1.3" - -[[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"] -git-tree-sha1 = "8c5b39db37c1d0340bf3b14895fba160c2d6cbb5" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.14.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = "CUDSS" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceSparseArraysExt = "SparseArrays" - ArrayInterfaceStaticArraysExt = "StaticArrays" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - 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 = "014bc22d6c400a7703c0f5dc1fdc302440cf88be" -uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" -version = "1.0.4" - -[[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 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.9" - -[[deps.BitTwiddlingConvenienceFunctions]] -deps = ["Static"] -git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" -uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" -version = "0.1.6" - -[[deps.Blosc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "19b98ee7e3db3b4eff74c5c9c72bf32144e24f10" -uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" -version = "1.21.5+0" - -[[deps.Bzip2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" -uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.8+1" - -[[deps.CEnum]] -git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" -uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.5.0" - -[[deps.CFTime]] -deps = ["Dates", "Printf"] -git-tree-sha1 = "5afb5c5ba2688ca43a9ad2e5a91cbb93921ccfa1" -uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.1.3" - -[[deps.CPUSummary]] -deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "5a97e67919535d6841172016c9530fd69494e5ec" -uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.6" - -[[deps.CRC32c]] -uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc" - -[[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 = "fdd9dfb67dfefd548f51000cc400bb51003de247" -uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.4.3" - - [deps.CUDA.extensions] - ChainRulesCoreExt = "ChainRulesCore" - EnzymeCoreExt = "EnzymeCore" - SpecialFunctionsExt = "SpecialFunctions" - - [deps.CUDA.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.CUDA_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "97df9d4d6be8ac6270cb8fd3b8fc413690820cbd" -uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.9.1+1" - -[[deps.CUDA_Runtime_Discovery]] -deps = ["Libdl"] -git-tree-sha1 = "f3b237289a5a77c759b2dd5d4c2ff641d67c4030" -uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.3.4" - -[[deps.CUDA_Runtime_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "afea94249b821dc754a8ca6695d3daed851e1f5a" -uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.14.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 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" -uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.0+2" - -[[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 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.24.0" -weakdeps = ["SparseArrays"] - - [deps.ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[deps.ClimaOcean]] -deps = ["Adapt", "CFTime", "CUDA", "ClimaSeaIce", "CubicSplines", "DataDeps", "Dates", "Downloads", "ImageMorphology", "JLD2", "KernelAbstractions", "NCDatasets", "Oceananigans", "Printf", "Scratch", "SeawaterPolynomials", "StaticArrays", "Statistics", "SurfaceFluxes", "Thermodynamics"] -path = "/Users/loaner/development/ClimaOcean.jl" -uuid = "0376089a-ecfe-4b0e-a64f-9c555d74d754" -version = "0.2.0" - -[[deps.ClimaSeaIce]] -deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "36752a8f020c7f1c959fea0e5a98b113d54fc74f" -uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.1.1" - -[[deps.CloseOpenIntervals]] -deps = ["Static", "StaticArrayInterface"] -git-tree-sha1 = "05ba0d07cd4fd8b7a39541e31a7b0254704ea581" -uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" -version = "0.1.13" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "b8fe8546d52ca154ac556809e10c75e6e7430ac8" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.5" - -[[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 = "b5278586822443594ff615963b0c09755771b3e0" -uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.26.0" - -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.5" - -[[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.10.0" -weakdeps = ["SpecialFunctions"] - - [deps.ColorVectorSpace.extensions] - SpecialFunctionsExt = "SpecialFunctions" - -[[deps.Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "362a287c3aa50601b0bc359053d5c2468f0e7ce0" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.11" - -[[deps.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 = "d6fb5bf939a2753c74984b11434ea25d6c397a58" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.6" - -[[deps.CommonSolve]] -git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" -uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.4" - -[[deps.CommonSubexpressions]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.0" - -[[deps.CommonWorldInvalidations]] -git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" -uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" -version = "1.0.0" - -[[deps.Compat]] -deps = ["TOML", "UUIDs"] -git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.15.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.1+0" - -[[deps.CompositionsBase]] -git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" -uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" -version = "0.1.2" -weakdeps = ["InverseFunctions"] - - [deps.CompositionsBase.extensions] - CompositionsBaseInverseFunctionsExt = "InverseFunctions" - -[[deps.ConcurrentUtilities]] -deps = ["Serialization", "Sockets"] -git-tree-sha1 = "ea32b83ca4fefa1768dc84e504cc0a94fb1ab8d1" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.4.2" - -[[deps.ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d8a9c0b6ac2d9081bf76324b39c78ca3ce4f0c98" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.6" -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.CpuId]] -deps = ["Markdown"] -git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" -uuid = "adafc99b-e345-5852-983c-f28acb93d879" -version = "0.3.1" - -[[deps.Crayons]] -git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" -uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" -version = "4.1.1" - -[[deps.CubedSphere]] -deps = ["Elliptic", "FFTW", "Printf", "ProgressBars", "SpecialFunctions", "TaylorSeries", "Test"] -git-tree-sha1 = "10134667d7d3569b191a65801514271b8a93b292" -uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.2.5" - -[[deps.CubicSplines]] -deps = ["Random", "Test"] -git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" -uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" -version = "0.2.1" - -[[deps.DataAPI]] -git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.16.0" - -[[deps.DataDeps]] -deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] -git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" -uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.13" - -[[deps.DataFrames]] -deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.6.1" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.20" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.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 = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "9c405847cc7ecda2dc921ccf18b47ca150d7317e" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.109" - - [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 = "76deb8c15f37a3853f13ea2226b8f2577652de05" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.5.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.ExactPredicates]] -deps = ["IntervalArithmetic", "Random", "StaticArrays"] -git-tree-sha1 = "b3f2ff58735b5f024c392fde763f29b057e4b025" -uuid = "429591f6-91af-11e9-00e2-59fbe8cec110" -version = "2.2.8" - -[[deps.ExceptionUnwrapping]] -deps = ["Test"] -git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" -uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" -version = "0.1.10" - -[[deps.Expat_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1c6317308b9dc757616f0b5cb379db10494443a7" -uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.6.2+0" - -[[deps.ExprTools]] -git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" -uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.10" - -[[deps.Extents]] -git-tree-sha1 = "94997910aca72897524d2237c41eb852153b0f65" -uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.3" - -[[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.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 = "0653c0a2396a6da5bc4766c43041ef5fd3efbe57" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.11.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 = "2de436b72c3422940cbe1367611d137008af7ec3" -uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.23.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 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" - -[[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] -git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" -uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.96+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 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" -uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.2+0" - -[[deps.FreeTypeAbstraction]] -deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] -git-tree-sha1 = "2493cdfd0740015955a8e46de4ef28f49460d8bc" -uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" -version = "0.10.3" - -[[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" -uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.14+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 = "a74c3f1cf56a3dfcdef0605f8cdb7015926aae30" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "10.3.0" - -[[deps.GPUArraysCore]] -deps = ["Adapt"] -git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" -uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.1.6" - -[[deps.GPUCompiler]] -deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "Preferences", "Scratch", "Serialization", "TOML", "TimerOutputs", "UUIDs"] -git-tree-sha1 = "ab29216184312f99ff957b32cd63c2fe9c928b91" -uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "0.26.7" - -[[deps.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "9fff8990361d5127b770e3454488360443019bb3" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.5" - -[[deps.GeometryBasics]] -deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] -git-tree-sha1 = "b62f2b2d76cee0d61a2ef2b3118cd2a3215d3134" -uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" -version = "0.4.11" - -[[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 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" -uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.2+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 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.8" - -[[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.HostCPUFeatures]] -deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] -git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" -uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.17" - -[[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5e19e1e4fa3e71b774ce746274364aef0234634e" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.11.1+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 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" -uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.5" - -[[deps.IfElse]] -git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" -uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" -version = "0.1.1" - -[[deps.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 = "437abb322a41d527c197fa800455f79d414f0a3c" -uuid = "82e4d734-157c-48bb-816b-45c225c6df19" -version = "0.6.8" - -[[deps.ImageMetadata]] -deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] -git-tree-sha1 = "355e2b974f2e3212a75dfb60519de21361ad3cb7" -uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" -version = "0.9.9" - -[[deps.ImageMorphology]] -deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] -git-tree-sha1 = "6f0a801136cb9c229aebea0df296cdcd471dbcd1" -uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" -version = "0.4.5" - -[[deps.Imath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0936ba688c6d201805a83da835b55c61a180db52" -uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" -version = "3.1.11+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 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.5" - -[[deps.InlineStrings]] -git-tree-sha1 = "45521d31238e87ee9f9732561bfee12d4eebd52d" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.2" - - [deps.InlineStrings.extensions] - ArrowTypesExt = "ArrowTypes" - ParsersExt = "Parsers" - - [deps.InlineStrings.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" - -[[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 = "14eb2b542e748570b56446f4c50fbfb2306ebc45" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.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 = "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_jll", "MacroTools", "RoundingEmulator"] -git-tree-sha1 = "433b0bb201cd76cb087b017e49244f10394ebe9c" -uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.14" -weakdeps = ["DiffRules", "ForwardDiff", "RecipesBase"] - - [deps.IntervalArithmetic.extensions] - IntervalArithmeticDiffRulesExt = "DiffRules" - IntervalArithmeticForwardDiffExt = "ForwardDiff" - IntervalArithmeticRecipesBaseExt = "RecipesBase" - -[[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 = "18c59411ece4838b18cd7f537e56cf5e41ce5bfd" -uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.15" -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", "PrecompileTools", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] -git-tree-sha1 = "67d4690d32c22e28818a434b293a374cc78473d3" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.51" - -[[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 = "c84a835e1a09b289ffcd2271bf2a337bbdda6637" -uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.0.3+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 = "d0448cebd5919e06ca5edc7a264631790de810ec" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.22" - - [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 = "7d703202e65efa1369de1279c162b915e245eed1" -uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.9" - -[[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" -uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.2+0" - -[[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] -git-tree-sha1 = "020abd49586480c1be84f57da0017b5d3db73f7c" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "8.0.0" -weakdeps = ["BFloat16s"] - - [deps.LLVM.extensions] - BFloat16sExt = "BFloat16s" - -[[deps.LLVMExtra_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "c2636c264861edc6d305e6b4d528f09566d24c5e" -uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.30+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"] -git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" -uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.2+0" - -[[deps.LaTeXStrings]] -git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" -uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.3.1" - -[[deps.LayoutPointers]] -deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "a9eaadb366f5493a5654e843864c13d8b107548c" -uuid = "10f19ff3-798f-405d-979b-55457f8fc047" -version = "0.1.17" - -[[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"] -git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" -uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.11+0" - -[[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" -uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.49.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 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" -uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.40.1+0" - -[[deps.Libuuid_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" -uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.40.1+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 = "eef2e1fc1dc38af90a18eb16e519e06d1fd10c2a" -uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -version = "2.19.0" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.28" - - [deps.LogExpFunctions.extensions] - LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" - LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" - LogExpFunctionsInverseFunctionsExt = "InverseFunctions" - - [deps.LogExpFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - -[[deps.Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[deps.LoggingExtras]] -deps = ["Dates", "Logging"] -git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" -uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.0.3" - -[[deps.LoopVectorization]] -deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "8084c25a250e00ae427a379a5b607e7aed96a2dd" -uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.171" -weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] - - [deps.LoopVectorization.extensions] - ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] - SpecialFunctionsExt = "SpecialFunctions" - -[[deps.Lz4_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "7f26c8fc5229e68484e0b3447312c98e16207d11" -uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" -version = "1.10.0+0" - -[[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] -git-tree-sha1 = "f046ccd0c6db2832a9f639e2c669c6fe867e5f4f" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2024.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", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "19d4bd098928a3263693991500d05d74dbdc2004" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.2.2+0" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.11" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "8c35d5420193841b2f367e658540e8d9e0601ed0" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.4.0+0" - -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.13" - -[[deps.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.ManualMemory]] -git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" -uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" -version = "0.1.8" - -[[deps.MappedArrays]] -git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.2" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[deps.MarkdownAST]] -deps = ["AbstractTrees", "Markdown"] -git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" -uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" -version = "0.1.2" - -[[deps.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 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.2.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 = "a640912695952b074672edb5f9aaee2f7f9fd59a" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.4" - -[[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 = "942c78ad3c95e47bcbab3eeacb0b8a846bcfb33b" -uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.91.4" - - [deps.Oceananigans.extensions] - OceananigansEnzymeExt = "Enzyme" - - [deps.Oceananigans.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - -[[deps.OffsetArrays]] -git-tree-sha1 = "1a27764e945a152f7ca7efa04de513d473e9542e" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.14.1" -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 = "8292dd5c8a38257111ada2174000a33745b06d4e" -uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.2.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", "TOML", "Zlib_jll"] -git-tree-sha1 = "2f0a1d8c79bc385ec3fcda12830c9d0e72b30e71" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.4+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "38cb508d080d21dc1128f7fb04f20387ed4c0af4" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.4.3" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.14+0" - -[[deps.OpenSpecFun_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" -uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" -version = "0.5.5+0" - -[[deps.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.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 = "cb5a2ab6763464ae0f19c86c56c63d4a2b0f5bda" -uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.52.2+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 = "fa85ac32172d96cfdb91dbc53e8e57007e5a2b5a" -uuid = "0e08944d-e94e-41b1-9406-dcf66b6a9d2e" -version = "0.19.5" - - [deps.PencilArrays.extensions] - PencilArraysAMDGPUExt = ["AMDGPU"] - PencilArraysDiffEqExt = ["DiffEqBase"] - PencilArraysHDF5Ext = ["HDF5"] - - [deps.PencilArrays.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" - HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" - -[[deps.PencilFFTs]] -deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "MPI", "PencilArrays", "Reexport", "TimerOutputs"] -git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" -uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" -version = "0.15.1" - -[[deps.Permutations]] -deps = ["Combinatorics", "LinearAlgebra", "Random"] -git-tree-sha1 = "4ca430561cf37c75964c8478eddae2d79e96ca9b" -uuid = "2ae35dd2-176d-5d53-8349-f30d82d94d4f" -version = "0.4.21" - -[[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 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" -uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.43.4+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.PolyesterWeave]] -deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] -git-tree-sha1 = "645bed98cd47f72f67316fd42fc47dee771aefcd" -uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" -version = "0.2.2" - -[[deps.PolygonOps]] -git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" -uuid = "647866c9-e3ac-4575-94e7-e3d426903924" -version = "0.1.2" - -[[deps.Polynomials]] -deps = ["LinearAlgebra", "RecipesBase", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "1a9cfb2dc2c2f1bd63f1906d72af39a79b49b736" -uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "4.0.11" - - [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 = "66b20dd35966a748321d3b2537c4584cf40387c7" -uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.3.2" - -[[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 = "8f6bc219586aef8baf0ff9a5fe16ee9c70cb65e4" -uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.10.2" - -[[deps.PtrArrays]] -git-tree-sha1 = "f011fbb92c4d401059b2212c05c0601b70f8b759" -uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" -version = "1.2.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 = "e237232771fdafbae3db5c31275303e056afaa9f" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.10.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.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"] -git-tree-sha1 = "d483cd324ce5cf5d61b77930f0bbd6cb61927d21" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.2+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 = "3484138c9fa4296a0cf46a74ca3f97b59d12b1d0" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.1.6" - - [deps.Roots.extensions] - RootsForwardDiffExt = "ForwardDiff" - RootsIntervalRootFindingExt = "IntervalRootFinding" - RootsSymPyExt = "SymPy" - RootsSymPyPythonCallExt = "SymPyPythonCall" - - [deps.Roots.weakdeps] - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" - SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" - SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" - -[[deps.Rotations]] -deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.1" -weakdeps = ["RecipesBase"] - - [deps.Rotations.extensions] - RotationsRecipesBaseExt = "RecipesBase" - -[[deps.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.SIMD]] -deps = ["PrecompileTools"] -git-tree-sha1 = "2803cab51702db743f3fda07dd1745aadfbf43bd" -uuid = "fdea26ae-647d-5447-a871-4b548cad5224" -version = "3.5.0" - -[[deps.SIMDTypes]] -git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" -uuid = "94e857df-77ce-4151-89e5-788b33177be4" -version = "0.1.0" - -[[deps.SLEEFPirates]] -deps = ["IfElse", "Static", "VectorizationBase"] -git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" -uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" -version = "0.6.43" - -[[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 = "ff11acffdb082493657550959d4feb4b6149e73a" -uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.5" - -[[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 = "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 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.4.0" -weakdeps = ["ChainRulesCore"] - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - -[[deps.StableHashTraits]] -deps = ["Compat", "PikaParser", "SHA", "Tables", "TupleTools"] -git-tree-sha1 = "a58e0d86783226378a6857f2de26d3314107e3ac" -uuid = "c5dd0088-6c3f-4803-b00e-f31a60c170fa" -version = "1.2.0" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.1" - -[[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] -git-tree-sha1 = "87d51a3ee9a4b0d2fe054bdd3fc2436258db2603" -uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.1.1" - -[[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] -git-tree-sha1 = "8963e5a083c837531298fc41599182a759a87a6d" -uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.5.1" -weakdeps = ["OffsetArrays", "StaticArrays"] - - [deps.StaticArrayInterface.extensions] - StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" - StaticArrayInterfaceStaticArraysExt = "StaticArrays" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "eeafab08ae20c62c44c8399ccb9354a04b80db50" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.7" -weakdeps = ["ChainRulesCore", "Statistics"] - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.3" - -[[deps.StaticPermutations]] -git-tree-sha1 = "193c3daa18ff3e55c1dae66acb6a762c4a3bdb0b" -uuid = "15972242-4b8f-49a0-b8a1-9ac0e7a1a45d" -version = "0.3.0" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.0" - -[[deps.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 = "bd9bd1c70cfc115cc3a30213fc725125a6b43652" -uuid = "5e0ebb24-38b0-5f93-81fe-25c709ecae67" -version = "2.1.0" - -[[deps.StridedViews]] -deps = ["LinearAlgebra", "PackageExtensionCompat"] -git-tree-sha1 = "2917996ce0fa6b8a3a85240a5e9ff930e2aeaa43" -uuid = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143" -version = "0.3.1" -weakdeps = ["CUDA"] - - [deps.StridedViews.extensions] - StridedViewsCUDAExt = "CUDA" - -[[deps.StringManipulation]] -deps = ["PrecompileTools"] -git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" -uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.3.4" - -[[deps.StructArrays]] -deps = ["ConstructionBase", "DataAPI", "Tables"] -git-tree-sha1 = "f4dc295e983502292c4c3f951dbb4e985e35b3be" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.18" -weakdeps = ["Adapt", "GPUArraysCore", "SparseArrays", "StaticArrays"] - - [deps.StructArrays.extensions] - StructArraysAdaptExt = "Adapt" - StructArraysGPUArraysCoreExt = "GPUArraysCore" - StructArraysSparseArraysExt = "SparseArrays" - StructArraysStaticArraysExt = "StaticArrays" - -[[deps.StructTypes]] -deps = ["Dates", "UUIDs"] -git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" -uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" -version = "1.10.0" - -[[deps.SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" - -[[deps.SurfaceFluxes]] -deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "89c701c87f378ce95e7ddbcd69b8f1106ba8b968" -uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.11.0" - - [deps.SurfaceFluxes.extensions] - CreateParametersExt = "ClimaParams" - - [deps.SurfaceFluxes.weakdeps] - ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.12.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 = "31834a05c8a9d52d7f56b23ae7ad1c3b72a4f1bf" -uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.13.2" - -[[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 = "80b13ddc5ae7b8605ef5a055e7f23c5b5f4775cf" -uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.12.7" - - [deps.Thermodynamics.extensions] - CreateParametersExt = "ClimaParams" - - [deps.Thermodynamics.weakdeps] - ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" - -[[deps.ThreadingUtilities]] -deps = ["ManualMemory"] -git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" -uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" -version = "0.5.2" - -[[deps.TiffImages]] -deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "SIMD", "UUIDs"] -git-tree-sha1 = "bc7fd5c91041f44636b2c134041f7e5263ce58ae" -uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.10.0" - -[[deps.TiledIteration]] -deps = ["OffsetArrays", "StaticArrayInterface"] -git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" -uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" -version = "0.5.0" - -[[deps.TimerOutputs]] -deps = ["ExprTools", "Printf"] -git-tree-sha1 = "5a13ae8a41237cff5ecf34f73eb1b8f42fff6531" -uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" -version = "0.5.24" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "96612ac5365777520c3c5396314c8cf7408f436a" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.11.1" -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 = "bf2c553f25e954a9b38c9c0593a59bb13113f9e5" -uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" -version = "0.1.5" - -[[deps.VectorizationBase]] -deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "e7f5b81c65eb858bed630fe006837b935518aca5" -uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.70" - -[[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 = "d9717ce3518dc68a99e6b96300813760d887a01d" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.1+0" - -[[deps.XSLT_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "XML2_jll", "Zlib_jll"] -git-tree-sha1 = "a54ee957f4c86b526460a720dbc882fa5edcbefc" -uuid = "aed1982a-8fda-507f-9586-7b0439959a61" -version = "1.1.41+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", "Xorg_libX11_jll"] -git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" -uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.6+0" - -[[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" -uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.11+0" - -[[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 = "bcd466676fef0878338c61e655629fa7bbc69d8e" -uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.17.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"] -git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" -uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.9.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 = "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 = "490376214c4721cdaca654041f635213c6165cb3" -uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.7+2" - -[[deps.libzip_jll]] -deps = ["Artifacts", "Bzip2_jll", "GnuTLS_jll", "JLLWrappers", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "3282b7d16ae7ac3e57ec2f3fa8fafb564d8f9f7f" -uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" -version = "1.10.1+0" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" - -[[deps.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "7d0ea0f4895ef2f5cb83645fa689e52cb55cf493" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2021.12.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" - -[[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 084aad21..08ab7c7a 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,6 +1,5 @@ [deps] CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" From c88ea507293fcefb2e9afa1e42abe45a23ea36de Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 30 Jul 2024 23:35:36 -0400 Subject: [PATCH 653/716] add visualization --- examples/near_global_omip_simulation.jl | 90 +++++++++++-------------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index d54c0e06..c2a8af78 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -20,6 +20,7 @@ using ClimaOcean using ClimaOcean.ECCO using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels +using CairoMakie using CFTime using Dates @@ -146,10 +147,7 @@ coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1 # ## Set up Output Writers # # We define output writers to save the simulation data at regular intervals. -# In this case we save the surface fluxes, the surface fields, at a fairly high frequency (half a day) -# and snapshots of the fields every 10 days. -# -# We also add a checkpoint writer to save the model state every 60 days, so that we can easily restart the simulation if needed. +# In this case we save the surface fluxes, and surface fields, at a fairly high frequency (half a day) fluxes = (u = model.velocities.u.boundary_conditions.top.condition, v = model.velocities.v.boundary_conditions.top.condition, @@ -158,28 +156,17 @@ fluxes = (u = model.velocities.u.boundary_conditions.top.condition, output_kwargs = (; overwrite_existing = true, array_type = Array{Float32}) -coupled_simulation.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; - schedule = TimeInterval(0.5days), - overwrite_existing = true, - filename = "surface_fluxes", - output_kwargs...) - -coupled_simulation.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); - schedule = TimeInterval(0.5days), - filename = "surface", - indices = (:, :, grid.Nz), - output_kwargs...) - -coupled_simulation.output_writers[:snapshots] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); - schedule = TimeInterval(10days), - filename = "snapshots", - output_kwargs...) - -coupled_simulation.output_writers[:checkpoint] = Checkpointer(model; - schedule = TimeInterval(60days), - overwrite_existing = true, - prefix = "checkpoint") - +ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; + schedule = TimeInterval(0.5days), + overwrite_existing = true, + filename = "surface_fluxes", + output_kwargs...) + +ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); + schedule = TimeInterval(0.5days), + filename = "surface", + indices = (:, :, grid.Nz), + output_kwargs...) # ## Warming up the simulation! # # As an initial condition we have interpolated ECCO tracer fields on our custom grid. @@ -198,7 +185,7 @@ run!(coupled_simulation) # ## Running the simulation # -# Now that the simulation has been warmed up, we can run it for the full year. +# Now that the simulation has been warmed up, we can run it for the full two years. # We increase the maximum time step size to 10 minutes and let the simulation run for 720 days. ocean.stop_time = 720days @@ -207,42 +194,47 @@ ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) # ## Visualizing the Results # -# after the simulation has finished, we can visualize the results. - -using CairoMakie - -u, v, w = model.velocities -T, S, e = model.tracers +# The simulation has finished, let's visualize the results. +# In this section we pull up the saved data and create visualizations using the CairoMakie.jl package. +# In particular, we generate a video of the evolution of surface fields: +# zonal velocity (u), meridional velocity (v), surface temperature (T), and turbulent kinetic energy (e) -using Oceananigans.Models.HydrostaticFreeSurfaceModels: VerticalVorticityField +u = FieldTimeSeries("surface.jld2", "u"; backend = OnDisk()) +v = FieldTimeSeries("surface.jld2", "v"; backend = OnDisk()) +T = FieldTimeSeries("surface.jld2", "T"; backend = OnDisk()) +e = FieldTimeSeries("surface.jld2", "e"; backend = OnDisk()) -ζ = VerticalVorticityField(model) -s = Field(sqrt(u^2 + v^2)) +iter = Observable(1) -compute!(ζ) -compute!(s) - -ζ = on_architecture(CPU(), ζ) -s = on_architecture(CPU(), s) -T = on_architecture(CPU(), T) -e = on_architecture(CPU(), e) +ui = @lift(interior(u[$iter], :, :, 1)) +vi = @lift(interior(u[$iter], :, :, 1)) +Ti = @lift(interior(u[$iter], :, :, 1)) +ei = @lift(interior(u[$iter], :, :, 1)) fig = Figure(size = (1000, 800)) -ax = Axis(fig[1, 1], title = "Vertical vorticity [s⁻¹]") -heatmap!(ax, interior(ζ, :, :, grid.Nz), colorrange = (-4e-5, 4e-5), colormap = :bwr) +ax = Axis(fig[1, 1], title = "Zonal velocity [ms⁻¹]") +heatmap!(ax, ui, colorrange = (-0.5, 0.5), colormap = :bwr) -ax = Axis(fig[1, 2], title = "Surface speed [ms⁻¹]") -heatmap!(ax, interior(s, :, :, grid.Nz), colorrange = (0, 0.5), colormap = :deep) +ax = Axis(fig[1, 2], title = "Meridional velocity [ms⁻¹]") +heatmap!(ax, vi, colorrange = (-0.5, 0.5), colormap = :bwr) ax = Axis(fig[2, 1], title = "Surface Temperature [Cᵒ]") -heatmap!(ax, interior(T, :, :, grid.Nz), colorrange = (-1, 30), colormap = :magma) +heatmap!(ax, Ti, colorrange = (-1, 30), colormap = :magma) ax = Axis(fig[2, 2], title = "Turbulent Kinetic Energy [m²s⁻²]") -heatmap!(ax, interior(e, :, :, grid.Nz), colorrange = (0, 1e-3), colormap = :solar) +heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) save("near_global_ocean_surface.png", fig) nothing #hide # ![](near_global_ocean_surface.png) +CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:length(u.times), framerate = 8) do i + @info "Generating frame $i of $(length(u.times))" + iter[] = i +end +nothing #hide + +# ![](near_global_ocean_surface.mp4) + From 23ddab58140abad1bdb5732e8871494038146d10 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Wed, 31 Jul 2024 14:06:39 -0400 Subject: [PATCH 654/716] check if it deploys --- docs/make.jl | 6 +-- examples/near_global_omip_simulation.jl | 70 +++++++++++++------------ 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 9e50798b..c7c1d063 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -55,7 +55,7 @@ pages = [ "Surface fluxes" => "literated/generate_surface_fluxes.md", "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", + # "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", ] ] @@ -91,10 +91,10 @@ for file in files rm(file) end -withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do +# withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], forcepush = true, devbranch = "main", push_preview = true) -end +# end diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index c2a8af78..17e83c64 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -1,15 +1,15 @@ -# # Near-global Ocean simulation +# # Near-global Ocean Simulation # # This Julia script sets up and runs a near-global ocean simulation using the Oceananigans.jl and ClimaOcean.jl packages. -# The simulation spans from 75°S to 75°N with a horizontal resolution of 1/4th of a degree and 40 vertical levels. +# The simulation covers latitudes from 75°S to 75°N with a horizontal resolution of 1/4 degree and 40 vertical levels. # -# The simulation is then ran for one year and the results are visualized using the CairoMakie.jl package. +# The simulation runs for one year, and the results are visualized using the CairoMakie.jl package. # # ## Initial Setup with Package Imports # -# The script begins by importing necessary Julia packages for visualization (CairoMakie), -# ocean modeling (Oceananigans, ClimaOcean), and handling of dates and times (CFTime, Dates). -# These packages provide the foundational tools for creating the simulation environment, +# The script begins by importing the necessary Julia packages for visualization (CairoMakie), +# ocean modeling (Oceananigans, ClimaOcean), and handling dates and times (CFTime, Dates). +# These packages provide the foundational tools for setting up the simulation environment, # including grid setup, physical processes modeling, and data visualization. using Printf @@ -27,10 +27,10 @@ using Dates # ## Grid Configuration # -# We define a near-global grid from 75°S to 75°N with a horizontal resolution of 1/4th of a degree and 40 vertical levels. +# We define a near-global grid from 75°S to 75°N with a horizontal resolution of 1/4 degree and 40 vertical levels. # The grid is created using Oceananigans' `LatitudeLongitudeGrid`. We use an exponential vertical spacing to better resolve the upper ocean layers. # The total depth of the domain is set to 6000 meters. -# Finally, we specify the architecture to be used for the simulation, which in this case is a GPU. +# Finally, we specify the architecture for the simulation, which in this case is a GPU. arch = GPU() @@ -49,9 +49,9 @@ grid = LatitudeLongitudeGrid(arch; # ## Bathymetry and Immersed Boundary # -# We retrieve the bathymetry from the ETOPO1 data by ensuring a minimum depth of 10 meters (everything shallower is considered land) -# The `interpolation_passes` parameter specifies the number of passes to interpolate the bathymetry data. The larger the number, -# the smoother the bathymetry will be. We also remove all connected regions (inland lakes) from the bathymetry data by specifying +# We retrieve the bathymetry from the ETOPO1 data, ensuring a minimum depth of 10 meters (depths shallower than this are considered land). +# The `interpolation_passes` parameter specifies the number of passes to interpolate the bathymetry data. A larger number +# results in a smoother bathymetry. We also remove all connected regions (such as inland lakes) from the bathymetry data by specifying # `connected_regions_allowed = 0`. bottom_height = retrieve_bathymetry(grid; @@ -64,8 +64,8 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) # ## Ocean Model Configuration # -# To set the ocean simulation we use the `ocean_simulation` function from ClimaOcean.jl. This allows us to build -# an ocean simulation with default parameters and numerics. In this case, the defaults are +# To configure the ocean simulation, we use the `ocean_simulation` function from ClimaOcean.jl. This function allows us to build +# an ocean simulation with default parameters and numerics. The defaults include: # - CATKE turbulence closure for vertical mixing, see [`CATKEVerticalDiffusivity`](@ref) # - WENO-based advection scheme for momentum in the vector invariant form, see [`WENOVectorInvariant`](@ref) # - WENO-based advection scheme for tracers, see [`WENO`](@ref) @@ -75,6 +75,7 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) # # The ocean model is then initialized with the ECCO2 temperature and salinity fields for January 1, 1993. + ocean = ocean_simulation(grid) model = ocean.model @@ -86,13 +87,13 @@ set!(model, # ## Prescribed Atmosphere and Radiation # -# The atmospheric data is prescribed using the JRA55 dataset. The dataset is loaded into memory in 4 snapshots at a time. +# The atmospheric data is prescribed using the JRA55 dataset, which is loaded into memory in 4 snapshots at a time. # The JRA55 dataset provides atmospheric data such as temperature, humidity, and wind fields to calculate turbulent fluxes -# through bulk formulae, see [`CrossRealmFluxes`](@ref) +# using bulk formulae, see [`CrossRealmFluxes`](@ref). # -# The radiation model specified an ocean albedo emissivity to compute the net radiative fluxes. -# The default ocean albedo is based on the Payne (1982) and depends on cloud cover (computed from -# the maximum possible incident solar radiation divided by the actual incident solar radiation), and the latitude. +# The radiation model specifies an ocean albedo emissivity to compute the net radiative fluxes. +# The default ocean albedo is based on Payne (1982) and depends on cloud cover (calculated from +# the ratio of maximum possible incident solar radiation to actual incident solar radiation) and latitude. # The ocean emissivity is set to 0.97. backend = JRA55NetCDFBackend(4) @@ -101,25 +102,25 @@ radiation = Radiation(arch) # ## Sea Ice Model # -# This simulation includes a simplified representation of an ice cover where the air-sea fluxes are shut down whenever the -# sea surface temperature is below the freezing point. Only heating fluxes are allowed. This is by no means a sea ice model -# but it allows to include atmosphere-ocean fluxes without having the temperature plummeting to - ∞. +# This simulation includes a simplified representation of ice cover where the air-sea fluxes are shut down whenever the +# sea surface temperature is below the freezing point. Only heating fluxes are allowed. This is not a full sea ice model, +# but it prevents the temperature from dropping excessively low by including atmosphere-ocean fluxes. sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() # ## The Coupled Simulation # -# Finally, we have everything it takes to define the coupled coupled, which includes the ocean, the atmosphere, and the radiation parameters. +# Finally, we define the coupled model, which includes the ocean, atmosphere, and radiation parameters. # The model is constructed using the `OceanSeaIceModel` constructor. # -# We can then construct a coupled simulation. In this case we start with a time step of 1 second and run the simulation for 720 days. -# We will eventually increase the time step size as the simulation progresses and the initialization shocks dissipate. +# We then create a coupled simulation, starting with a time step of 10 seconds and running the simulation for 10 days. +# We will eventually increase the time step size and end time as the simulation progresses and initialization shocks dissipate. # -# We also define a callback function to monitor the progress of the simulation. This function prints the current time, iteration, time step, +# We also define a callback function to monitor the simulation's progress. This function prints the current time, iteration, time step, # as well as the maximum velocities and tracers in the domain. The wall time is also printed to monitor the time taken for each iteration. coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -coupled_simulation = Simulation(coupled_model; Δt=10, stop_time = 720days) +coupled_simulation = Simulation(coupled_model; Δt=10, stop_time = 10days) wall_time = [time_ns()] @@ -147,7 +148,7 @@ coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1 # ## Set up Output Writers # # We define output writers to save the simulation data at regular intervals. -# In this case we save the surface fluxes, and surface fields, at a fairly high frequency (half a day) +# In this case, we save the surface fluxes and surface fields at a relatively high frequency (every half day). fluxes = (u = model.velocities.u.boundary_conditions.top.condition, v = model.velocities.v.boundary_conditions.top.condition, @@ -167,17 +168,18 @@ ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, mo filename = "surface", indices = (:, :, grid.Nz), output_kwargs...) -# ## Warming up the simulation! + +# ## Warming Up the Simulation # -# As an initial condition we have interpolated ECCO tracer fields on our custom grid. -# Most likely the bathymetry of the original ECCO data is different than our grid, so the initialization of the velocity -# field might lead to shocks if we use a large time step. +# As an initial condition, we have interpolated ECCO tracer fields onto our custom grid. +# The bathymetry of the original ECCO data may differ from our grid, so the initialization of the velocity +# field might cause shocks if a large time step is used. # # Therefore, we warm up with a small time step to ensure that the interpolated initial conditions adapt to the model numerics and -# parameterization without crashing. 30 days of integration with a maximum time step of 1.5 minutes should be enough to dissipate +# parameterization without causing instability. A 30-day integration with a maximum time step of 1.5 minutes should be sufficient to dissipate # spurious initialization shocks. -ocean.stop_time = 30days +ocean.stop_time = 10days wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) @@ -189,7 +191,7 @@ run!(coupled_simulation) # We increase the maximum time step size to 10 minutes and let the simulation run for 720 days. ocean.stop_time = 720days -wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 10minutes, max_change = 1.1) +wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 15minutes, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) # ## Visualizing the Results From 1f18b8e1faf4c6e5ac2a1d961fe55b21959a338e Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 1 Aug 2024 07:08:56 -0400 Subject: [PATCH 655/716] test the deploy keys --- docs/make.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index c7c1d063..ff7c3b52 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -16,10 +16,10 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ "inspect_ecco_data.jl", - "generate_surface_fluxes.jl", - "single_column_simulation.jl", + # "generate_surface_fluxes.jl", + # "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", - "near_global_omip_simulation.jl" + # "near_global_omip_simulation.jl" ] for file in to_be_literated @@ -52,8 +52,8 @@ pages = [ "Examples" => [ "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - "Surface fluxes" => "literated/generate_surface_fluxes.md", - "Single column simulation" => "literated/single_column_simulation.md", + # "Surface fluxes" => "literated/generate_surface_fluxes.md", + # "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", # "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", ] From b15e3ac349db5f1a6e668a6abf22c39f6b7e3321 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 10:34:45 -0400 Subject: [PATCH 656/716] test reading the ssh key --- docs/make.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index c7c1d063..f40a4688 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -91,10 +91,12 @@ for file in files rm(file) end -# withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do +withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do + documenter_home = ENV["HOME"] + ENV["DOCUMENTER_KEY"] = readline("$HOME/.ssh/id_rsa") deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], forcepush = true, devbranch = "main", push_preview = true) -# end +end From 4f5550eaaab7588205533beaff232823f6b847f7 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 11:11:22 -0400 Subject: [PATCH 657/716] typo --- docs/make.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index 3450cbf0..4808ca3b 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -93,7 +93,7 @@ end withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do documenter_home = ENV["HOME"] - ENV["DOCUMENTER_KEY"] = readline("$HOME/.ssh/id_rsa") + ENV["DOCUMENTER_KEY"] = readline("$(documenter_home)/.ssh/id_rsa") deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], forcepush = true, From e81ef73cfa803ce953caca6918246f2f07c99b39 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 11:30:11 -0400 Subject: [PATCH 658/716] the docs deploy? --- docs/make.jl | 8 +++---- examples/generate_surface_fluxes.jl | 29 +++++++++++++------------ examples/near_global_omip_simulation.jl | 6 ++++- examples/single_column_simulation.jl | 18 ++++++--------- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 4808ca3b..463df282 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -16,10 +16,10 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ "inspect_ecco_data.jl", - # "generate_surface_fluxes.jl", + "generate_surface_fluxes.jl", # "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", - # "near_global_omip_simulation.jl" + "near_global_omip_simulation.jl" ] for file in to_be_literated @@ -52,10 +52,10 @@ pages = [ "Examples" => [ "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - # "Surface fluxes" => "literated/generate_surface_fluxes.md", + "Surface fluxes" => "literated/generate_surface_fluxes.md", # "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - # "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", + "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", ] ] diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index 1f54ba95..8bcb5349 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -1,4 +1,4 @@ -# Calculating surface fluxes with an ocean and an atmosphere +# # Calculating surface fluxes with a prescribed ocean and an atmosphere # # ClimaOcean uses bulk formulae to estimate the surface exchange of momentum, # heat, and water vapor between the atmosphere and the ocean. @@ -37,6 +37,7 @@ nothing #hide # ![](ecco_continents.png) # Next, we construct our atmosphere and ocean. +# # The atmosphere is prescribed, downloaded from the JRA55 dataset. # It contains: # - zonal wind `u` @@ -67,7 +68,7 @@ ocean = ocean_simulation(grid; momentum_advection = nothing, # our ocean with initial conditions. To do this, we can use the ECCO2 dataset by # `set!`ting the model with the `ECCOMetadata`. If no date is specified, # the fields corresponding to January 1st, 1992 (the first available date in -# ECCO2) are used. +# ECCO2 dataset) are used. # This command will download the fields to the local machine. set!(ocean.model; @@ -91,13 +92,13 @@ coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) # Now that the surface fluxes are computed, we can extract and visualize them. # The turbulent fluxes are stored in `coupled_model.fluxes.turbulent`. # -# Qs = coupled_model.fluxes.turbulent.fields.sensible_heat : the sensible heat flux -# Ql = coupled_model.fluxes.turbulent.fields.latent_heat : the latent heat flux -# τx = coupled_model.fluxes.turbulent.fields.x_momentum : the zonal wind stress -# τy = coupled_model.fluxes.turbulent.fields.y_momentum : the meridional wind stress -# Mv = coupled_model.fluxes.turbulent.fields.water_vapor : evaporation +# Qs = coupled_model.fluxes.turbulent.fields.sensible_heat : the sensible heat flux (in Wm⁻²) +# Ql = coupled_model.fluxes.turbulent.fields.latent_heat : the latent heat flux (in Wm⁻²) +# τx = coupled_model.fluxes.turbulent.fields.x_momentum : the zonal wind stress (in Nm) +# τy = coupled_model.fluxes.turbulent.fields.y_momentum : the meridional wind stress (in Nm) +# Mv = coupled_model.fluxes.turbulent.fields.water_vapor : evaporation (in kg m⁻²s⁻¹) # -# They are 3D fields with one point in the vertical. To extract the data, we use the +# They are 2D fields (3D data structures with one point in the vertical). To extract the data, we use the # `interior` functionality from Oceananigans. turbulent_fluxes = coupled_model.fluxes.turbulent.fields @@ -109,21 +110,21 @@ Ql = interior(turbulent_fluxes.latent_heat, :, :, 1) Mv = interior(turbulent_fluxes.water_vapor, :, :, 1) nothing -fig = Figure() +fig = Figure(size = (1500, 1500)) -ax = Axis(fig[1, 1], title = "Sensible heat flux") +ax = Axis(fig[1, 1], title = "Sensible heat flux [Wm⁻²]") heatmap!(ax, Qs; colormap = :bwr) -ax = Axis(fig[1, 2], title = "Latent heat flux") +ax = Axis(fig[1, 2], title = "Latent heat flux [Wm⁻²]") heatmap!(ax, Ql; colormap = :bwr) -ax = Axis(fig[2, 1], title = "Zonal wind stress") +ax = Axis(fig[2, 1], title = "Zonal wind stress [Nm]") heatmap!(ax, τx; colormap = :bwr) -ax = Axis(fig[2, 2], title = "Meridional wind stress") +ax = Axis(fig[2, 2], title = "Meridional wind stress [Nm]") heatmap!(ax, τy; colormap = :bwr) -ax = Axis(fig[3, 1], title = "Evaporation") +ax = Axis(fig[3, 1], title = "Evaporation [kg m⁻²s⁻¹]") heatmap!(ax, Mv; colormap = :bwr) save("turbulent_fluxes.png", fig) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 17e83c64..57d627e7 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -213,19 +213,23 @@ vi = @lift(interior(u[$iter], :, :, 1)) Ti = @lift(interior(u[$iter], :, :, 1)) ei = @lift(interior(u[$iter], :, :, 1)) -fig = Figure(size = (1000, 800)) +fig = Figure(size = (2000, 1500)) ax = Axis(fig[1, 1], title = "Zonal velocity [ms⁻¹]") heatmap!(ax, ui, colorrange = (-0.5, 0.5), colormap = :bwr) +hidedecorations!(ax) ax = Axis(fig[1, 2], title = "Meridional velocity [ms⁻¹]") heatmap!(ax, vi, colorrange = (-0.5, 0.5), colormap = :bwr) +hidedecorations!(ax) ax = Axis(fig[2, 1], title = "Surface Temperature [Cᵒ]") heatmap!(ax, Ti, colorrange = (-1, 30), colormap = :magma) +hidedecorations!(ax) ax = Axis(fig[2, 2], title = "Turbulent Kinetic Energy [m²s⁻²]") heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) +hidedecorations!(ax) save("near_global_ocean_surface.png", fig) nothing #hide diff --git a/examples/single_column_simulation.jl b/examples/single_column_simulation.jl index e8ef7370..904c3bee 100644 --- a/examples/single_column_simulation.jl +++ b/examples/single_column_simulation.jl @@ -267,7 +267,7 @@ lines!(axτ, times, interior(ρτy, 1, 1, 1, :), label="Meridional") vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) axislegend(axτ) -lines!(axT, times, Tat[1:Nt] .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") +lines!(axT, times, Tat[1:Nt] .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") lines!(axT, times, interior(T, 1, 1, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) axislegend(axT) @@ -279,7 +279,6 @@ lines!(axQ, times, - interior(Qlw, 1, 1, 1, 1:Nt), color=colors[5], label="Longw 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[1:Nt], label="Prescribed freshwater flux") lines!(axF, times, - interior(Ev, 1, 1, 1, 1:Nt), label="Evaporation") vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) @@ -324,13 +323,10 @@ Smax = maximum(interior(S)) Smin = minimum(interior(S)) xlims!(axSz, Smin - 0.2, Smax + 0.2) -save("single_column_profiles.png", fig) -nothing # hide - -# ![](single_column_profiles.png) - -# record(fig, "$(location_name)_single_column_simulation.mp4", 1:8:Nt, framerate=24) do nn -# @info "Drawing frame $nn of $Nt..." -# n[] = nn -# end +record(fig, "single_column_profiles.mp4", 1:8:Nt, framerate=24) do nn + @info "Drawing frame $nn of $Nt..." + n[] = nn +end +nothing #hide +# ![](single_column_profiles.mp4) \ No newline at end of file From 6008b791eecedbc07c2c989751ce3d95964ae0cf Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 13:46:55 -0400 Subject: [PATCH 659/716] check deployment again --- docs/make.jl | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 463df282..2f03662e 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,11 +15,11 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - "inspect_ecco_data.jl", - "generate_surface_fluxes.jl", + # "inspect_ecco_data.jl", + # "generate_surface_fluxes.jl", # "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", - "near_global_omip_simulation.jl" + # "near_global_omip_simulation.jl" ] for file in to_be_literated @@ -50,13 +50,13 @@ pages = [ "Function index" => "library/function_index.md", ], - "Examples" => [ - "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - "Surface fluxes" => "literated/generate_surface_fluxes.md", - # "Single column simulation" => "literated/single_column_simulation.md", - # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", - ] + # "Examples" => [ + # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + # "Surface fluxes" => "literated/generate_surface_fluxes.md", + # # "Single column simulation" => "literated/single_column_simulation.md", + # # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", + # "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", + # ] ] makedocs( @@ -91,12 +91,10 @@ for file in files rm(file) end -withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do - documenter_home = ENV["HOME"] - ENV["DOCUMENTER_KEY"] = readline("$(documenter_home)/.ssh/id_rsa") - deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", - versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], - forcepush = true, - devbranch = "main", - push_preview = true) -end +documenter_home = ENV["HOME"] +ENV["DOCUMENTER_KEY"] = readline("$(documenter_home)/.ssh/id_rsa") +deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", + versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], + forcepush = true, + devbranch = "main", + push_preview = true) \ No newline at end of file From 87a1ad4c5a16cef65e8e1b32828e8a055c336381 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 16:20:41 -0400 Subject: [PATCH 660/716] test docs deployment --- docs/make.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 2f03662e..f99fba76 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -91,10 +91,10 @@ for file in files rm(file) end -documenter_home = ENV["HOME"] -ENV["DOCUMENTER_KEY"] = readline("$(documenter_home)/.ssh/id_rsa") -deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", - versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], - forcepush = true, - devbranch = "main", - push_preview = true) \ No newline at end of file +withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do + deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", + versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], + forcepush = true, + devbranch = "main", + push_preview = true) +end From 447666e50a2fcd83cf619560fa8b4925855eb6a7 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 16:29:27 -0400 Subject: [PATCH 661/716] remove `winthenv` --- docs/make.jl | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index f99fba76..8e5219e8 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -51,12 +51,12 @@ pages = [ ], # "Examples" => [ - # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - # "Surface fluxes" => "literated/generate_surface_fluxes.md", - # # "Single column simulation" => "literated/single_column_simulation.md", - # # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - # "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", - # ] + # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + # "Surface fluxes" => "literated/generate_surface_fluxes.md", + # "Single column simulation" => "literated/single_column_simulation.md", + # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", + # "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", + # ] ] makedocs( @@ -91,10 +91,10 @@ for file in files rm(file) end -withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do - deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", - versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], - forcepush = true, - devbranch = "main", - push_preview = true) -end +# withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do +deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", + versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], + forcepush = true, + devbranch = "main", + push_preview = true) +# end From 3b92297b6fbf7f2abf98e480392638513654922c Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 16:48:58 -0400 Subject: [PATCH 662/716] near global simulation in docs --- docs/make.jl | 32 ++++++++++++------------- examples/near_global_omip_simulation.jl | 6 ++--- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 8e5219e8..0edadc4c 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,11 +15,11 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - # "inspect_ecco_data.jl", - # "generate_surface_fluxes.jl", - # "single_column_simulation.jl", + "inspect_ecco_data.jl", + "generate_surface_fluxes.jl", + "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", - # "near_global_omip_simulation.jl" + "near_global_omip_simulation.jl" ] for file in to_be_literated @@ -50,13 +50,13 @@ pages = [ "Function index" => "library/function_index.md", ], - # "Examples" => [ - # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - # "Surface fluxes" => "literated/generate_surface_fluxes.md", - # "Single column simulation" => "literated/single_column_simulation.md", + "Examples" => [ + "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + "Surface fluxes" => "literated/generate_surface_fluxes.md", + "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - # "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", - # ] + "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", + ] ] makedocs( @@ -91,10 +91,8 @@ for file in files rm(file) end -# withenv("GITHUB_REPOSITORY" => "CliMA/ClimaOceanDocumentation") do -deploydocs( repo = "github.com/CliMA/ClimaOceanDocumentation.git", - versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], - forcepush = true, - devbranch = "main", - push_preview = true) -# end +deploydocs(repo = "github.com/CliMA/ClimaOceanDocumentation.git", + versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], + forcepush = true, + devbranch = "main", + push_preview = true) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 57d627e7..0497f220 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -182,7 +182,6 @@ ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, mo ocean.stop_time = 10days wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) - run!(coupled_simulation) # ## Running the simulation @@ -190,9 +189,10 @@ run!(coupled_simulation) # Now that the simulation has been warmed up, we can run it for the full two years. # We increase the maximum time step size to 10 minutes and let the simulation run for 720 days. -ocean.stop_time = 720days +ocean.stop_time = 100days wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 15minutes, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +run!(coupled_simulation) # ## Visualizing the Results # From b7c171300b57c08b1beae70dc0eb74ce5f893c7c Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 17:34:09 -0400 Subject: [PATCH 663/716] better comments --- examples/generate_bathymetry.jl | 80 ++++++++++++----------------- examples/generate_surface_fluxes.jl | 2 +- 2 files changed, 35 insertions(+), 47 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index f98ac860..3719d6d1 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -1,70 +1,58 @@ -using CairoMakie +# # Generate bathymetry data for the Mediterranean Sea +# +# This script shows how to configure an Immersed boundary grid with realistic bathymetry using ClimaOcean.jl +# by generating the bathymetry data for the Mediterranean Sea. +# +# For this example, we need Oceananigans for the LatitudeLongitudeGrid and Field utilities, +# ClimaOcean to donwload and regrid the bathymetry, and CairoMakie to visualize the grid. + +using ClimaOcean using Oceananigans -using ClimaOcean.Bathymetry: regrid_bathymetry - -##### -##### Quarter degree near-global grid -##### - -grid = LatitudeLongitudeGrid(CPU(); - size = (4 * 360, 4 * 160, 1), - latitude = (-80, 80), - longitude = (-180, 180), - z = (0, 1), - 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(size=(2400, 1200)) -ax = Axis(fig[1, 1]) -heatmap!(ax, λ, φ, interior(h, :, :, 1), nan_color=:white, colorrange=(-5000, 0)) - -λp = -112.45 -φp = 42.86 -text = "😻" -text!(ax, λp, φp; text, fontsize=30) - -display(fig) +using CairoMakie -##### -##### Regional Mediterranean grid -##### +# We start by defining a gridded domain for the Mediterranean Sea using the `LatitudeLongitudeGrid` from Oceananigans. +# To have a reasonable resolution, we set a grid size to 1/25ᵒ of a degree in both latitude and longitude. +# +# The Mediterranean sea is positioned roughly between 25ᵒ and 50ᵒ latitude and -10ᵒ and 45ᵒ longitude. -# 1/25th degree resolution Nλ = 25 * 55 Nφ = 25 * 25 -grid = LatitudeLongitudeGrid(CPU(); - size = (Nλ, Nφ, 1), +grid = LatitudeLongitudeGrid(size = (Nλ, Nφ, 1), latitude = (25, 50), longitude = (-10, 45), - z = (0, 1), - halo = (4, 4, 4)) + z = (0, 1)) + +# Next, we generate the bathymetry data for the Mediterranean Sea using the `regrid_bathymetry` function from ClimaOcean. +# The function downloads the bathymetry data from the ETOPO1 dataset, regrids it to the provided grid, and returns the bathymetry field. +# The three different regidding procedures here show the effect of different parameters on the generated bathymetry. +# +# - `h_rough` shows the output of the function with default parameters, which means only one interpolation passes and no restrictions on connected regions. +# - `h_smooth` shows the output of the function with 40 interpolation passes, which results in a smoother bathymetry. +# - `h_nolakes` shows the output of the function with `connected_regions_allowed = 0`, which means that the function does not allow connected regions in the bathymetry +# (e.g., lakes) and fills them with land. + +h_rough = regrid_bathymetry(grid) +h_smooth = regrid_bathymetry(grid; interpolation_passes = 40) +h_nolakes = regrid_bathymetry(grid; connected_regions_allowed = 0) -h_smooth = regrid_bathymetry(grid, height_above_water=1, minimum_depth=10, interpolation_passes = 40) -h_rough = regrid_bathymetry(grid, height_above_water=1, minimum_depth=10, interpolation_passes = 1) -h_nolakes = regrid_bathymetry(grid, height_above_water=1, minimum_depth=10, connected_regions_allowed = 0) +# Finally, we visualize the generated bathymetry data for the Mediterranean Sea using CairoMakie. λ, φ, z = nodes(h_smooth) land_smooth = interior(h_smooth) .>= 0 interior(h_smooth)[land_smooth] .= NaN land_rough = interior(h_rough) .>= 0 -interior(h_rough)[land_rough] .= NaN +interior(h_rough)[land_rough] .= NaNxe land_nolakes = interior(h_nolakes) .>= 0 interior(h_nolakes)[land_nolakes] .= NaN fig = Figure(resolution=(2400, 800)) ax = Axis(fig[1, 1]) -heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) +heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white) ax = Axis(fig[1, 2]) -heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) +heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white) ax = Axis(fig[1, 3]) -heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white) #, colorrange=(-5000, 0)) +heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white) display(fig) diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index 8bcb5349..a185d405 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -1,4 +1,4 @@ -# # Calculating surface fluxes with a prescribed ocean and an atmosphere +# # Surface fluxes from prescribed ocean and atmosphere # # ClimaOcean uses bulk formulae to estimate the surface exchange of momentum, # heat, and water vapor between the atmosphere and the ocean. From e3c4908745dcd061ad1c82ac1afaa46903c424ab Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 17:34:28 -0400 Subject: [PATCH 664/716] another test --- docs/make.jl | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 0edadc4c..c768edc5 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,11 +15,11 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - "inspect_ecco_data.jl", - "generate_surface_fluxes.jl", - "single_column_simulation.jl", - # "mediterranean_simulation_with_ecco_restoring.jl", - "near_global_omip_simulation.jl" + # "inspect_ecco_data.jl", + # "generate_surface_fluxes.jl", + # "single_column_simulation.jl", + # # "mediterranean_simulation_with_ecco_restoring.jl", + # "near_global_omip_simulation.jl" ] for file in to_be_literated @@ -50,13 +50,13 @@ pages = [ "Function index" => "library/function_index.md", ], - "Examples" => [ - "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - "Surface fluxes" => "literated/generate_surface_fluxes.md", - "Single column simulation" => "literated/single_column_simulation.md", - # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", - ] + # "Examples" => [ + # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + # "Surface fluxes" => "literated/generate_surface_fluxes.md", + # "Single column simulation" => "literated/single_column_simulation.md", + # # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", + # "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", + # ] ] makedocs( From 297bacddcbf18890e141cf4a57031684f5425011 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Fri, 2 Aug 2024 06:34:22 -0400 Subject: [PATCH 665/716] try new keys --- docs/make.jl | 24 ++++++++++++------------ examples/near_global_omip_simulation.jl | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index c768edc5..0edadc4c 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,11 +15,11 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - # "inspect_ecco_data.jl", - # "generate_surface_fluxes.jl", - # "single_column_simulation.jl", - # # "mediterranean_simulation_with_ecco_restoring.jl", - # "near_global_omip_simulation.jl" + "inspect_ecco_data.jl", + "generate_surface_fluxes.jl", + "single_column_simulation.jl", + # "mediterranean_simulation_with_ecco_restoring.jl", + "near_global_omip_simulation.jl" ] for file in to_be_literated @@ -50,13 +50,13 @@ pages = [ "Function index" => "library/function_index.md", ], - # "Examples" => [ - # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", - # "Surface fluxes" => "literated/generate_surface_fluxes.md", - # "Single column simulation" => "literated/single_column_simulation.md", - # # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - # "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", - # ] + "Examples" => [ + "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + "Surface fluxes" => "literated/generate_surface_fluxes.md", + "Single column simulation" => "literated/single_column_simulation.md", + # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", + "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", + ] ] makedocs( diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 0497f220..6476a124 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -189,8 +189,8 @@ run!(coupled_simulation) # Now that the simulation has been warmed up, we can run it for the full two years. # We increase the maximum time step size to 10 minutes and let the simulation run for 720 days. -ocean.stop_time = 100days -wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 15minutes, max_change = 1.1) +ocean.stop_time = 60days +wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 10minutes, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) run!(coupled_simulation) From 2a6d7a919a811eef37166933f9d3bcd5986d3e4f Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Fri, 2 Aug 2024 15:34:01 -0400 Subject: [PATCH 666/716] progress it stuck on single_column_grid --- docs/make.jl | 4 +- prototype_omip_simulation/Manifest.toml | 224 +----------------------- 2 files changed, 6 insertions(+), 222 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 0edadc4c..cd41f1b2 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -17,7 +17,7 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ "inspect_ecco_data.jl", "generate_surface_fluxes.jl", - "single_column_simulation.jl", + # "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", "near_global_omip_simulation.jl" ] @@ -53,7 +53,7 @@ pages = [ "Examples" => [ "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", "Surface fluxes" => "literated/generate_surface_fluxes.md", - "Single column simulation" => "literated/single_column_simulation.md", + # "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", ] diff --git a/prototype_omip_simulation/Manifest.toml b/prototype_omip_simulation/Manifest.toml index 9ec3daf5..3d4f43c0 100644 --- a/prototype_omip_simulation/Manifest.toml +++ b/prototype_omip_simulation/Manifest.toml @@ -180,12 +180,6 @@ git-tree-sha1 = "bcba305388e16aa5c879e896726db9e71b4942c6" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" version = "0.14.0+1" -[[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 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" -uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.0+2" - [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] git-tree-sha1 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" @@ -438,18 +432,6 @@ git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" version = "0.1.10" -[[deps.FFMPEG]] -deps = ["FFMPEG_jll"] -git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8" -uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" -version = "0.4.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 = "4820348781ae578893311153d69049a93d05f39d" @@ -477,12 +459,6 @@ git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" version = "0.8.5" -[[deps.Fontconfig_jll]] -deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] -git-tree-sha1 = "db16beca600632c95fc8aca29890d83788dd8b23" -uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" -version = "2.13.96+0" - [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" @@ -493,18 +469,6 @@ weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] ForwardDiffStaticArraysExt = "StaticArrays" -[[deps.FreeType2_jll]] -deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "5c1d8ae0efc6c2e7b1fc502cbe25def8f661b7bc" -uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.2+0" - -[[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1ed150b39aebcc805c26b93a8d0122c940f64ce2" -uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.14+0" - [[deps.Future]] deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" @@ -532,12 +496,6 @@ git-tree-sha1 = "518ebd058c9895de468a8c255797b0c53fdb44dd" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" version = "0.26.5" -[[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" @@ -550,12 +508,6 @@ 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 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" -uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.2+0" - [[deps.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" @@ -567,12 +519,6 @@ 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.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" @@ -585,12 +531,6 @@ git-tree-sha1 = "d1d712be3164d61d1fb98e7ce9bcbc6cc06b45ed" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" version = "1.10.8" -[[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.HostCPUFeatures]] deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" @@ -727,12 +667,6 @@ version = "0.9.21" [deps.KernelAbstractions.weakdeps] EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" -[[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "170b660facf5df5de098d866564877e119141cbd" -uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.2+0" - [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Requires", "Unicode"] git-tree-sha1 = "389aea28d882a40b5e1747069af71bdbd47a1cae" @@ -769,12 +703,6 @@ weakdeps = ["Serialization"] [deps.LRUCache.extensions] SerializationExt = ["Serialization"] -[[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" -uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.2+0" - [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" @@ -822,42 +750,12 @@ 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"] -git-tree-sha1 = "9fd170c4bbfd8b935fdc5f8b7aa33532c991a673" -uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" -version = "1.8.11+0" - -[[deps.Libgpg_error_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "fbb1f2bef882392312feb1ede3615ddc1e9b99ed" -uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" -version = "1.49.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 = "0c4f9c4f1a50d8f35048fa0532dabbadf702f81e" -uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.40.1+0" - -[[deps.Libuuid_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5ee6203157c120d79034c748a2acba45b82b8807" -uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.40.1+0" - [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -1067,12 +965,6 @@ 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" @@ -1107,24 +999,18 @@ git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.5+0" -[[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.OrthogonalSphericalShellGrids]] -deps = ["Adapt", "CUDA", "Documenter", "DocumenterTools", "FFMPEG", "JLD2", "JSON3", "KernelAbstractions", "Oceananigans", "OffsetArrays", "Printf"] -git-tree-sha1 = "1a31c10d9eeec98bfdbb66282b39be643db31fea" +deps = ["Adapt", "CUDA", "Documenter", "DocumenterTools", "JLD2", "KernelAbstractions", "MPI", "Oceananigans", "OffsetArrays"] +git-tree-sha1 = "f9614694b607bd2168aef61a819f98a43b9b81c5" repo-rev = "main" -repo-url = "https://github.com/simone-silvestri/OrthogonalSphericalShellGrids.jl.git" +repo-url = "https://github.com/CliMA/OrthogonalSphericalShellGrids.jl" uuid = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" -version = "0.1.0" +version = "0.1.2" [[deps.P11Kit_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1177,12 +1063,6 @@ git-tree-sha1 = "bd69f3f0ee248cfb4241800aefb705b5ded592ff" uuid = "4a48f351-57a6-4416-9ec4-c37015456aae" version = "0.15.1" -[[deps.Pixman_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "35621f10a7531bc8fa58f74610b1bfb70a3cfc6b" -uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.43.4+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" @@ -1637,66 +1517,12 @@ git-tree-sha1 = "52ff2af32e591541550bd753c0da8b9bc92bb9d9" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" version = "2.12.7+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", "Xorg_libX11_jll"] -git-tree-sha1 = "d2d1a5c49fae4ba39983f63de6afcbea47194e85" -uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.6+0" - -[[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -git-tree-sha1 = "47e45cd78224c53109495b3e324df0c37bb61fbe" -uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" -version = "0.9.11+0" - -[[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" @@ -1714,41 +1540,11 @@ git-tree-sha1 = "46bf7be2917b59b761247be3f317ddf75e50e997" uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" version = "1.1.2+0" -[[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1827acba325fdcdf1d2647fc8d5301dd9ba43a9d" -uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.9.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 = "d7015d2e18a5fd9a4f47de711837e980519781a4" -uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.43+1" - -[[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" @@ -1770,15 +1566,3 @@ version = "2021.12.0+0" 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 8013eef44bb739920c334f65f7f842bab4efa731 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Fri, 2 Aug 2024 19:51:26 -0400 Subject: [PATCH 667/716] test only with snapshot --- examples/near_global_omip_simulation.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 6476a124..d199db00 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -236,11 +236,11 @@ nothing #hide # ![](near_global_ocean_surface.png) -CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:length(u.times), framerate = 8) do i - @info "Generating frame $i of $(length(u.times))" - iter[] = i -end -nothing #hide +# CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:length(u.times), framerate = 8) do i +# @info "Generating frame $i of $(length(u.times))" +# iter[] = i +# end +# nothing #hide -# ![](near_global_ocean_surface.mp4) +# # ![](near_global_ocean_surface.mp4) From 5df3f22b45f4eeae61f2f2eb838519f4f176f43d Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sat, 3 Aug 2024 10:28:48 +1000 Subject: [PATCH 668/716] gif -> mp4 gifs are very big in size since there is no compression --- examples/inspect_ecco_data.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/inspect_ecco_data.jl b/examples/inspect_ecco_data.jl index 71ec6609..9ee3ab69 100644 --- a/examples/inspect_ecco_data.jl +++ b/examples/inspect_ecco_data.jl @@ -76,7 +76,7 @@ text!(axS, 50, 50, text=depth_str, justification=:center, fontsize=24) stillframes = 10 movingframes = Nz -record(fig, "ECCO_temperature_salinity.gif", framerate=4) do io +record(fig, "ECCO_temperature_salinity.mp4", framerate=4) do io [recordframe!(io) for _ = 1:stillframes] @@ -94,4 +94,6 @@ record(fig, "ECCO_temperature_salinity.gif", framerate=4) do io [recordframe!(io) for _ = 1:stillframes] end +nothing #hide +# ![](ECCO_temperature_salinity.mp4) From cf46b69513dda1a9ccec906bef5a981051a7918c Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 08:04:59 -0400 Subject: [PATCH 669/716] remove also "inspect_ecco_data.jl" --- docs/make.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index cd41f1b2..1d0243d7 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,7 +15,7 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples") const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ - "inspect_ecco_data.jl", + # "inspect_ecco_data.jl", "generate_surface_fluxes.jl", # "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", @@ -51,7 +51,7 @@ pages = [ ], "Examples" => [ - "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", "Surface fluxes" => "literated/generate_surface_fluxes.md", # "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", From 91e01392868ddcb57e92afaf2d033b355bb994a1 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 11:00:21 -0400 Subject: [PATCH 670/716] try with a video? --- examples/generate_surface_fluxes.jl | 17 +++++++++----- examples/near_global_omip_simulation.jl | 31 +++++++++++-------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index a185d405..9c33e7c4 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -92,11 +92,11 @@ coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) # Now that the surface fluxes are computed, we can extract and visualize them. # The turbulent fluxes are stored in `coupled_model.fluxes.turbulent`. # -# Qs = coupled_model.fluxes.turbulent.fields.sensible_heat : the sensible heat flux (in Wm⁻²) -# Ql = coupled_model.fluxes.turbulent.fields.latent_heat : the latent heat flux (in Wm⁻²) -# τx = coupled_model.fluxes.turbulent.fields.x_momentum : the zonal wind stress (in Nm) -# τy = coupled_model.fluxes.turbulent.fields.y_momentum : the meridional wind stress (in Nm) -# Mv = coupled_model.fluxes.turbulent.fields.water_vapor : evaporation (in kg m⁻²s⁻¹) +# `Qs = coupled_model.fluxes.turbulent.fields.sensible_heat` : the sensible heat flux (in Wm⁻²) +# `Ql = coupled_model.fluxes.turbulent.fields.latent_heat` : the latent heat flux (in Wm⁻²) +# `τx = coupled_model.fluxes.turbulent.fields.x_momentum ` : the zonal wind stress (in Nm) +# `τy = coupled_model.fluxes.turbulent.fields.y_momentum ` : the meridional wind stress (in Nm) +# `Mv = coupled_model.fluxes.turbulent.fields.water_vapor` : evaporation (in kg m⁻²s⁻¹) # # They are 2D fields (3D data structures with one point in the vertical). To extract the data, we use the # `interior` functionality from Oceananigans. @@ -110,22 +110,27 @@ Ql = interior(turbulent_fluxes.latent_heat, :, :, 1) Mv = interior(turbulent_fluxes.water_vapor, :, :, 1) nothing -fig = Figure(size = (1500, 1500)) +fig = Figure(size = (1000, 2000)) ax = Axis(fig[1, 1], title = "Sensible heat flux [Wm⁻²]") heatmap!(ax, Qs; colormap = :bwr) +hidedecoration!(ax) ax = Axis(fig[1, 2], title = "Latent heat flux [Wm⁻²]") heatmap!(ax, Ql; colormap = :bwr) +hidedecoration!(ax) ax = Axis(fig[2, 1], title = "Zonal wind stress [Nm]") heatmap!(ax, τx; colormap = :bwr) +hidedecoration!(ax) ax = Axis(fig[2, 2], title = "Meridional wind stress [Nm]") heatmap!(ax, τy; colormap = :bwr) +hidedecoration!(ax) ax = Axis(fig[3, 1], title = "Evaporation [kg m⁻²s⁻¹]") heatmap!(ax, Mv; colormap = :bwr) +hidedecoration!(ax) save("turbulent_fluxes.png", fig) nothing #hide diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index d199db00..e8eaa527 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -135,15 +135,15 @@ function progress(sim) step_time = 1e-9 * (time_ns() - wall_time[1]) @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", - prettytime(sim.model.clock.time), - sim.model.clock.iteration, - prettytime(sim.Δt), + prettytime(ocean.model.clock.time), + ocean.model.clock.iteration, + prettytime(ocean.Δt), umax..., Tmax, Tmin, prettytime(step_time)) wall_time[1] = time_ns() end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(10)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) # ## Set up Output Writers # @@ -181,7 +181,7 @@ ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, mo ocean.stop_time = 10days wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(1)) +ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) run!(coupled_simulation) # ## Running the simulation @@ -206,14 +206,16 @@ v = FieldTimeSeries("surface.jld2", "v"; backend = OnDisk()) T = FieldTimeSeries("surface.jld2", "T"; backend = OnDisk()) e = FieldTimeSeries("surface.jld2", "e"; backend = OnDisk()) -iter = Observable(1) +Nt = length(u.times) + +iter = Observable(Nt) ui = @lift(interior(u[$iter], :, :, 1)) vi = @lift(interior(u[$iter], :, :, 1)) Ti = @lift(interior(u[$iter], :, :, 1)) ei = @lift(interior(u[$iter], :, :, 1)) -fig = Figure(size = (2000, 1500)) +fig = Figure(size = (1000, 750)) ax = Axis(fig[1, 1], title = "Zonal velocity [ms⁻¹]") heatmap!(ax, ui, colorrange = (-0.5, 0.5), colormap = :bwr) @@ -231,16 +233,11 @@ ax = Axis(fig[2, 2], title = "Turbulent Kinetic Energy [m²s⁻²]") heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) hidedecorations!(ax) -save("near_global_ocean_surface.png", fig) +CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:length(u.times), framerate = 8) do i + @info "Generating frame $i of $(length(u.times))" + iter[] = i +end nothing #hide -# ![](near_global_ocean_surface.png) - -# CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:length(u.times), framerate = 8) do i -# @info "Generating frame $i of $(length(u.times))" -# iter[] = i -# end -# nothing #hide - -# # ![](near_global_ocean_surface.mp4) +# ![](near_global_ocean_surface.mp4) From 4a007d95ec81ff85fdb518a70097444035667b42 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 11:00:52 -0400 Subject: [PATCH 671/716] print every 500 iterations --- examples/near_global_omip_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index e8eaa527..87d3e8a9 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -143,7 +143,7 @@ function progress(sim) wall_time[1] = time_ns() end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(500)) # ## Set up Output Writers # From 70f7c5e4f23550bbfffebddbee48e141c9e616c4 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 11:02:31 -0400 Subject: [PATCH 672/716] max abs --- examples/near_global_omip_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 87d3e8a9..d91392a7 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -131,10 +131,10 @@ function progress(sim) Tmax = maximum(interior(T)) Tmin = minimum(interior(T)) - umax = maximum(interior(u)), maximum(interior(v)), maximum(interior(w)) + umax = maximum(abs, interior(u)), maximum(abs, interior(v)), maximum(abs, interior(w)) step_time = 1e-9 * (time_ns() - wall_time[1]) - @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(trac): %.2f, %.2f, wtime: %s \n", + @info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(T): %.2f, min(T): %.2f, wtime: %s \n", prettytime(ocean.model.clock.time), ocean.model.clock.iteration, prettytime(ocean.Δt), From 7463008dcca7ef0a005472a07767f92ec05cb84b Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 11:03:30 -0400 Subject: [PATCH 673/716] some changes to simulation details --- examples/near_global_omip_simulation.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index d91392a7..09f5cda3 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -190,7 +190,8 @@ run!(coupled_simulation) # We increase the maximum time step size to 10 minutes and let the simulation run for 720 days. ocean.stop_time = 60days -wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 10minutes, max_change = 1.1) +coupled_simulation.stop_time = 60days +wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 15minutes, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) run!(coupled_simulation) From 665e88d0ef49adbbfc8ead00b3d3ebd1289e035a Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 11:05:05 -0400 Subject: [PATCH 674/716] smaller titles --- examples/near_global_omip_simulation.jl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 09f5cda3..5c678750 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -25,7 +25,7 @@ using CairoMakie using CFTime using Dates -# ## Grid Configuration +# ### Grid Configuration # # We define a near-global grid from 75°S to 75°N with a horizontal resolution of 1/4 degree and 40 vertical levels. # The grid is created using Oceananigans' `LatitudeLongitudeGrid`. We use an exponential vertical spacing to better resolve the upper ocean layers. @@ -47,7 +47,7 @@ grid = LatitudeLongitudeGrid(arch; longitude = (0, 360), latitude = (-75, 75)) -# ## Bathymetry and Immersed Boundary +# ### Bathymetry and Immersed Boundary # # We retrieve the bathymetry from the ETOPO1 data, ensuring a minimum depth of 10 meters (depths shallower than this are considered land). # The `interpolation_passes` parameter specifies the number of passes to interpolate the bathymetry data. A larger number @@ -62,7 +62,7 @@ bottom_height = retrieve_bathymetry(grid; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) -# ## Ocean Model Configuration +# ### Ocean Model Configuration # # To configure the ocean simulation, we use the `ocean_simulation` function from ClimaOcean.jl. This function allows us to build # an ocean simulation with default parameters and numerics. The defaults include: @@ -85,7 +85,7 @@ set!(model, T = ECCOMetadata(:temperature; date), S = ECCOMetadata(:salinity; date)) -# ## Prescribed Atmosphere and Radiation +# ### Prescribed Atmosphere and Radiation # # The atmospheric data is prescribed using the JRA55 dataset, which is loaded into memory in 4 snapshots at a time. # The JRA55 dataset provides atmospheric data such as temperature, humidity, and wind fields to calculate turbulent fluxes @@ -100,7 +100,7 @@ backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation(arch) -# ## Sea Ice Model +# ### Sea Ice Model # # This simulation includes a simplified representation of ice cover where the air-sea fluxes are shut down whenever the # sea surface temperature is below the freezing point. Only heating fluxes are allowed. This is not a full sea ice model, @@ -145,7 +145,7 @@ end coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(500)) -# ## Set up Output Writers +# ### Set up Output Writers # # We define output writers to save the simulation data at regular intervals. # In this case, we save the surface fluxes and surface fields at a relatively high frequency (every half day). @@ -169,7 +169,7 @@ ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, mo indices = (:, :, grid.Nz), output_kwargs...) -# ## Warming Up the Simulation +# ### Warming Up the Simulation # # As an initial condition, we have interpolated ECCO tracer fields onto our custom grid. # The bathymetry of the original ECCO data may differ from our grid, so the initialization of the velocity @@ -184,7 +184,7 @@ wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) run!(coupled_simulation) -# ## Running the simulation +# ### Running the simulation # # Now that the simulation has been warmed up, we can run it for the full two years. # We increase the maximum time step size to 10 minutes and let the simulation run for 720 days. From dc00749d414d314bbdd66945802541ce896d99d8 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 11:06:55 -0400 Subject: [PATCH 675/716] lift correct variables --- examples/near_global_omip_simulation.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 5c678750..43764183 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -212,9 +212,9 @@ Nt = length(u.times) iter = Observable(Nt) ui = @lift(interior(u[$iter], :, :, 1)) -vi = @lift(interior(u[$iter], :, :, 1)) -Ti = @lift(interior(u[$iter], :, :, 1)) -ei = @lift(interior(u[$iter], :, :, 1)) +vi = @lift(interior(v[$iter], :, :, 1)) +Ti = @lift(interior(T[$iter], :, :, 1)) +ei = @lift(interior(e[$iter], :, :, 1)) fig = Figure(size = (1000, 750)) From b8a4d0b8fa0460727d46c76dc2ee7f7aa6c1ae79 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 11:07:37 -0400 Subject: [PATCH 676/716] reduce frames by a factor of two --- examples/near_global_omip_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index 43764183..b82145b5 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -158,13 +158,13 @@ fluxes = (u = model.velocities.u.boundary_conditions.top.condition, output_kwargs = (; overwrite_existing = true, array_type = Array{Float32}) ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; - schedule = TimeInterval(0.5days), + schedule = TimeInterval(1day), overwrite_existing = true, filename = "surface_fluxes", output_kwargs...) ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); - schedule = TimeInterval(0.5days), + schedule = TimeInterval(1day), filename = "surface", indices = (:, :, grid.Nz), output_kwargs...) From 5f622a4d15c0e4fee4f91a56ae602739fb8a0bbd Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 11:52:41 -0400 Subject: [PATCH 677/716] bugfix --- examples/generate_surface_fluxes.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index 9c33e7c4..a3e2fb27 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -114,23 +114,23 @@ fig = Figure(size = (1000, 2000)) ax = Axis(fig[1, 1], title = "Sensible heat flux [Wm⁻²]") heatmap!(ax, Qs; colormap = :bwr) -hidedecoration!(ax) +hidedecorations!(ax) ax = Axis(fig[1, 2], title = "Latent heat flux [Wm⁻²]") heatmap!(ax, Ql; colormap = :bwr) -hidedecoration!(ax) +hidedecorations!(ax) ax = Axis(fig[2, 1], title = "Zonal wind stress [Nm]") heatmap!(ax, τx; colormap = :bwr) -hidedecoration!(ax) +hidedecorations!(ax) ax = Axis(fig[2, 2], title = "Meridional wind stress [Nm]") heatmap!(ax, τy; colormap = :bwr) -hidedecoration!(ax) +hidedecorations!(ax) ax = Axis(fig[3, 1], title = "Evaporation [kg m⁻²s⁻¹]") heatmap!(ax, Mv; colormap = :bwr) -hidedecoration!(ax) +hidedecorations!(ax) save("turbulent_fluxes.png", fig) nothing #hide From 7f2936f9aee11fefcffc098f070c4600971cd6b3 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 13:16:42 -0400 Subject: [PATCH 678/716] another bugfix --- examples/near_global_omip_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_omip_simulation.jl index b82145b5..ca21d155 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_omip_simulation.jl @@ -158,13 +158,13 @@ fluxes = (u = model.velocities.u.boundary_conditions.top.condition, output_kwargs = (; overwrite_existing = true, array_type = Array{Float32}) ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; - schedule = TimeInterval(1day), + schedule = TimeInterval(1days), overwrite_existing = true, filename = "surface_fluxes", output_kwargs...) ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); - schedule = TimeInterval(1day), + schedule = TimeInterval(1days), filename = "surface", indices = (:, :, grid.Nz), output_kwargs...) From 51ca04696186193bda044e2257de885cd5077918 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 13:33:11 -0400 Subject: [PATCH 679/716] adding generate bathymetry --- docs/make.jl | 4 +++- examples/generate_bathymetry.jl | 11 ++++++++--- ...lation.jl => near_global_ocean_simulation.jl} | 16 +++++++++++++++- 3 files changed, 26 insertions(+), 5 deletions(-) rename examples/{near_global_omip_simulation.jl => near_global_ocean_simulation.jl} (97%) diff --git a/docs/make.jl b/docs/make.jl index 1d0243d7..1231a50e 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -16,6 +16,7 @@ const OUTPUT_DIR = joinpath(@__DIR__, "src/literated") to_be_literated = [ # "inspect_ecco_data.jl", + "generate_bathymetry.jl", "generate_surface_fluxes.jl", # "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", @@ -52,10 +53,11 @@ pages = [ "Examples" => [ # "Inspect ECCO2 data" => "literated/inspect_ecco_data.md", + "Generate bathymetry" => "literated/generate_bathymetry.md", "Surface fluxes" => "literated/generate_surface_fluxes.md", # "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - "Near global OMIP simulation" => "literated/near_global_omip_simulation.md", + "Near global Ocean simulation" => "literated/near_global_ocean_simulation.md", ] ] diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 3719d6d1..6342d3b2 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -43,16 +43,21 @@ h_nolakes = regrid_bathymetry(grid; connected_regions_allowed = 0) land_smooth = interior(h_smooth) .>= 0 interior(h_smooth)[land_smooth] .= NaN land_rough = interior(h_rough) .>= 0 -interior(h_rough)[land_rough] .= NaNxe +interior(h_rough)[land_rough] .= NaN land_nolakes = interior(h_nolakes) .>= 0 interior(h_nolakes)[land_nolakes] .= NaN -fig = Figure(resolution=(2400, 800)) +fig = Figure(resolution=(1200, 400)) ax = Axis(fig[1, 1]) heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white) + ax = Axis(fig[1, 2]) heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white) + ax = Axis(fig[1, 3]) heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white) -display(fig) +save("different_bottom_heights.png", fig) +nothing #hide + +# ![](different_bottom_heights.png) \ No newline at end of file diff --git a/examples/near_global_omip_simulation.jl b/examples/near_global_ocean_simulation.jl similarity index 97% rename from examples/near_global_omip_simulation.jl rename to examples/near_global_ocean_simulation.jl index ca21d155..13235321 100644 --- a/examples/near_global_omip_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -56,12 +56,19 @@ grid = LatitudeLongitudeGrid(arch; bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, - dir = "./", interpolation_passes = 20, connected_regions_allowed = 0) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) +fig = Figure() +axis = Axis(fig[1, 1], title = "Bathymetry") +heatmap!(axis, Array(bottom_height), colormap = :topo) +save("bathymetry.png", fig) +nothing #hide + +# ![](bathymetry.png) + # ### Ocean Model Configuration # # To configure the ocean simulation, we use the `ocean_simulation` function from ClimaOcean.jl. This function allows us to build @@ -84,6 +91,7 @@ date = DateTimeProlepticGregorian(1993, 1, 1) set!(model, T = ECCOMetadata(:temperature; date), S = ECCOMetadata(:salinity; date)) +nothing #hide # ### Prescribed Atmosphere and Radiation # @@ -99,6 +107,7 @@ set!(model, backend = JRA55NetCDFBackend(4) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation(arch) +nothing #hide # ### Sea Ice Model # @@ -107,6 +116,7 @@ radiation = Radiation(arch) # but it prevents the temperature from dropping excessively low by including atmosphere-ocean fluxes. sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() +nothing #hide # ## The Coupled Simulation # @@ -144,6 +154,7 @@ function progress(sim) end coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(500)) +nothing #hide # ### Set up Output Writers # @@ -168,6 +179,7 @@ ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, mo filename = "surface", indices = (:, :, grid.Nz), output_kwargs...) +nothing #hide # ### Warming Up the Simulation # @@ -183,6 +195,7 @@ ocean.stop_time = 10days wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) run!(coupled_simulation) +nothing #hide # ### Running the simulation # @@ -194,6 +207,7 @@ coupled_simulation.stop_time = 60days wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 15minutes, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) run!(coupled_simulation) +nothing #hide # ## Visualizing the Results # From 91f3c5d7dd582475860b6b89c95740ecaf93d00f Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 13:41:22 -0400 Subject: [PATCH 680/716] some bugfixes --- examples/generate_bathymetry.jl | 8 +++++--- examples/near_global_ocean_simulation.jl | 13 ++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 6342d3b2..5d0afd15 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -49,13 +49,15 @@ interior(h_nolakes)[land_nolakes] .= NaN fig = Figure(resolution=(1200, 400)) ax = Axis(fig[1, 1]) -heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white) +hm = heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white, colormap = :vermeer) ax = Axis(fig[1, 2]) -heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white) +hm = heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white, colormap = :vermeer) ax = Axis(fig[1, 3]) -heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white) +hm = heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white, colormap = :vermeer) + +cb = Colorbar(fig[1, 4], hm, label="Depth [m]") save("different_bottom_heights.png", fig) nothing #hide diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 13235321..73db428e 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -52,18 +52,21 @@ grid = LatitudeLongitudeGrid(arch; # We retrieve the bathymetry from the ETOPO1 data, ensuring a minimum depth of 10 meters (depths shallower than this are considered land). # The `interpolation_passes` parameter specifies the number of passes to interpolate the bathymetry data. A larger number # results in a smoother bathymetry. We also remove all connected regions (such as inland lakes) from the bathymetry data by specifying -# `connected_regions_allowed = 0`. +# `connected_regions_allowed = 2` (on top of the global ocean: the Mediterranean and the north sea). bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, interpolation_passes = 20, - connected_regions_allowed = 0) + connected_regions_allowed = 2) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) -fig = Figure() -axis = Axis(fig[1, 1], title = "Bathymetry") -heatmap!(axis, Array(bottom_height), colormap = :topo) +fig = Figure(size = (800, 400)) +axis = Axis(fig[1, 1], title = "Bathymetry [m]") +hm = heatmap!(axis, Array(interior(bottom_height, :, :, 1)), colormap = :vermeer, colorrange = (-6000, 0)) +cb = Colorbar(fig[1, 2], hm) +hidedecorations!(axis) + save("bathymetry.png", fig) nothing #hide From 6fcd1cefd8ae1530574ac9a2ee7cf8bda255ccba Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 13:44:28 -0400 Subject: [PATCH 681/716] better colormaps --- examples/generate_bathymetry.jl | 16 ++++++++-------- examples/near_global_ocean_simulation.jl | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 5d0afd15..a1d777a4 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -13,14 +13,14 @@ using CairoMakie # We start by defining a gridded domain for the Mediterranean Sea using the `LatitudeLongitudeGrid` from Oceananigans. # To have a reasonable resolution, we set a grid size to 1/25ᵒ of a degree in both latitude and longitude. # -# The Mediterranean sea is positioned roughly between 25ᵒ and 50ᵒ latitude and -10ᵒ and 45ᵒ longitude. +# The Mediterranean sea is positioned roughly between 28ᵒ and 48ᵒ latitude and 0ᵒ and 42ᵒ longitude. -Nλ = 25 * 55 -Nφ = 25 * 25 +Nλ = 25 * 42 +Nφ = 25 * 20 grid = LatitudeLongitudeGrid(size = (Nλ, Nφ, 1), - latitude = (25, 50), - longitude = (-10, 45), + latitude = (28, 48), + longitude = (0, 42), z = (0, 1)) # Next, we generate the bathymetry data for the Mediterranean Sea using the `regrid_bathymetry` function from ClimaOcean. @@ -49,13 +49,13 @@ interior(h_nolakes)[land_nolakes] .= NaN fig = Figure(resolution=(1200, 400)) ax = Axis(fig[1, 1]) -hm = heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white, colormap = :vermeer) +hm = heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white, colormap = :deep) ax = Axis(fig[1, 2]) -hm = heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white, colormap = :vermeer) +hm = heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white, colormap = :deep) ax = Axis(fig[1, 3]) -hm = heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white, colormap = :vermeer) +hm = heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white, colormap = :deep) cb = Colorbar(fig[1, 4], hm, label="Depth [m]") diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 73db428e..6e4e8897 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -63,7 +63,7 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) fig = Figure(size = (800, 400)) axis = Axis(fig[1, 1], title = "Bathymetry [m]") -hm = heatmap!(axis, Array(interior(bottom_height, :, :, 1)), colormap = :vermeer, colorrange = (-6000, 0)) +hm = heatmap!(axis, Array(interior(bottom_height, :, :, 1)), colormap = :deep, colorrange = (-6000, 0)) cb = Colorbar(fig[1, 2], hm) hidedecorations!(axis) From 9be704499881e20f169f54bcf38f1d486a8f980b Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 13:46:13 -0400 Subject: [PATCH 682/716] more massaging --- examples/generate_bathymetry.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index a1d777a4..555cfe8e 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -35,6 +35,7 @@ grid = LatitudeLongitudeGrid(size = (Nλ, Nφ, 1), h_rough = regrid_bathymetry(grid) h_smooth = regrid_bathymetry(grid; interpolation_passes = 40) h_nolakes = regrid_bathymetry(grid; connected_regions_allowed = 0) +nothing # hide # Finally, we visualize the generated bathymetry data for the Mediterranean Sea using CairoMakie. @@ -47,12 +48,12 @@ interior(h_rough)[land_rough] .= NaN land_nolakes = interior(h_nolakes) .>= 0 interior(h_nolakes)[land_nolakes] .= NaN -fig = Figure(resolution=(1200, 400)) +fig = Figure(resolution=(1400, 400)) ax = Axis(fig[1, 1]) -hm = heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white, colormap = :deep) +hm = heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white, colormap = :deep) ax = Axis(fig[1, 2]) -hm = heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white, colormap = :deep) +hm = heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white, colormap = :deep) ax = Axis(fig[1, 3]) hm = heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white, colormap = :deep) From b0e95ac928d5490c81d56d2ad343a1e2e7214382 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 13:56:26 -0400 Subject: [PATCH 683/716] try the full global ocean --- docs/Project.toml | 1 + ...mulation.jl => global_ocean_simulation.jl} | 36 +++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) rename examples/{near_global_ocean_simulation.jl => global_ocean_simulation.jl} (90%) diff --git a/docs/Project.toml b/docs/Project.toml index 08ab7c7a..c5baf5a7 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -3,6 +3,7 @@ CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" +OrthogonalSphericalShellGrids = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0" [compat] CairoMakie = "0.10.12" diff --git a/examples/near_global_ocean_simulation.jl b/examples/global_ocean_simulation.jl similarity index 90% rename from examples/near_global_ocean_simulation.jl rename to examples/global_ocean_simulation.jl index 6e4e8897..649d3a8b 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/global_ocean_simulation.jl @@ -21,15 +21,16 @@ using ClimaOcean.ECCO using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels using CairoMakie +using OrthogonalSphericalShellGrids using CFTime using Dates # ### Grid Configuration # -# We define a near-global grid from 75°S to 75°N with a horizontal resolution of 1/4 degree and 40 vertical levels. -# The grid is created using Oceananigans' `LatitudeLongitudeGrid`. We use an exponential vertical spacing to better resolve the upper ocean layers. -# The total depth of the domain is set to 6000 meters. +# We define a global grid with a horizontal resolution of 1/4 degree and 40 vertical levels. +# The grid is a `TripolarGrid` with the north poles located at 55ᵒ N and 105ᵒ W and 105ᵒ E, respectively. +# We use an exponential vertical spacing to better resolve the upper ocean layers. The total depth of the domain is set to 6000 meters. # Finally, we specify the architecture for the simulation, which in this case is a GPU. arch = GPU() @@ -40,30 +41,33 @@ Nx = 1440 Ny = 600 Nz = length(z_faces) - 1 -grid = LatitudeLongitudeGrid(arch; - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = z_faces, - longitude = (0, 360), - latitude = (-75, 75)) +grid = TripolarGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = z_faces, + first_pole_longitude = 75, + north_poles_latitude = 55) # ### Bathymetry and Immersed Boundary # # We retrieve the bathymetry from the ETOPO1 data, ensuring a minimum depth of 10 meters (depths shallower than this are considered land). # The `interpolation_passes` parameter specifies the number of passes to interpolate the bathymetry data. A larger number # results in a smoother bathymetry. We also remove all connected regions (such as inland lakes) from the bathymetry data by specifying -# `connected_regions_allowed = 2` (on top of the global ocean: the Mediterranean and the north sea). +# `connected_regions_allowed = 0` bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, - interpolation_passes = 20, - connected_regions_allowed = 2) + interpolation_passes = 5, + connected_regions_allowed = 0) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) +bathymetry = deepcopy(Array(interior(bottom_height, :, :, 1))) +bathymetry[bathymetry .>= 0] .= NaN + fig = Figure(size = (800, 400)) axis = Axis(fig[1, 1], title = "Bathymetry [m]") -hm = heatmap!(axis, Array(interior(bottom_height, :, :, 1)), colormap = :deep, colorrange = (-6000, 0)) +hm = heatmap!(axis, bathymetry, colormap = :deep, colorrange = (-6000, 0)) cb = Colorbar(fig[1, 2], hm) hidedecorations!(axis) @@ -79,14 +83,15 @@ nothing #hide # - CATKE turbulence closure for vertical mixing, see [`CATKEVerticalDiffusivity`](@ref) # - WENO-based advection scheme for momentum in the vector invariant form, see [`WENOVectorInvariant`](@ref) # - WENO-based advection scheme for tracers, see [`WENO`](@ref) -# - `SplitExplicitFreeSurfaceSolver` with a Courant number of 0.7, see [`SplitExplicitFreeSurface`](@ref) +# - `SplitExplicitFreeSurfaceSolver` with 75 substeps, see [`SplitExplicitFreeSurface`](@ref) # - TEOS-10 equation of state, see [`TEOS10EquationOfState`](@ref) # - Quadratic bottom drag with a drag coefficient of 0.003 # # The ocean model is then initialized with the ECCO2 temperature and salinity fields for January 1, 1993. +free_surface = SplitExplicitFreeSurface(grid; substeps = 75) -ocean = ocean_simulation(grid) +ocean = ocean_simulation(grid; free_surface) model = ocean.model date = DateTimeProlepticGregorian(1993, 1, 1) @@ -94,6 +99,7 @@ date = DateTimeProlepticGregorian(1993, 1, 1) set!(model, T = ECCOMetadata(:temperature; date), S = ECCOMetadata(:salinity; date)) + nothing #hide # ### Prescribed Atmosphere and Radiation From a6f80f590df61e4288405c8b0c9d8e637ec8261b Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 14:46:32 -0400 Subject: [PATCH 684/716] global ocean simulation --- docs/make.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 1231a50e..7f80a8c8 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -20,7 +20,7 @@ to_be_literated = [ "generate_surface_fluxes.jl", # "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", - "near_global_omip_simulation.jl" + "global_ocean_simulation.jl" ] for file in to_be_literated @@ -57,7 +57,7 @@ pages = [ "Surface fluxes" => "literated/generate_surface_fluxes.md", # "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - "Near global Ocean simulation" => "literated/near_global_ocean_simulation.md", + "Global Ocean simulation" => "literated/global_ocean_simulation.md", ] ] From baaa569fc6651fff59df785ff0e994cc58b91565 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 15:57:13 -0400 Subject: [PATCH 685/716] Parameter space problem --- docs/make.jl | 4 ++-- ...ion.jl => near_global_ocean_simulation.jl} | 20 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) rename examples/{global_ocean_simulation.jl => near_global_ocean_simulation.jl} (95%) diff --git a/docs/make.jl b/docs/make.jl index 7f80a8c8..e551fb70 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -20,7 +20,7 @@ to_be_literated = [ "generate_surface_fluxes.jl", # "single_column_simulation.jl", # "mediterranean_simulation_with_ecco_restoring.jl", - "global_ocean_simulation.jl" + "near_global_ocean_simulation.jl" ] for file in to_be_literated @@ -57,7 +57,7 @@ pages = [ "Surface fluxes" => "literated/generate_surface_fluxes.md", # "Single column simulation" => "literated/single_column_simulation.md", # "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md", - "Global Ocean simulation" => "literated/global_ocean_simulation.md", + "Near-global Ocean simulation" => "literated/near_global_ocean_simulation.md", ] ] diff --git a/examples/global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl similarity index 95% rename from examples/global_ocean_simulation.jl rename to examples/near_global_ocean_simulation.jl index 649d3a8b..c94e60b9 100644 --- a/examples/global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -29,7 +29,7 @@ using Dates # ### Grid Configuration # # We define a global grid with a horizontal resolution of 1/4 degree and 40 vertical levels. -# The grid is a `TripolarGrid` with the north poles located at 55ᵒ N and 105ᵒ W and 105ᵒ E, respectively. +# The grid is a `LatitudeLongitudeGrid` capped at 75°S to 75°N. # We use an exponential vertical spacing to better resolve the upper ocean layers. The total depth of the domain is set to 6000 meters. # Finally, we specify the architecture for the simulation, which in this case is a GPU. @@ -41,26 +41,26 @@ Nx = 1440 Ny = 600 Nz = length(z_faces) - 1 -grid = TripolarGrid(arch; - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = z_faces, - first_pole_longitude = 75, - north_poles_latitude = 55) +grid = LatitudeLongitudeGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = z_faces, + latitude = (-75, 75), + longitude = (0, 360)) # ### Bathymetry and Immersed Boundary # # We retrieve the bathymetry from the ETOPO1 data, ensuring a minimum depth of 10 meters (depths shallower than this are considered land). # The `interpolation_passes` parameter specifies the number of passes to interpolate the bathymetry data. A larger number # results in a smoother bathymetry. We also remove all connected regions (such as inland lakes) from the bathymetry data by specifying -# `connected_regions_allowed = 0` +# `connected_regions_allowed = 2` (Mediterrean sea an North sea in addition to the ocean) bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, interpolation_passes = 5, - connected_regions_allowed = 0) + connected_regions_allowed = 2) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) bathymetry = deepcopy(Array(interior(bottom_height, :, :, 1))) bathymetry[bathymetry .>= 0] .= NaN From b89e12f9e0c2c86a2e685909cea2b3ada9ba7e89 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 3 Aug 2024 17:00:50 -0400 Subject: [PATCH 686/716] unfortunately we cannot use active cells map --- examples/near_global_ocean_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index c94e60b9..dcf3fd31 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -60,7 +60,7 @@ bottom_height = retrieve_bathymetry(grid; interpolation_passes = 5, connected_regions_allowed = 2) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map = true) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) bathymetry = deepcopy(Array(interior(bottom_height, :, :, 1))) bathymetry[bathymetry .>= 0] .= NaN From 638eb78d2d832355800a3be9ae7960d50b9143a3 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sun, 4 Aug 2024 07:11:44 +1000 Subject: [PATCH 687/716] few tweaks --- examples/near_global_ocean_simulation.jl | 35 ++++++++++++------------ 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index dcf3fd31..fd7f8809 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -1,18 +1,17 @@ # # Near-global Ocean Simulation # -# This Julia script sets up and runs a near-global ocean simulation using the Oceananigans.jl and ClimaOcean.jl packages. +# The example sets up and runs a near-global ocean simulation using the Oceananigans.jl and ClimaOcean.jl packages. # The simulation covers latitudes from 75°S to 75°N with a horizontal resolution of 1/4 degree and 40 vertical levels. # -# The simulation runs for one year, and the results are visualized using the CairoMakie.jl package. +# The ouptut of the simulation is visualized with the CairoMakie.jl package. # # ## Initial Setup with Package Imports # -# The script begins by importing the necessary Julia packages for visualization (CairoMakie), -# ocean modeling (Oceananigans, ClimaOcean), and handling dates and times (CFTime, Dates). +# We begin by importing the necessary Julia packages for visualization (CairoMakie), +# ocean modeling (Oceananigans, ClimaOcean), and handling dates and times (CFTime, Dates). # These packages provide the foundational tools for setting up the simulation environment, # including grid setup, physical processes modeling, and data visualization. -using Printf using Oceananigans using Oceananigans.Units using Oceananigans: architecture, on_architecture @@ -20,11 +19,11 @@ using ClimaOcean using ClimaOcean.ECCO using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels -using CairoMakie using OrthogonalSphericalShellGrids - +using CairoMakie using CFTime using Dates +using Printf # ### Grid Configuration # @@ -135,8 +134,9 @@ nothing #hide # We then create a coupled simulation, starting with a time step of 10 seconds and running the simulation for 10 days. # We will eventually increase the time step size and end time as the simulation progresses and initialization shocks dissipate. # -# We also define a callback function to monitor the simulation's progress. This function prints the current time, iteration, time step, -# as well as the maximum velocities and tracers in the domain. The wall time is also printed to monitor the time taken for each iteration. +# We also define a callback function to monitor the simulation's progress. This function +# outputs the current time, iteration, time step, as well as the maximum velocities and tracer +# values in the domain. The wall time is also printed to monitor the time taken for each iteration. coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) coupled_simulation = Simulation(coupled_model; Δt=10, stop_time = 10days) @@ -168,7 +168,8 @@ nothing #hide # ### Set up Output Writers # # We define output writers to save the simulation data at regular intervals. -# In this case, we save the surface fluxes and surface fields at a relatively high frequency (every half day). +# In this case, we save the surface fluxes and surface fields at a relatively +# high frequency (every 12 hours). fluxes = (u = model.velocities.u.boundary_conditions.top.condition, v = model.velocities.v.boundary_conditions.top.condition, @@ -193,12 +194,13 @@ nothing #hide # ### Warming Up the Simulation # # As an initial condition, we have interpolated ECCO tracer fields onto our custom grid. -# The bathymetry of the original ECCO data may differ from our grid, so the initialization of the velocity -# field might cause shocks if a large time step is used. +# The bathymetry of the original ECCO data may differ from our grid, so the initialization +# of the velocity field might cause shocks if a large time step is used. # -# Therefore, we warm up with a small time step to ensure that the interpolated initial conditions adapt to the model numerics and -# parameterization without causing instability. A 30-day integration with a maximum time step of 1.5 minutes should be sufficient to dissipate -# spurious initialization shocks. +# Therefore, we start by a 'warm up', i.e., running the simulation with a small time step, +# to ensure that the interpolated initial conditions adapt to the model numerics and +# parameterization without causing instability. A 30-day integration with a maximum time step +# of 90 seconds should be sufficient to dissipate spurious initialization shocks. ocean.stop_time = 10days wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) @@ -221,7 +223,7 @@ nothing #hide # ## Visualizing the Results # # The simulation has finished, let's visualize the results. -# In this section we pull up the saved data and create visualizations using the CairoMakie.jl package. +# We first load the saved data and then create visualizations using the CairoMakie.jl package. # In particular, we generate a video of the evolution of surface fields: # zonal velocity (u), meridional velocity (v), surface temperature (T), and turbulent kinetic energy (e) @@ -264,4 +266,3 @@ end nothing #hide # ![](near_global_ocean_surface.mp4) - From 34a1cfd33f48c4b0e73758bdddfc8a34bb7f38d6 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sun, 4 Aug 2024 07:15:00 +1000 Subject: [PATCH 688/716] code cleanup --- src/DataWrangling/JRA55.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index a29048a6..3cfd6dea 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -455,7 +455,7 @@ function JRA55_field_time_series(variable_name; boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) times = jra55_times(native_times) - + if backend isa JRA55NetCDFBackend fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; backend, @@ -534,7 +534,7 @@ function JRA55_field_time_series(variable_name; else copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) end - + while n <= all_Nt print(" ... processing time index $n of $all_Nt \r") @@ -626,7 +626,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); 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...) - + freshwater_flux = (rain = Fra, snow = Fsn) @@ -648,7 +648,7 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); tracers = (T = Ta, q = qa) - + pressure = pa downwelling_radiation = TwoBandDownwellingRadiation(shortwave=Qs, longwave=Ql) @@ -669,4 +669,3 @@ function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); end end # module - From 365472b268203e7da26204d21f9856d4c8f9ea7f Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sun, 4 Aug 2024 07:16:36 +1000 Subject: [PATCH 689/716] code cleanup --- src/OceanSeaIceModels/minimum_temperature_sea_ice.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl index efd56771..6fab535e 100644 --- a/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl +++ b/src/OceanSeaIceModels/minimum_temperature_sea_ice.jl @@ -28,7 +28,7 @@ function limit_fluxes_over_sea_ice!(grid, kernel_parameters, sea_ice::MinimumTem launch!(architecture(grid), grid, kernel_parameters, _cap_fluxes_on_sea_ice!, centered_velocity_fluxes, net_tracer_fluxes, - grid, + grid, sea_ice.minimum_temperature, ocean_temperature) @@ -37,7 +37,7 @@ end @kernel function _cap_fluxes_on_sea_ice!(centered_velocity_fluxes, net_tracer_fluxes, - grid, + grid, minimum_temperature, ocean_temperature) @@ -55,8 +55,8 @@ end cooling_sea_ice = sea_ice & (Jᵀ[i, j, 1] > 0) # Don't allow the ocean to cool below the minimum temperature! (make sure it heats up though!) - Jᵀ[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), Jᵀ[i, j, 1]) - + Jᵀ[i, j, 1] = ifelse(cooling_sea_ice, zero(grid), Jᵀ[i, j, 1]) + # If we are in a "sea ice" region we remove all fluxes Jˢ[i, j, 1] = ifelse(sea_ice, zero(grid), Jˢ[i, j, 1]) Jᵘ[i, j, 1] = ifelse(sea_ice, zero(grid), Jᵘ[i, j, 1]) From 6f3982cc50bf08de92907df3cf86a98e8c5d694a Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sun, 4 Aug 2024 07:18:04 +1000 Subject: [PATCH 690/716] code cleanup --- src/OceanSeaIceModels/OceanSeaIceModels.jl | 1 - src/OceanSeaIceModels/ocean_only_model.jl | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index a30c5b52..29dbf669 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -104,4 +104,3 @@ end end end # module - diff --git a/src/OceanSeaIceModels/ocean_only_model.jl b/src/OceanSeaIceModels/ocean_only_model.jl index 8ab28eb8..0b32a1a2 100644 --- a/src/OceanSeaIceModels/ocean_only_model.jl +++ b/src/OceanSeaIceModels/ocean_only_model.jl @@ -23,14 +23,14 @@ function time_step!(coupled_model::NoSeaIceModel, Δt; callbacks=[], compute_ten tick!(coupled_model.clock, ocean.Δt) # An Ocean-only model advances with the ocean time-step! update_state!(coupled_model, callbacks; compute_tendencies) - + return nothing end function update_state!(coupled_model::NoSeaIceModel, callbacks=[]; compute_tendencies=false) time = Time(coupled_model.clock.time) update_model_field_time_series!(coupled_model.atmosphere, time) - + ocean_model = coupled_model.ocean.model # Do we really have to do this? @@ -42,4 +42,3 @@ function update_state!(coupled_model::NoSeaIceModel, callbacks=[]; compute_tende compute_atmosphere_ocean_fluxes!(coupled_model) return nothing end - From c818e523841552a06a2c1c0cb169bb73c020b9ad Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sun, 4 Aug 2024 07:27:17 +1000 Subject: [PATCH 691/716] clearer explanation --- examples/generate_bathymetry.jl | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 555cfe8e..b903e835 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -23,14 +23,19 @@ grid = LatitudeLongitudeGrid(size = (Nλ, Nφ, 1), longitude = (0, 42), z = (0, 1)) -# Next, we generate the bathymetry data for the Mediterranean Sea using the `regrid_bathymetry` function from ClimaOcean. -# The function downloads the bathymetry data from the ETOPO1 dataset, regrids it to the provided grid, and returns the bathymetry field. -# The three different regidding procedures here show the effect of different parameters on the generated bathymetry. +# Next, we generate the bathymetry data for the Mediterranean Sea using the +# `regrid_bathymetry` function from ClimaOcean. The function downloads the bathymetry +# data from the ETOPO1 dataset, regrids it to the provided grid, and returns the +# bathymetry field. The three different regidding procedures below demonstrate the effect +# of different parameters on the generated bathymetry: # -# - `h_rough` shows the output of the function with default parameters, which means only one interpolation passes and no restrictions on connected regions. -# - `h_smooth` shows the output of the function with 40 interpolation passes, which results in a smoother bathymetry. -# - `h_nolakes` shows the output of the function with `connected_regions_allowed = 0`, which means that the function does not allow connected regions in the bathymetry -# (e.g., lakes) and fills them with land. +# - `h_rough` shows the output of the function with default parameters, which means only +# one interpolation passes and no restrictions on connected regions. +# - `h_smooth` shows the output of the function with 40 interpolation passes, which results +# in a smoother bathymetry. +# - `h_nolakes` shows the output of the function with `connected_regions_allowed = 0`, which +# means that the function does not allow connected regions in the bathymetry (e.g., lakes) +# and fills them with land. h_rough = regrid_bathymetry(grid) h_smooth = regrid_bathymetry(grid; interpolation_passes = 40) @@ -49,11 +54,12 @@ land_nolakes = interior(h_nolakes) .>= 0 interior(h_nolakes)[land_nolakes] .= NaN fig = Figure(resolution=(1400, 400)) + ax = Axis(fig[1, 1]) -hm = heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white, colormap = :deep) +hm = heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white, colormap = :deep) ax = Axis(fig[1, 2]) -hm = heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white, colormap = :deep) +hm = heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white, colormap = :deep) ax = Axis(fig[1, 3]) hm = heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white, colormap = :deep) @@ -63,4 +69,4 @@ cb = Colorbar(fig[1, 4], hm, label="Depth [m]") save("different_bottom_heights.png", fig) nothing #hide -# ![](different_bottom_heights.png) \ No newline at end of file +# ![](different_bottom_heights.png) From c61f648ef366caf87ef5cebfd1c9a9909d6011bd Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sun, 4 Aug 2024 07:28:13 +1000 Subject: [PATCH 692/716] clearer explanation --- examples/generate_bathymetry.jl | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index b903e835..23e92329 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -10,17 +10,21 @@ using ClimaOcean using Oceananigans using CairoMakie -# We start by defining a gridded domain for the Mediterranean Sea using the `LatitudeLongitudeGrid` from Oceananigans. -# To have a reasonable resolution, we set a grid size to 1/25ᵒ of a degree in both latitude and longitude. +# We start by defining a gridded domain for the Mediterranean Sea using the `LatitudeLongitudeGrid` from Oceananigans. # # The Mediterranean sea is positioned roughly between 28ᵒ and 48ᵒ latitude and 0ᵒ and 42ᵒ longitude. +# We define a grid in this region and to have a reasonable resolution, we set a grid resolution to 1/25ᵒ +# in both latitude and longitude directions. -Nλ = 25 * 42 -Nφ = 25 * 20 +latitude_range = (28, 48) +longitude_range = (0, 42) + +Nφ = 25 * (latitude_range[2] - latitude_range[1]) +Nλ = 25 * (longitude_range[2] - longitude_range[1]) grid = LatitudeLongitudeGrid(size = (Nλ, Nφ, 1), - latitude = (28, 48), - longitude = (0, 42), + latitude = latitude_range, + longitude = longitude_range, z = (0, 1)) # Next, we generate the bathymetry data for the Mediterranean Sea using the @@ -48,8 +52,10 @@ nothing # hide land_smooth = interior(h_smooth) .>= 0 interior(h_smooth)[land_smooth] .= NaN + land_rough = interior(h_rough) .>= 0 interior(h_rough)[land_rough] .= NaN + land_nolakes = interior(h_nolakes) .>= 0 interior(h_nolakes)[land_nolakes] .= NaN From e2cae09cf88498c2e6a1ec5f6ad389517c63a54d Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sun, 4 Aug 2024 06:46:16 -0400 Subject: [PATCH 693/716] try the global ocean --- examples/near_global_ocean_simulation.jl | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index dcf3fd31..c7fd9a74 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -41,12 +41,19 @@ Nx = 1440 Ny = 600 Nz = length(z_faces) - 1 -grid = LatitudeLongitudeGrid(arch; - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = z_faces, - latitude = (-75, 75), - longitude = (0, 360)) +grid = TripolarGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = z_faces, + first_pole_longitude = 75, + north_poles_latitude = 55) + +# grid = LatitudeLongitudeGrid(arch; +# size = (Nx, Ny, Nz), +# halo = (7, 7, 7), +# z = z_faces, +# latitude = (-75, 75), +# longitude = (0, 360)) # ### Bathymetry and Immersed Boundary # @@ -58,14 +65,14 @@ grid = LatitudeLongitudeGrid(arch; bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, interpolation_passes = 5, - connected_regions_allowed = 2) + connected_regions_allowed = 0) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) bathymetry = deepcopy(Array(interior(bottom_height, :, :, 1))) bathymetry[bathymetry .>= 0] .= NaN -fig = Figure(size = (800, 400)) +fig = Figure(size = (800, 300)) axis = Axis(fig[1, 1], title = "Bathymetry [m]") hm = heatmap!(axis, bathymetry, colormap = :deep, colorrange = (-6000, 0)) cb = Colorbar(fig[1, 2], hm) From eead6e52dd7acfd3ab17e319275eb89c1f0ebb91 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sun, 4 Aug 2024 10:10:35 -0400 Subject: [PATCH 694/716] better visualizations --- examples/near_global_ocean_simulation.jl | 163 ++++++++++++++--------- 1 file changed, 97 insertions(+), 66 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 6cd288ec..cead4ffe 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -1,17 +1,18 @@ # # Near-global Ocean Simulation # -# The example sets up and runs a near-global ocean simulation using the Oceananigans.jl and ClimaOcean.jl packages. +# This Julia script sets up and runs a near-global ocean simulation using the Oceananigans.jl and ClimaOcean.jl packages. # The simulation covers latitudes from 75°S to 75°N with a horizontal resolution of 1/4 degree and 40 vertical levels. # -# The ouptut of the simulation is visualized with the CairoMakie.jl package. +# The simulation runs for one year, and the results are visualized using the CairoMakie.jl package. # # ## Initial Setup with Package Imports # -# We begin by importing the necessary Julia packages for visualization (CairoMakie), -# ocean modeling (Oceananigans, ClimaOcean), and handling dates and times (CFTime, Dates). +# The script begins by importing the necessary Julia packages for visualization (CairoMakie), +# ocean modeling (Oceananigans, ClimaOcean), and handling dates and times (CFTime, Dates). # These packages provide the foundational tools for setting up the simulation environment, # including grid setup, physical processes modeling, and data visualization. +using Printf using Oceananigans using Oceananigans.Units using Oceananigans: architecture, on_architecture @@ -19,11 +20,11 @@ using ClimaOcean using ClimaOcean.ECCO using ClimaOcean.OceanSimulations using ClimaOcean.OceanSeaIceModels -using OrthogonalSphericalShellGrids using CairoMakie +using OrthogonalSphericalShellGrids + using CFTime using Dates -using Printf # ### Grid Configuration # @@ -40,19 +41,12 @@ Nx = 1440 Ny = 600 Nz = length(z_faces) - 1 -grid = TripolarGrid(arch; - size = (Nx, Ny, Nz), - halo = (7, 7, 7), - z = z_faces, - first_pole_longitude = 75, - north_poles_latitude = 55) - -# grid = LatitudeLongitudeGrid(arch; -# size = (Nx, Ny, Nz), -# halo = (7, 7, 7), -# z = z_faces, -# latitude = (-75, 75), -# longitude = (0, 360)) +grid = LatitudeLongitudeGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), + z = z_faces, + latitude = (-75, 75), + longitude = (0, 360)) # ### Bathymetry and Immersed Boundary # @@ -64,14 +58,14 @@ grid = TripolarGrid(arch; bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, interpolation_passes = 5, - connected_regions_allowed = 0) + connected_regions_allowed = 2) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) bathymetry = deepcopy(Array(interior(bottom_height, :, :, 1))) bathymetry[bathymetry .>= 0] .= NaN -fig = Figure(size = (800, 300)) +fig = Figure(size = (800, 400)) axis = Axis(fig[1, 1], title = "Bathymetry [m]") hm = heatmap!(axis, bathymetry, colormap = :deep, colorrange = (-6000, 0)) cb = Colorbar(fig[1, 2], hm) @@ -105,7 +99,6 @@ date = DateTimeProlepticGregorian(1993, 1, 1) set!(model, T = ECCOMetadata(:temperature; date), S = ECCOMetadata(:salinity; date)) - nothing #hide # ### Prescribed Atmosphere and Radiation @@ -119,7 +112,7 @@ nothing #hide # the ratio of maximum possible incident solar radiation to actual incident solar radiation) and latitude. # The ocean emissivity is set to 0.97. -backend = JRA55NetCDFBackend(4) +backend = JRA55NetCDFBackend(41) atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation(arch) nothing #hide @@ -141,9 +134,8 @@ nothing #hide # We then create a coupled simulation, starting with a time step of 10 seconds and running the simulation for 10 days. # We will eventually increase the time step size and end time as the simulation progresses and initialization shocks dissipate. # -# We also define a callback function to monitor the simulation's progress. This function -# outputs the current time, iteration, time step, as well as the maximum velocities and tracer -# values in the domain. The wall time is also printed to monitor the time taken for each iteration. +# We also define a callback function to monitor the simulation's progress. This function prints the current time, iteration, time step, +# as well as the maximum velocities and tracers in the domain. The wall time is also printed to monitor the time taken for each iteration. coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) coupled_simulation = Simulation(coupled_model; Δt=10, stop_time = 10days) @@ -175,39 +167,25 @@ nothing #hide # ### Set up Output Writers # # We define output writers to save the simulation data at regular intervals. -# In this case, we save the surface fluxes and surface fields at a relatively -# high frequency (every 12 hours). - -fluxes = (u = model.velocities.u.boundary_conditions.top.condition, - v = model.velocities.v.boundary_conditions.top.condition, - T = model.tracers.T.boundary_conditions.top.condition, - S = model.tracers.S.boundary_conditions.top.condition) - -output_kwargs = (; overwrite_existing = true, array_type = Array{Float32}) - -ocean.output_writers[:fluxes] = JLD2OutputWriter(model, fluxes; - schedule = TimeInterval(1days), - overwrite_existing = true, - filename = "surface_fluxes", - output_kwargs...) +# In this case, we save the surface fluxes and surface fields at a relatively high frequency (every day). ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); schedule = TimeInterval(1days), filename = "surface", indices = (:, :, grid.Nz), - output_kwargs...) + overwrite_existing = true, + array_type = Array{Float32}) nothing #hide # ### Warming Up the Simulation # # As an initial condition, we have interpolated ECCO tracer fields onto our custom grid. -# The bathymetry of the original ECCO data may differ from our grid, so the initialization -# of the velocity field might cause shocks if a large time step is used. +# The bathymetry of the original ECCO data may differ from our grid, so the initialization of the velocity +# field might cause shocks if a large time step is used. # -# Therefore, we start by a 'warm up', i.e., running the simulation with a small time step, -# to ensure that the interpolated initial conditions adapt to the model numerics and -# parameterization without causing instability. A 30-day integration with a maximum time step -# of 90 seconds should be sufficient to dissipate spurious initialization shocks. +# Therefore, we warm up with a small time step to ensure that the interpolated initial conditions adapt to the model numerics and +# parameterization without causing instability. A 30-day integration with a maximum time step of 1.5 minutes should be sufficient to dissipate +# spurious initialization shocks. ocean.stop_time = 10days wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) @@ -218,11 +196,11 @@ nothing #hide # ### Running the simulation # # Now that the simulation has been warmed up, we can run it for the full two years. -# We increase the maximum time step size to 10 minutes and let the simulation run for 720 days. +# We increase the maximum time step size to 12 minutes and let the simulation run for 100 days. -ocean.stop_time = 60days -coupled_simulation.stop_time = 60days -wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 15minutes, max_change = 1.1) +ocean.stop_time = 100days +coupled_simulation.stop_time = 100days +wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 12minutes, max_change = 1.1) ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) run!(coupled_simulation) nothing #hide @@ -230,46 +208,99 @@ nothing #hide # ## Visualizing the Results # # The simulation has finished, let's visualize the results. -# We first load the saved data and then create visualizations using the CairoMakie.jl package. +# In this section we pull up the saved data and create visualizations using the CairoMakie.jl package. # In particular, we generate a video of the evolution of surface fields: -# zonal velocity (u), meridional velocity (v), surface temperature (T), and turbulent kinetic energy (e) +# surface speed (s), vertical velocity just below the surface (w), surface temperature (T), and turbulent kinetic energy (e) u = FieldTimeSeries("surface.jld2", "u"; backend = OnDisk()) v = FieldTimeSeries("surface.jld2", "v"; backend = OnDisk()) T = FieldTimeSeries("surface.jld2", "T"; backend = OnDisk()) e = FieldTimeSeries("surface.jld2", "e"; backend = OnDisk()) +w = FieldTimeSeries("surface.jld2", "w"; backend = OnDisk()) Nt = length(u.times) iter = Observable(Nt) -ui = @lift(interior(u[$iter], :, :, 1)) -vi = @lift(interior(v[$iter], :, :, 1)) -Ti = @lift(interior(T[$iter], :, :, 1)) -ei = @lift(interior(e[$iter], :, :, 1)) +Ti = @lift begin + Ti = interior(T[$iter], :, :, 1)) + Ti[Ti .== 0] .= NaN + Ti +end + +ei = @lift begin + ei = interior(e[$iter], :, :, 1) + ei[ei .== 0] .= NaN + ei +end + +wi = @lift begin + wi = interior(w[$iter], :, :, 1) + wi[wi .== 0] .= NaN + wi +end + +si = @lift begin + s = sqrt(u[$iter]^2 + vi[$iter]^2) + s = Field(s) + compute!(s) + s = interior(s, :, :, 1) + s[s .== 0] .= NaN + s +end fig = Figure(size = (1000, 750)) -ax = Axis(fig[1, 1], title = "Zonal velocity [ms⁻¹]") -heatmap!(ax, ui, colorrange = (-0.5, 0.5), colormap = :bwr) +ax = Axis(fig[1, 1], title = "Surface speed [ms⁻¹]") +heatmap!(ax, si, colorrange = (0, 0.5), colormap = :deep) hidedecorations!(ax) -ax = Axis(fig[1, 2], title = "Meridional velocity [ms⁻¹]") -heatmap!(ax, vi, colorrange = (-0.5, 0.5), colormap = :bwr) +CairoMakie.record(fig, "near_global_ocean_surface_speed.mp4", 1:length(u.times), framerate = 8) do i + @info "Generating frame $i of $(length(u.times))" + iter[] = i +end +nothing #hide + +# ![](near_global_ocean_surface_speed.mp4) + +fig = Figure(size = (1000, 750)) + +ax = Axis(fig[1, 1], title = "Vertical velocity [ms⁻¹]") +heatmap!(ax, wi, colorrange = (-0.5e-3, 0.5e-3), colormap = :bwr) hidedecorations!(ax) -ax = Axis(fig[2, 1], title = "Surface Temperature [Cᵒ]") +CairoMakie.record(fig, "near_global_ocean_surface_vertical_velocity.mp4", 1:length(u.times), framerate = 8) do i + @info "Generating frame $i of $(length(u.times))" + iter[] = i +end +nothing #hide + +# ![](near_global_ocean_surface_vertical_velocity.mp4) + +fig = Figure(size = (1000, 750)) + +ax = Axis(fig[1, 1], title = "Surface Temperature [Cᵒ]") heatmap!(ax, Ti, colorrange = (-1, 30), colormap = :magma) hidedecorations!(ax) -ax = Axis(fig[2, 2], title = "Turbulent Kinetic Energy [m²s⁻²]") +CairoMakie.record(fig, "near_global_ocean_surface_temperature.mp4", 1:length(u.times), framerate = 8) do i + @info "Generating frame $i of $(length(u.times))" + iter[] = i +end +nothing #hide + +# ![](near_global_ocean_surface_temperature.mp4 + +fig = Figure(size = (1000, 750)) + +ax = Axis(fig[1, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) hidedecorations!(ax) -CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:length(u.times), framerate = 8) do i +CairoMakie.record(fig, "near_global_ocean_surface_tke.mp4", 1:length(u.times), framerate = 8) do i @info "Generating frame $i of $(length(u.times))" iter[] = i end nothing #hide -# ![](near_global_ocean_surface.mp4) +# ![](near_global_ocean_surface_tke.mp4 From 1691ffc719a139a1764c5ca9370bb0fa7a83540f Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sun, 4 Aug 2024 15:12:56 -0400 Subject: [PATCH 695/716] try again --- examples/generate_bathymetry.jl | 16 ++++----- examples/near_global_ocean_simulation.jl | 44 ++++-------------------- 2 files changed, 15 insertions(+), 45 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 23e92329..808b64e6 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -59,18 +59,18 @@ interior(h_rough)[land_rough] .= NaN land_nolakes = interior(h_nolakes) .>= 0 interior(h_nolakes)[land_nolakes] .= NaN -fig = Figure(resolution=(1400, 400)) +fig = Figure(resolution=(850, 1150)) -ax = Axis(fig[1, 1]) -hm = heatmap!(ax, λ, φ, interior(h_rough, :, :, 1), nan_color=:white, colormap = :deep) +ax = Axis(fig[1, 1], title = "Rough bathymetry", xlabel = "Longitude", ylabel = "Latitude") +hm = heatmap!(ax, λ, φ, - interior(h_rough, :, :, 1), nan_color=:white, colormap = Reverse(:deep)) -ax = Axis(fig[1, 2]) -hm = heatmap!(ax, λ, φ, interior(h_smooth, :, :, 1), nan_color=:white, colormap = :deep) +ax = Axis(fig[2, 1], title = "Smooth bathymetry", xlabel = "Longitude", ylabel = "Latitude") +hm = heatmap!(ax, λ, φ, - interior(h_smooth, :, :, 1), nan_color=:white, colormap = Reverse(:deep)) -ax = Axis(fig[1, 3]) -hm = heatmap!(ax, λ, φ, interior(h_nolakes, :, :, 1), nan_color=:white, colormap = :deep) +ax = Axis(fig[3, 1], title = "Bathymetry without lakes}", xlabel = "Longitude", ylabel = "Latitude") +hm = heatmap!(ax, λ, φ, - interior(h_nolakes, :, :, 1), nan_color=:white, colormap = Reverse(:deep)) -cb = Colorbar(fig[1, 4], hm, label="Depth [m]") +cb = Colorbar(fig[1:3, 2], hm, height = Relative(3/4), label = "Depth [m]") save("different_bottom_heights.png", fig) nothing #hide diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index cead4ffe..98bc6944 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -223,7 +223,7 @@ Nt = length(u.times) iter = Observable(Nt) Ti = @lift begin - Ti = interior(T[$iter], :, :, 1)) + Ti = interior(T[$iter], :, :, 1) Ti[Ti .== 0] .= NaN Ti end @@ -249,58 +249,28 @@ si = @lift begin s end -fig = Figure(size = (1000, 750)) +fig = Figure(size = (1000, 2800)) ax = Axis(fig[1, 1], title = "Surface speed [ms⁻¹]") heatmap!(ax, si, colorrange = (0, 0.5), colormap = :deep) hidedecorations!(ax) -CairoMakie.record(fig, "near_global_ocean_surface_speed.mp4", 1:length(u.times), framerate = 8) do i - @info "Generating frame $i of $(length(u.times))" - iter[] = i -end -nothing #hide - -# ![](near_global_ocean_surface_speed.mp4) - -fig = Figure(size = (1000, 750)) - -ax = Axis(fig[1, 1], title = "Vertical velocity [ms⁻¹]") +ax = Axis(fig[2, 1], title = "Vertical velocity [ms⁻¹]") heatmap!(ax, wi, colorrange = (-0.5e-3, 0.5e-3), colormap = :bwr) hidedecorations!(ax) -CairoMakie.record(fig, "near_global_ocean_surface_vertical_velocity.mp4", 1:length(u.times), framerate = 8) do i - @info "Generating frame $i of $(length(u.times))" - iter[] = i -end -nothing #hide - -# ![](near_global_ocean_surface_vertical_velocity.mp4) - -fig = Figure(size = (1000, 750)) - -ax = Axis(fig[1, 1], title = "Surface Temperature [Cᵒ]") +ax = Axis(fig[3, 1], title = "Surface Temperature [Cᵒ]") heatmap!(ax, Ti, colorrange = (-1, 30), colormap = :magma) hidedecorations!(ax) -CairoMakie.record(fig, "near_global_ocean_surface_temperature.mp4", 1:length(u.times), framerate = 8) do i - @info "Generating frame $i of $(length(u.times))" - iter[] = i -end -nothing #hide - -# ![](near_global_ocean_surface_temperature.mp4 - -fig = Figure(size = (1000, 750)) - -ax = Axis(fig[1, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") +ax = Axis(fig[4, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) hidedecorations!(ax) -CairoMakie.record(fig, "near_global_ocean_surface_tke.mp4", 1:length(u.times), framerate = 8) do i +CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:length(u.times), framerate = 8) do i @info "Generating frame $i of $(length(u.times))" iter[] = i end nothing #hide -# ![](near_global_ocean_surface_tke.mp4 +# ![](near_global_ocean_surface.mp4) From 20468f8c2f06070670862ab025d213028bc6b664 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Mon, 5 Aug 2024 10:32:52 +1000 Subject: [PATCH 696/716] fix bug --- examples/near_global_ocean_simulation.jl | 30 +++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 98bc6944..f0eea682 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -161,7 +161,7 @@ function progress(sim) wall_time[1] = time_ns() end -coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(500)) +coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1000)) nothing #hide # ### Set up Output Writers @@ -173,7 +173,7 @@ ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, mo schedule = TimeInterval(1days), filename = "surface", indices = (:, :, grid.Nz), - overwrite_existing = true, + overwrite_existing = true, array_type = Array{Float32}) nothing #hide @@ -183,9 +183,9 @@ nothing #hide # The bathymetry of the original ECCO data may differ from our grid, so the initialization of the velocity # field might cause shocks if a large time step is used. # -# Therefore, we warm up with a small time step to ensure that the interpolated initial conditions adapt to the model numerics and -# parameterization without causing instability. A 30-day integration with a maximum time step of 1.5 minutes should be sufficient to dissipate -# spurious initialization shocks. +# Therefore, we warm up with a small time step to ensure that the interpolated initial conditions adapt +# to the model numerics and parameterization without causing instability. A 10-day integration with +# a maximum time step of 1.5 minutes should be sufficient to dissipate spurious initialization shocks. ocean.stop_time = 10days wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) @@ -209,8 +209,9 @@ nothing #hide # # The simulation has finished, let's visualize the results. # In this section we pull up the saved data and create visualizations using the CairoMakie.jl package. -# In particular, we generate a video of the evolution of surface fields: -# surface speed (s), vertical velocity just below the surface (w), surface temperature (T), and turbulent kinetic energy (e) +# In particular, we generate an animation of the evolution of surface fields: +# surface speed (s), vertical velocity just below the surface (w), surface temperature (T), and +# turbulent kinetic energy (e). u = FieldTimeSeries("surface.jld2", "u"; backend = OnDisk()) v = FieldTimeSeries("surface.jld2", "v"; backend = OnDisk()) @@ -218,7 +219,8 @@ T = FieldTimeSeries("surface.jld2", "T"; backend = OnDisk()) e = FieldTimeSeries("surface.jld2", "e"; backend = OnDisk()) w = FieldTimeSeries("surface.jld2", "w"; backend = OnDisk()) -Nt = length(u.times) +times = u.times +Nt = length(times) iter = Observable(Nt) @@ -241,8 +243,7 @@ wi = @lift begin end si = @lift begin - s = sqrt(u[$iter]^2 + vi[$iter]^2) - s = Field(s) + s = Field(sqrt(u[$iter]^2 + v[$iter]^2)) compute!(s) s = interior(s, :, :, 1) s[s .== 0] .= NaN @@ -256,7 +257,7 @@ heatmap!(ax, si, colorrange = (0, 0.5), colormap = :deep) hidedecorations!(ax) ax = Axis(fig[2, 1], title = "Vertical velocity [ms⁻¹]") -heatmap!(ax, wi, colorrange = (-0.5e-3, 0.5e-3), colormap = :bwr) +heatmap!(ax, wi, colorrange = (-5e-4, 5e-4), colormap = :bwr) hidedecorations!(ax) ax = Axis(fig[3, 1], title = "Surface Temperature [Cᵒ]") @@ -267,10 +268,11 @@ ax = Axis(fig[4, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) hidedecorations!(ax) -CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:length(u.times), framerate = 8) do i - @info "Generating frame $i of $(length(u.times))" - iter[] = i +CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:Nt, framerate = 8) do i + @info "Generating frame $i of $Nt" + iter[] = i end + nothing #hide # ![](near_global_ocean_surface.mp4) From 32d25db7324b19f77b987c14e3b7896818fc797d Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 5 Aug 2024 08:58:10 -0400 Subject: [PATCH 697/716] change figure size --- examples/near_global_ocean_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 98bc6944..27509a22 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -249,7 +249,7 @@ si = @lift begin s end -fig = Figure(size = (1000, 2800)) +fig = Figure(size = (850, 1650)) ax = Axis(fig[1, 1], title = "Surface speed [ms⁻¹]") heatmap!(ax, si, colorrange = (0, 0.5), colormap = :deep) From e76f053c8b3139795cb548317e124c619b8ce30a Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 5 Aug 2024 15:33:47 -0400 Subject: [PATCH 698/716] one movie per quantity --- examples/near_global_ocean_simulation.jl | 46 ++++++++++++++++++------ 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index bc32d03f..e52290de 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -250,29 +250,55 @@ si = @lift begin s end -fig = Figure(size = (850, 1650)) +fig = Figure(size = (800, 400)) ax = Axis(fig[1, 1], title = "Surface speed [ms⁻¹]") heatmap!(ax, si, colorrange = (0, 0.5), colormap = :deep) hidedecorations!(ax) -ax = Axis(fig[2, 1], title = "Vertical velocity [ms⁻¹]") +CairoMakie.record(fig, "near_global_ocean_surface_s.mp4", 1:Nt, framerate = 8) do i + @info "Generating frame $i of $Nt" + iter[] = i +end +nothing #hide + + # ![](near_global_ocean_surface_s.mp4) + +fig = Figure(size = (800, 400)) +ax = Axis(fig[1, 1], title = "Vertical velocity [ms⁻¹]") heatmap!(ax, wi, colorrange = (-5e-4, 5e-4), colormap = :bwr) hidedecorations!(ax) -ax = Axis(fig[3, 1], title = "Surface Temperature [Cᵒ]") +CairoMakie.record(fig, "near_global_ocean_surface_w.mp4", 1:Nt, framerate = 8) do i + @info "Generating frame $i of $Nt" + iter[] = i +end +nothing #hide + +# ![](near_global_ocean_surface_w.mp4) + +fig = Figure(size = (800, 400)) +ax = Axis(fig[1, 1], title = "Surface Temperature [Cᵒ]") heatmap!(ax, Ti, colorrange = (-1, 30), colormap = :magma) hidedecorations!(ax) -ax = Axis(fig[4, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") +CairoMakie.record(fig, "near_global_ocean_surface_T.mp4", 1:Nt, framerate = 8) do i + @info "Generating frame $i of $Nt" + iter[] = i +end +nothing #hide + +# ![](near_global_ocean_surface_T.mp4) + +fig = Figure(size = (800, 400)) +ax = Axis(fig[1, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) hidedecorations!(ax) -CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt" - iter[] = i +CairoMakie.record(fig, "near_global_ocean_surface_e.mp4", 1:Nt, framerate = 8) do i + @info "Generating frame $i of $Nt" + iter[] = i end - nothing #hide - -# ![](near_global_ocean_surface.mp4) + +# ![](near_global_ocean_surface_e.mp4) From 0cc5af08f2931d7a07ff77fa02ab4f06a98206c8 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 5 Aug 2024 16:58:05 -0400 Subject: [PATCH 699/716] bugfix --- .../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 d03f3ef0..733ac773 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -215,7 +215,7 @@ and ``Π`` is the "similarity profile", which is a logarithmic profile adjusted by the stability function ``ψ`` and dependent on the Monin-Obukhov length ``L`` and the roughness length ``ℓ``. """ -struct LogarthmicSimilarityProfile end +struct LogarithmicSimilarityProfile end struct COARELogarthmicSimilarityProfile end @inline similarity_profile(::LogarthmicSimilarityProfile, ψ, h, ℓ, L) = From eedc8b7a4f963f8faf5597ec317d51b7bfa5d43a Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 5 Aug 2024 16:58:54 -0400 Subject: [PATCH 700/716] fix typo --- .../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 d03f3ef0..733ac773 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -215,7 +215,7 @@ and ``Π`` is the "similarity profile", which is a logarithmic profile adjusted by the stability function ``ψ`` and dependent on the Monin-Obukhov length ``L`` and the roughness length ``ℓ``. """ -struct LogarthmicSimilarityProfile end +struct LogarithmicSimilarityProfile end struct COARELogarthmicSimilarityProfile end @inline similarity_profile(::LogarthmicSimilarityProfile, ψ, h, ℓ, L) = From 21386db858aafab0b9571ba5b565f65183fa35c0 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 5 Aug 2024 17:08:15 -0400 Subject: [PATCH 701/716] some more bugfixes --- .../similarity_theory_turbulent_fluxes.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl index 733ac773..851ac9a6 100644 --- a/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/CrossRealmFluxes/similarity_theory_turbulent_fluxes.jl @@ -197,7 +197,7 @@ end ##### """ - LogarthmicSimilarityProfile() + LogarithmicSimilarityProfile() Represents the classic Monin-Obukhov similarity profile, which finds that @@ -216,12 +216,12 @@ which is a logarithmic profile adjusted by the stability function ``ψ`` and dep the Monin-Obukhov length ``L`` and the roughness length ``ℓ``. """ struct LogarithmicSimilarityProfile end -struct COARELogarthmicSimilarityProfile end +struct COARELogarithmicSimilarityProfile end -@inline similarity_profile(::LogarthmicSimilarityProfile, ψ, h, ℓ, L) = +@inline similarity_profile(::LogarithmicSimilarityProfile, ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) + ψ(ℓ / L) -@inline similarity_profile(::COARELogarthmicSimilarityProfile, ψ, h, ℓ, L) = +@inline similarity_profile(::COARELogarithmicSimilarityProfile, ψ, h, ℓ, L) = log(h / ℓ) - ψ(h / L) ##### From e72d56c8e40b0c55d8425cfa296847c579cc4c53 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 6 Aug 2024 15:56:35 -0400 Subject: [PATCH 702/716] first small change --- examples/near_global_ocean_simulation.jl | 54 +++++++++--------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index e52290de..80b652d3 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -186,22 +186,24 @@ nothing #hide # Therefore, we warm up with a small time step to ensure that the interpolated initial conditions adapt # to the model numerics and parameterization without causing instability. A 10-day integration with # a maximum time step of 1.5 minutes should be sufficient to dissipate spurious initialization shocks. +# We use an adaptive time step that maintains the [CFL condition](https://en.wikipedia.org/wiki/Courant%E2%80%93Friedrichs%E2%80%93Lewy_condition) equal to 0.1. +# For this scope, we use the Oceananigans utility `conjure_time_step_wizard!` (see Oceanigans's documentation) ocean.stop_time = 10days -wizard = TimeStepWizard(; cfl = 0.1, max_Δt = 90, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +conjure_time_step_wizard!(ocean; cfl = 0.1, max_Δt = 90, max_change = 1.1) run!(coupled_simulation) nothing #hide # ### Running the simulation # -# Now that the simulation has been warmed up, we can run it for the full two years. -# We increase the maximum time step size to 12 minutes and let the simulation run for 100 days. +# Now that the simulation has been warmed up, we can run it for the full 100 days. +# We increase the maximum time step size to 10 minutes and let the simulation run for 100 days. +# This time, we set the CFL in the time_step_wizard to be 0.25 as this is the recommended CFL to be +# used in conjunction with Oceananigans' hydrosta ocean.stop_time = 100days coupled_simulation.stop_time = 100days -wizard = TimeStepWizard(; cfl = 0.25, max_Δt = 12minutes, max_change = 1.1) -ocean.callbacks[:wizard] = Callback(wizard, IterationInterval(10)) +conjure_time_step_wizard!(ocean; cfl = 0.25, max_Δt = 600, max_change = 1.1) run!(coupled_simulation) nothing #hide @@ -210,14 +212,12 @@ nothing #hide # The simulation has finished, let's visualize the results. # In this section we pull up the saved data and create visualizations using the CairoMakie.jl package. # In particular, we generate an animation of the evolution of surface fields: -# surface speed (s), vertical velocity just below the surface (w), surface temperature (T), and -# turbulent kinetic energy (e). +# surface speed (s), surface temperature (T), and turbulent kinetic energy (e). u = FieldTimeSeries("surface.jld2", "u"; backend = OnDisk()) v = FieldTimeSeries("surface.jld2", "v"; backend = OnDisk()) T = FieldTimeSeries("surface.jld2", "T"; backend = OnDisk()) e = FieldTimeSeries("surface.jld2", "e"; backend = OnDisk()) -w = FieldTimeSeries("surface.jld2", "w"; backend = OnDisk()) times = u.times Nt = length(times) @@ -236,12 +236,6 @@ ei = @lift begin ei end -wi = @lift begin - wi = interior(w[$iter], :, :, 1) - wi[wi .== 0] .= NaN - wi -end - si = @lift begin s = Field(sqrt(u[$iter]^2 + v[$iter]^2)) compute!(s) @@ -252,12 +246,13 @@ end fig = Figure(size = (800, 400)) -ax = Axis(fig[1, 1], title = "Surface speed [ms⁻¹]") +ax = Axis(fig[1, 1]) heatmap!(ax, si, colorrange = (0, 0.5), colormap = :deep) +cb = Colorbar(fig[0, 1], vertical = false, label = "Surface speed [ms⁻¹]") hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_s.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt" + @info "Generating frame $i of $Nt \r" iter[] = i end nothing #hide @@ -265,25 +260,13 @@ nothing #hide # ![](near_global_ocean_surface_s.mp4) fig = Figure(size = (800, 400)) -ax = Axis(fig[1, 1], title = "Vertical velocity [ms⁻¹]") -heatmap!(ax, wi, colorrange = (-5e-4, 5e-4), colormap = :bwr) -hidedecorations!(ax) - -CairoMakie.record(fig, "near_global_ocean_surface_w.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt" - iter[] = i -end -nothing #hide - -# ![](near_global_ocean_surface_w.mp4) - -fig = Figure(size = (800, 400)) -ax = Axis(fig[1, 1], title = "Surface Temperature [Cᵒ]") -heatmap!(ax, Ti, colorrange = (-1, 30), colormap = :magma) +ax = Axis(fig[1, 1]) +hm = heatmap!(ax, Ti, colorrange = (-1, 30), colormap = :magma) +cb = Colorbar(fig[0, 1], vertical = false, label = "Surface Temperature [Cᵒ]") hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_T.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt" + @info "Generating frame $i of $Nt \r" iter[] = i end nothing #hide @@ -291,12 +274,13 @@ nothing #hide # ![](near_global_ocean_surface_T.mp4) fig = Figure(size = (800, 400)) -ax = Axis(fig[1, 1], title = "Turbulent Kinetic Energy [m²s⁻²]") +ax = Axis(fig[1, 1]) heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) +cb = Colorbar(fig[0, 1], vertical = false, label = "Turbulent Kinetic Energy [m²s⁻²]") hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_e.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt" + @info "Generating frame $i of $Nt \r" iter[] = i end nothing #hide From 2cfa937956a2b45c1f3839c867efb17ab5655836 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 7 Aug 2024 06:56:24 +1000 Subject: [PATCH 703/716] lakes -> connected regions --- examples/generate_bathymetry.jl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 808b64e6..374eed39 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -37,13 +37,13 @@ grid = LatitudeLongitudeGrid(size = (Nλ, Nφ, 1), # one interpolation passes and no restrictions on connected regions. # - `h_smooth` shows the output of the function with 40 interpolation passes, which results # in a smoother bathymetry. -# - `h_nolakes` shows the output of the function with `connected_regions_allowed = 0`, which +# - `h_no_connected_regions` shows the output of the function with `connected_regions_allowed = 0`, which # means that the function does not allow connected regions in the bathymetry (e.g., lakes) # and fills them with land. -h_rough = regrid_bathymetry(grid) -h_smooth = regrid_bathymetry(grid; interpolation_passes = 40) -h_nolakes = regrid_bathymetry(grid; connected_regions_allowed = 0) +h_rough = regrid_bathymetry(grid) +h_smooth = regrid_bathymetry(grid; interpolation_passes = 40) +h_no_connected_regions = regrid_bathymetry(grid; connected_regions_allowed = 0) nothing # hide # Finally, we visualize the generated bathymetry data for the Mediterranean Sea using CairoMakie. @@ -56,8 +56,8 @@ interior(h_smooth)[land_smooth] .= NaN land_rough = interior(h_rough) .>= 0 interior(h_rough)[land_rough] .= NaN -land_nolakes = interior(h_nolakes) .>= 0 -interior(h_nolakes)[land_nolakes] .= NaN +land_no_connected_regions = interior(h_no_connected_regions) .>= 0 +interior(h_no_connected_regions)[land_no_connected_regions] .= NaN fig = Figure(resolution=(850, 1150)) @@ -67,8 +67,8 @@ hm = heatmap!(ax, λ, φ, - interior(h_rough, :, :, 1), nan_color=:white, colorm ax = Axis(fig[2, 1], title = "Smooth bathymetry", xlabel = "Longitude", ylabel = "Latitude") hm = heatmap!(ax, λ, φ, - interior(h_smooth, :, :, 1), nan_color=:white, colormap = Reverse(:deep)) -ax = Axis(fig[3, 1], title = "Bathymetry without lakes}", xlabel = "Longitude", ylabel = "Latitude") -hm = heatmap!(ax, λ, φ, - interior(h_nolakes, :, :, 1), nan_color=:white, colormap = Reverse(:deep)) +ax = Axis(fig[3, 1], title = "Bathymetry without connected regions}", xlabel = "Longitude", ylabel = "Latitude") +hm = heatmap!(ax, λ, φ, - interior(h_no_connected_regions, :, :, 1), nan_color=:white, colormap = Reverse(:deep)) cb = Colorbar(fig[1:3, 2], hm, height = Relative(3/4), label = "Depth [m]") From 832803fbc7665970fe85e078d272c57dab947e44 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 7 Aug 2024 06:58:19 +1000 Subject: [PATCH 704/716] warm up -> spin up --- examples/near_global_ocean_simulation.jl | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 80b652d3..e6583416 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -177,17 +177,18 @@ ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, mo array_type = Array{Float32}) nothing #hide -# ### Warming Up the Simulation +# ### Spinning Up the Simulation # # As an initial condition, we have interpolated ECCO tracer fields onto our custom grid. # The bathymetry of the original ECCO data may differ from our grid, so the initialization of the velocity # field might cause shocks if a large time step is used. # -# Therefore, we warm up with a small time step to ensure that the interpolated initial conditions adapt -# to the model numerics and parameterization without causing instability. A 10-day integration with -# a maximum time step of 1.5 minutes should be sufficient to dissipate spurious initialization shocks. +# Therefore, we spin up the simulation with a small time step to ensure that the interpolated initial +# conditions adapt to the model numerics and parameterization without causing instability. A 10-day +# integration with a maximum time step of 1.5 minutes should be sufficient to dissipate spurious +# initialization shocks. # We use an adaptive time step that maintains the [CFL condition](https://en.wikipedia.org/wiki/Courant%E2%80%93Friedrichs%E2%80%93Lewy_condition) equal to 0.1. -# For this scope, we use the Oceananigans utility `conjure_time_step_wizard!` (see Oceanigans's documentation) +# For this scope, we use the Oceananigans utility `conjure_time_step_wizard!` (see Oceanigans's documentation). ocean.stop_time = 10days conjure_time_step_wizard!(ocean; cfl = 0.1, max_Δt = 90, max_change = 1.1) @@ -196,10 +197,10 @@ nothing #hide # ### Running the simulation # -# Now that the simulation has been warmed up, we can run it for the full 100 days. +# Now that the simulation has spun up, we can run it for the full 100 days. # We increase the maximum time step size to 10 minutes and let the simulation run for 100 days. -# This time, we set the CFL in the time_step_wizard to be 0.25 as this is the recommended CFL to be -# used in conjunction with Oceananigans' hydrosta +# This time, we set the CFL in the `time_step_wizard` to be 0.25; this is the recommended CFL to be +# used in conjunction with Oceananigans' hydrostatic model. ocean.stop_time = 100days coupled_simulation.stop_time = 100days From 906341e2f302d09f1f4da4231978cc2298e21be3 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 7 Aug 2024 07:02:31 +1000 Subject: [PATCH 705/716] add colorbars --- examples/near_global_ocean_simulation.jl | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index e6583416..93c58672 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -66,10 +66,10 @@ bathymetry = deepcopy(Array(interior(bottom_height, :, :, 1))) bathymetry[bathymetry .>= 0] .= NaN fig = Figure(size = (800, 400)) -axis = Axis(fig[1, 1], title = "Bathymetry [m]") +ax = Axis(fig[1, 1], title = "Bathymetry [m]") hm = heatmap!(axis, bathymetry, colormap = :deep, colorrange = (-6000, 0)) cb = Colorbar(fig[1, 2], hm) -hidedecorations!(axis) +hidedecorations!(ax) save("bathymetry.png", fig) nothing #hide @@ -204,7 +204,7 @@ nothing #hide ocean.stop_time = 100days coupled_simulation.stop_time = 100days -conjure_time_step_wizard!(ocean; cfl = 0.25, max_Δt = 600, max_change = 1.1) +conjure_time_step_wizard!(ocean; cfl = 0.25, max_Δt = 10minutes, max_change = 1.1) run!(coupled_simulation) nothing #hide @@ -248,13 +248,13 @@ end fig = Figure(size = (800, 400)) ax = Axis(fig[1, 1]) -heatmap!(ax, si, colorrange = (0, 0.5), colormap = :deep) -cb = Colorbar(fig[0, 1], vertical = false, label = "Surface speed [ms⁻¹]") +hm = heatmap!(ax, si, colorrange = (0, 0.5), colormap = :deep) +cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Surface speed [ms⁻¹]") hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_s.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt \r" - iter[] = i + @info "Generating frame $i of $Nt \r" + iter[] = i end nothing #hide @@ -263,12 +263,12 @@ nothing #hide fig = Figure(size = (800, 400)) ax = Axis(fig[1, 1]) hm = heatmap!(ax, Ti, colorrange = (-1, 30), colormap = :magma) -cb = Colorbar(fig[0, 1], vertical = false, label = "Surface Temperature [Cᵒ]") +cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Surface Temperature [Cᵒ]") hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_T.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt \r" - iter[] = i + @info "Generating frame $i of $Nt \r" + iter[] = i end nothing #hide @@ -276,14 +276,14 @@ nothing #hide fig = Figure(size = (800, 400)) ax = Axis(fig[1, 1]) -heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) -cb = Colorbar(fig[0, 1], vertical = false, label = "Turbulent Kinetic Energy [m²s⁻²]") +hm = heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) +cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Turbulent Kinetic Energy [m²s⁻²]") hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_e.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt \r" - iter[] = i + @info "Generating frame $i of $Nt \r" + iter[] = i end nothing #hide - + # ![](near_global_ocean_surface_e.mp4) From d7afd8a02d63af891acd5709fa0291f851b7ac96 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 7 Aug 2024 07:07:36 +1000 Subject: [PATCH 706/716] code alignment --- examples/near_global_ocean_simulation.jl | 60 ++++++++++++++---------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 93c58672..5a62d6f2 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -41,19 +41,21 @@ Nx = 1440 Ny = 600 Nz = length(z_faces) - 1 -grid = LatitudeLongitudeGrid(arch; - size = (Nx, Ny, Nz), - halo = (7, 7, 7), +grid = LatitudeLongitudeGrid(arch; + size = (Nx, Ny, Nz), + halo = (7, 7, 7), z = z_faces, latitude = (-75, 75), longitude = (0, 360)) # ### Bathymetry and Immersed Boundary # -# We retrieve the bathymetry from the ETOPO1 data, ensuring a minimum depth of 10 meters (depths shallower than this are considered land). -# The `interpolation_passes` parameter specifies the number of passes to interpolate the bathymetry data. A larger number -# results in a smoother bathymetry. We also remove all connected regions (such as inland lakes) from the bathymetry data by specifying -# `connected_regions_allowed = 2` (Mediterrean sea an North sea in addition to the ocean) +# We retrieve the bathymetry from the ETOPO1 data, ensuring a minimum depth of 10 meters +# (depths shallower than this are considered land). The `interpolation_passes` parameter +# specifies the number of passes to interpolate the bathymetry data. A larger number +# results in a smoother bathymetry. We also remove all connected regions (such as inland +# lakes) from the bathymetry data by specifying `connected_regions_allowed = 2` (Mediterrean +# sea an North sea in addition to the ocean). bottom_height = retrieve_bathymetry(grid; minimum_depth = 10, @@ -91,7 +93,7 @@ nothing #hide free_surface = SplitExplicitFreeSurface(grid; substeps = 75) -ocean = ocean_simulation(grid; free_surface) +ocean = ocean_simulation(grid; free_surface) model = ocean.model date = DateTimeProlepticGregorian(1993, 1, 1) @@ -103,14 +105,15 @@ nothing #hide # ### Prescribed Atmosphere and Radiation # -# The atmospheric data is prescribed using the JRA55 dataset, which is loaded into memory in 4 snapshots at a time. -# The JRA55 dataset provides atmospheric data such as temperature, humidity, and wind fields to calculate turbulent fluxes +# The atmospheric data is prescribed using the JRA55 dataset, which is loaded +# into memory in 4 snapshots at a time. The JRA55 dataset provides atmospheric +# data such as temperature, humidity, and wind fields to calculate turbulent fluxes # using bulk formulae, see [`CrossRealmFluxes`](@ref). # -# The radiation model specifies an ocean albedo emissivity to compute the net radiative fluxes. -# The default ocean albedo is based on Payne (1982) and depends on cloud cover (calculated from -# the ratio of maximum possible incident solar radiation to actual incident solar radiation) and latitude. -# The ocean emissivity is set to 0.97. +# The radiation model specifies an ocean albedo emissivity to compute the net radiative +# fluxes. The default ocean albedo is based on Payne (1982) and depends on cloud cover +# (calculated from the ratio of maximum possible incident solar radiation to actual +# incident solar radiation) and latitude. The ocean emissivity is set to 0.97. backend = JRA55NetCDFBackend(41) atmosphere = JRA55_prescribed_atmosphere(arch; backend) @@ -119,23 +122,30 @@ nothing #hide # ### Sea Ice Model # -# This simulation includes a simplified representation of ice cover where the air-sea fluxes are shut down whenever the -# sea surface temperature is below the freezing point. Only heating fluxes are allowed. This is not a full sea ice model, -# but it prevents the temperature from dropping excessively low by including atmosphere-ocean fluxes. +# This simulation includes a simplified representation of ice cover where the +# air-sea fluxes are shut down whenever the sea surface temperature is below +# the freezing point. Only heating fluxes are allowed. This is not a full +# sea ice model, but it prevents the temperature from dropping excessively +# low by including atmosphere-ocean fluxes. sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() nothing #hide # ## The Coupled Simulation # -# Finally, we define the coupled model, which includes the ocean, atmosphere, and radiation parameters. -# The model is constructed using the `OceanSeaIceModel` constructor. +# Finally, we define the coupled model, which includes the ocean, atmosphere, +# and radiation parameters. The model is constructed using the `OceanSeaIceModel` +# constructor. # -# We then create a coupled simulation, starting with a time step of 10 seconds and running the simulation for 10 days. -# We will eventually increase the time step size and end time as the simulation progresses and initialization shocks dissipate. +# We then create a coupled simulation, starting with a time step of 10 seconds +# and running the simulation for 10 days. +# We will eventually increase the time step size and end time as the simulation +# progresses and initialization shocks dissipate. # -# We also define a callback function to monitor the simulation's progress. This function prints the current time, iteration, time step, -# as well as the maximum velocities and tracers in the domain. The wall time is also printed to monitor the time taken for each iteration. +# We also define a callback function to monitor the simulation's progress. +# This function prints the current time, iteration, time step, +# as well as the maximum velocities and tracers in the domain. The wall time +# is also printed to monitor the time taken for each iteration. coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) coupled_simulation = Simulation(coupled_model; Δt=10, stop_time = 10days) @@ -144,7 +154,7 @@ wall_time = [time_ns()] function progress(sim) ocean = sim.model.ocean - u, v, w = ocean.model.velocities + u, v, w = ocean.model.velocities T = ocean.model.tracers.T Tmax = maximum(interior(T)) @@ -166,7 +176,7 @@ nothing #hide # ### Set up Output Writers # -# We define output writers to save the simulation data at regular intervals. +# We define output writers to save the simulation data at regular intervals. # In this case, we save the surface fluxes and surface fields at a relatively high frequency (every day). ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); From 26968911cadd30d0cdec0ae30539a4e9560bce05 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 7 Aug 2024 08:49:35 -0400 Subject: [PATCH 707/716] bugfix --- examples/near_global_ocean_simulation.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 80b652d3..ad00babf 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -65,11 +65,11 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) bathymetry = deepcopy(Array(interior(bottom_height, :, :, 1))) bathymetry[bathymetry .>= 0] .= NaN -fig = Figure(size = (800, 400)) -axis = Axis(fig[1, 1], title = "Bathymetry [m]") -hm = heatmap!(axis, bathymetry, colormap = :deep, colorrange = (-6000, 0)) -cb = Colorbar(fig[1, 2], hm) -hidedecorations!(axis) +fig = Figure(size = (1200, 400)) +ax = Axis(fig[1, 1]) +hm = heatmap!(ax, bathymetry, colormap = :deep, colorrange = (-6000, 0)) +cb = Colorbar(fig[0, 1], hm, label = "Bottom height [m]", vertical = false) +hidedecorations!(ax) save("bathymetry.png", fig) nothing #hide @@ -198,8 +198,8 @@ nothing #hide # # Now that the simulation has been warmed up, we can run it for the full 100 days. # We increase the maximum time step size to 10 minutes and let the simulation run for 100 days. -# This time, we set the CFL in the time_step_wizard to be 0.25 as this is the recommended CFL to be -# used in conjunction with Oceananigans' hydrosta +# This time, we set the CFL in the time_step_wizard to be 0.25 as this is the maximum recommended CFL to be +# used in conjunction with Oceananigans' hydrostatic time-stepping algorithm ([two step Adams-Bashfort](https://en.wikipedia.org/wiki/Linear_multistep_method)) ocean.stop_time = 100days coupled_simulation.stop_time = 100days From 1418c46c18dac386d4311bb4753623ca1a4bb317 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 9 Aug 2024 18:00:13 -0400 Subject: [PATCH 708/716] some formatting changes --- examples/near_global_ocean_simulation.jl | 43 ++++++++++-------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 6bfaf3c2..0360d707 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -1,11 +1,11 @@ -# # Near-global Ocean Simulation +# # Near-global ocean simulation # # This Julia script sets up and runs a near-global ocean simulation using the Oceananigans.jl and ClimaOcean.jl packages. # The simulation covers latitudes from 75°S to 75°N with a horizontal resolution of 1/4 degree and 40 vertical levels. # # The simulation runs for one year, and the results are visualized using the CairoMakie.jl package. # -# ## Initial Setup with Package Imports +# ## Initial setup with package imports # # The script begins by importing the necessary Julia packages for visualization (CairoMakie), # ocean modeling (Oceananigans, ClimaOcean), and handling dates and times (CFTime, Dates). @@ -15,18 +15,13 @@ using Printf using Oceananigans using Oceananigans.Units -using Oceananigans: architecture, on_architecture using ClimaOcean -using ClimaOcean.ECCO -using ClimaOcean.OceanSimulations -using ClimaOcean.OceanSeaIceModels using CairoMakie -using OrthogonalSphericalShellGrids using CFTime using Dates -# ### Grid Configuration +# ### Grid configuration # # We define a global grid with a horizontal resolution of 1/4 degree and 40 vertical levels. # The grid is a `LatitudeLongitudeGrid` capped at 75°S to 75°N. @@ -48,7 +43,7 @@ grid = LatitudeLongitudeGrid(arch; latitude = (-75, 75), longitude = (0, 360)) -# ### Bathymetry and Immersed Boundary +# ### Bathymetry and immersed boundary # # We retrieve the bathymetry from the ETOPO1 data, ensuring a minimum depth of 10 meters # (depths shallower than this are considered land). The `interpolation_passes` parameter @@ -57,10 +52,10 @@ grid = LatitudeLongitudeGrid(arch; # lakes) from the bathymetry data by specifying `connected_regions_allowed = 2` (Mediterrean # sea an North sea in addition to the ocean). -bottom_height = retrieve_bathymetry(grid; - minimum_depth = 10, - interpolation_passes = 5, - connected_regions_allowed = 2) +bottom_height = regrid_bathymetry(grid; + minimum_depth = 10, + interpolation_passes = 5, + connected_regions_allowed = 2) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) @@ -78,7 +73,7 @@ nothing #hide # ![](bathymetry.png) -# ### Ocean Model Configuration +# ### Ocean model configuration # # To configure the ocean simulation, we use the `ocean_simulation` function from ClimaOcean.jl. This function allows us to build # an ocean simulation with default parameters and numerics. The defaults include: @@ -91,9 +86,7 @@ nothing #hide # # The ocean model is then initialized with the ECCO2 temperature and salinity fields for January 1, 1993. -free_surface = SplitExplicitFreeSurface(grid; substeps = 75) - -ocean = ocean_simulation(grid; free_surface) +ocean = ocean_simulation(grid) model = ocean.model date = DateTimeProlepticGregorian(1993, 1, 1) @@ -103,7 +96,7 @@ set!(model, S = ECCOMetadata(:salinity; date)) nothing #hide -# ### Prescribed Atmosphere and Radiation +# ### Prescribed atmosphere and radiation # # The atmospheric data is prescribed using the JRA55 dataset, which is loaded # into memory in 4 snapshots at a time. The JRA55 dataset provides atmospheric @@ -120,7 +113,7 @@ atmosphere = JRA55_prescribed_atmosphere(arch; backend) radiation = Radiation(arch) nothing #hide -# ### Sea Ice Model +# ### Sea ice model # # This simulation includes a simplified representation of ice cover where the # air-sea fluxes are shut down whenever the sea surface temperature is below @@ -131,7 +124,7 @@ nothing #hide sea_ice = ClimaOcean.OceanSeaIceModels.MinimumTemperatureSeaIce() nothing #hide -# ## The Coupled Simulation +# ## The coupled simulation # # Finally, we define the coupled model, which includes the ocean, atmosphere, # and radiation parameters. The model is constructed using the `OceanSeaIceModel` @@ -174,10 +167,11 @@ end coupled_simulation.callbacks[:progress] = Callback(progress, IterationInterval(1000)) nothing #hide -# ### Set up Output Writers +# ### Set up output writers # # We define output writers to save the simulation data at regular intervals. # In this case, we save the surface fluxes and surface fields at a relatively high frequency (every day). +# The `indices` keyword argument allows us to save down a slice at the surface, which is located at `k = grid.Nz` ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, model.velocities); schedule = TimeInterval(1days), @@ -187,7 +181,7 @@ ocean.output_writers[:surface] = JLD2OutputWriter(model, merge(model.tracers, mo array_type = Array{Float32}) nothing #hide -# ### Spinning Up the Simulation +# ### Spinning up the simulation # # As an initial condition, we have interpolated ECCO tracer fields onto our custom grid. # The bathymetry of the original ECCO data may differ from our grid, so the initialization of the velocity @@ -218,7 +212,7 @@ conjure_time_step_wizard!(ocean; cfl = 0.25, max_Δt = 10minutes, max_change = 1 run!(coupled_simulation) nothing #hide -# ## Visualizing the Results +# ## Visualizing the results # # The simulation has finished, let's visualize the results. # In this section we pull up the saved data and create visualizations using the CairoMakie.jl package. @@ -263,7 +257,6 @@ cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Surface speed [ms⁻¹]" hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_s.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt \r" iter[] = i end nothing #hide @@ -277,7 +270,6 @@ cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Surface Temperature [C hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_T.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt \r" iter[] = i end nothing #hide @@ -291,7 +283,6 @@ cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Turbulent Kinetic Energy hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_e.mp4", 1:Nt, framerate = 8) do i - @info "Generating frame $i of $Nt \r" iter[] = i end nothing #hide From 3613f056234b5eccac2c3776e8fd4f71e298b372 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Sat, 10 Aug 2024 13:01:41 -0400 Subject: [PATCH 709/716] bugfix --- src/ClimaOcean.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 86bd2339..ff1b7be7 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -7,6 +7,7 @@ export SimilarityTheoryTurbulentFluxes, JRA55_prescribed_atmosphere, JRA55NetCDFBackend, + ECCOMetadata, ecco2_field, regrid_bathymetry, retrieve_bathymetry, @@ -69,7 +70,7 @@ using .DataWrangling using .InitialConditions using .OceanSeaIceModels using .OceanSimulations -using .DataWrangling: JRA55, ECCO +using .DataWrangling: JRA55, ECCO, ECCOMetadata using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend using ClimaOcean.DataWrangling.ECCO: ecco_field From 92f2d9a49df0d4a96588f410855e8a7d707f62ea Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Sat, 10 Aug 2024 13:02:06 -0400 Subject: [PATCH 710/716] typo --- src/ClimaOcean.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index ff1b7be7..9c22df5e 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -70,9 +70,9 @@ using .DataWrangling using .InitialConditions using .OceanSeaIceModels using .OceanSimulations -using .DataWrangling: JRA55, ECCO, ECCOMetadata +using .DataWrangling: JRA55, ECCO using ClimaOcean.DataWrangling.JRA55: JRA55_prescribed_atmosphere, JRA55NetCDFBackend -using ClimaOcean.DataWrangling.ECCO: ecco_field +using ClimaOcean.DataWrangling.ECCO: ecco_field, ECCOMetadata end # module From 79383454a008cd829ae8f73e95438b5581ffd3ec Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 10 Aug 2024 16:36:26 -0400 Subject: [PATCH 711/716] bugfix --- 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 84d3e4b8..80d2b490 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -15,7 +15,7 @@ using Oceananigans.TimeSteppers: tick! using Oceananigans.Models: AbstractModel using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries -using ClimaSeaIce: melting_temperature +using ClimaSeaIce.SeaIceThermodynamics: melting_temperature using ClimaOcean: stateindex From a2a37fd82d89d52d73424a69a13fe765aff2645c Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Sat, 10 Aug 2024 16:37:53 -0400 Subject: [PATCH 712/716] back to how it was --- 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 80d2b490..84d3e4b8 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -15,7 +15,7 @@ using Oceananigans.TimeSteppers: tick! using Oceananigans.Models: AbstractModel using Oceananigans.OutputReaders: FieldTimeSeries, GPUAdaptedFieldTimeSeries -using ClimaSeaIce.SeaIceThermodynamics: melting_temperature +using ClimaSeaIce: melting_temperature using ClimaOcean: stateindex From 86e851730af15a11c99e04f767a674beec56a37a Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 12 Aug 2024 21:37:52 -0400 Subject: [PATCH 713/716] fix precompilation issue --- src/DataWrangling/ecco_metadata.jl | 2 +- src/DataWrangling/ecco_restoring.jl | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index 3855bcac..ceb1d30c 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -1,6 +1,6 @@ using CFTime using Dates -import Dates: year, month, day + import Oceananigans.Fields: set! import Base diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index b214db30..fc617961 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -1,4 +1,3 @@ -using Oceananigans.Units using Oceananigans.Grids: node, on_architecture using Oceananigans.Fields: interpolate!, interpolate, location, instantiated_location using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices @@ -9,7 +8,7 @@ using Base using NCDatasets using JLD2 -using Dates +using Dates: Second using ClimaOcean: stateindex From 29defef6f359498bf05b3a1180b780012a90bd2f Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 13 Aug 2024 12:19:44 -0400 Subject: [PATCH 714/716] Update examples/near_global_ocean_simulation.jl Co-authored-by: Gregory L. Wagner --- examples/near_global_ocean_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 0360d707..9e2ceef2 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -65,7 +65,7 @@ bathymetry[bathymetry .>= 0] .= NaN fig = Figure(size = (1200, 400)) ax = Axis(fig[1, 1]) hm = heatmap!(ax, bathymetry, colormap = :deep, colorrange = (-6000, 0)) -cb = Colorbar(fig[0, 1], hm, label = "Bottom height [m]", vertical = false) +cb = Colorbar(fig[0, 1], hm, label = "Bottom height (m)", vertical = false) hidedecorations!(ax) save("bathymetry.png", fig) From 7056623191321bb0c0373860c462286257dd5a82 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 13 Aug 2024 12:23:52 -0400 Subject: [PATCH 715/716] fix examples then merge --- examples/generate_bathymetry.jl | 2 +- examples/generate_surface_fluxes.jl | 48 +++++++++++++++++++---------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/examples/generate_bathymetry.jl b/examples/generate_bathymetry.jl index 374eed39..fcf3652f 100644 --- a/examples/generate_bathymetry.jl +++ b/examples/generate_bathymetry.jl @@ -70,7 +70,7 @@ hm = heatmap!(ax, λ, φ, - interior(h_smooth, :, :, 1), nan_color=:white, color ax = Axis(fig[3, 1], title = "Bathymetry without connected regions}", xlabel = "Longitude", ylabel = "Latitude") hm = heatmap!(ax, λ, φ, - interior(h_no_connected_regions, :, :, 1), nan_color=:white, colormap = Reverse(:deep)) -cb = Colorbar(fig[1:3, 2], hm, height = Relative(3/4), label = "Depth [m]") +cb = Colorbar(fig[1:3, 2], hm, height = Relative(3/4), label = "Depth (m)") save("different_bottom_heights.png", fig) nothing #hide diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index a3e2fb27..078dbf58 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -92,11 +92,11 @@ coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) # Now that the surface fluxes are computed, we can extract and visualize them. # The turbulent fluxes are stored in `coupled_model.fluxes.turbulent`. # -# `Qs = coupled_model.fluxes.turbulent.fields.sensible_heat` : the sensible heat flux (in Wm⁻²) -# `Ql = coupled_model.fluxes.turbulent.fields.latent_heat` : the latent heat flux (in Wm⁻²) -# `τx = coupled_model.fluxes.turbulent.fields.x_momentum ` : the zonal wind stress (in Nm) -# `τy = coupled_model.fluxes.turbulent.fields.y_momentum ` : the meridional wind stress (in Nm) -# `Mv = coupled_model.fluxes.turbulent.fields.water_vapor` : evaporation (in kg m⁻²s⁻¹) +# Qs = coupled_model.fluxes.turbulent.fields.sensible_heat : the sensible heat flux (in Wm⁻²) +# Ql = coupled_model.fluxes.turbulent.fields.latent_heat : the latent heat flux (in Wm⁻²) +# τx = coupled_model.fluxes.turbulent.fields.x_momentum : the zonal wind stress (in Nm) +# τy = coupled_model.fluxes.turbulent.fields.y_momentum : the meridional wind stress (in Nm) +# Mv = coupled_model.fluxes.turbulent.fields.water_vapor : evaporation (in kg m⁻²s⁻¹) # # They are 2D fields (3D data structures with one point in the vertical). To extract the data, we use the # `interior` functionality from Oceananigans. @@ -108,31 +108,45 @@ Ql = interior(turbulent_fluxes.latent_heat, :, :, 1) τx = interior(turbulent_fluxes.x_momentum, :, :, 1) τy = interior(turbulent_fluxes.y_momentum, :, :, 1) Mv = interior(turbulent_fluxes.water_vapor, :, :, 1) -nothing - -fig = Figure(size = (1000, 2000)) +nothing #hide -ax = Axis(fig[1, 1], title = "Sensible heat flux [Wm⁻²]") -heatmap!(ax, Qs; colormap = :bwr) +fig = Figure(size = (800, 400)) +ax = Axis(fig[1, 1], title = "Sensible heat flux (Wm⁻²)") +hm = heatmap!(ax, Qs; colormap = :bwr) hidedecorations!(ax) +save("sensible_heat_flux.png", fig) +nothing #hide +# ![](sensible_heat_flux.png) -ax = Axis(fig[1, 2], title = "Latent heat flux [Wm⁻²]") +fig = Figure(size = (800, 400)) +ax = Axis(fig[1, 2], title = "Latent heat flux (Wm⁻²)") heatmap!(ax, Ql; colormap = :bwr) hidedecorations!(ax) +save("latent_heat_flux.png", fig) +nothing #hide +# ![](latent_heat_flux.png) -ax = Axis(fig[2, 1], title = "Zonal wind stress [Nm]") +fig = Figure(size = (800, 400)) +ax = Axis(fig[2, 1], title = "Zonal wind stress (Nm)") heatmap!(ax, τx; colormap = :bwr) hidedecorations!(ax) +save("zonal_wind_stress.png", fig) +nothing #hide +# ![](zonal_wind_stress.png) -ax = Axis(fig[2, 2], title = "Meridional wind stress [Nm]") +fig = Figure(size = (800, 400)) +ax = Axis(fig[2, 2], title = "Meridional wind stress (Nm)") heatmap!(ax, τy; colormap = :bwr) hidedecorations!(ax) +save("meridional_wind_stress.png", fig) +nothing #hide +# ![](meridional_wind_stress.png) -ax = Axis(fig[3, 1], title = "Evaporation [kg m⁻²s⁻¹]") +fig = Figure(size = (800, 400)) +ax = Axis(fig[3, 1], title = "Water vapor flux (kg m⁻²s⁻¹)") heatmap!(ax, Mv; colormap = :bwr) hidedecorations!(ax) - -save("turbulent_fluxes.png", fig) +save("water_vapor_flux.png", fig) nothing #hide +# ![](water_vapor_flux.png) -# ![](turbulent_fluxes.png) From 0c0ce6c45f9ad3c887d3f1fed3d5663d90a975d0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 13 Aug 2024 12:24:38 -0400 Subject: [PATCH 716/716] different unit of measure --- examples/near_global_ocean_simulation.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 9e2ceef2..12df9c99 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -253,7 +253,7 @@ end fig = Figure(size = (800, 400)) ax = Axis(fig[1, 1]) hm = heatmap!(ax, si, colorrange = (0, 0.5), colormap = :deep) -cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Surface speed [ms⁻¹]") +cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Surface speed (ms⁻¹)") hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_s.mp4", 1:Nt, framerate = 8) do i @@ -266,7 +266,7 @@ nothing #hide fig = Figure(size = (800, 400)) ax = Axis(fig[1, 1]) hm = heatmap!(ax, Ti, colorrange = (-1, 30), colormap = :magma) -cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Surface Temperature [Cᵒ]") +cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Surface Temperature (Cᵒ)") hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_T.mp4", 1:Nt, framerate = 8) do i @@ -279,7 +279,7 @@ nothing #hide fig = Figure(size = (800, 400)) ax = Axis(fig[1, 1]) hm = heatmap!(ax, ei, colorrange = (0, 1e-3), colormap = :solar) -cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Turbulent Kinetic Energy [m²s⁻²]") +cb = Colorbar(fig[0, 1], hm, vertical = false, label = "Turbulent Kinetic Energy (m²s⁻²)") hidedecorations!(ax) CairoMakie.record(fig, "near_global_ocean_surface_e.mp4", 1:Nt, framerate = 8) do i