From 6fd48b45a5f76d9ce3bdbd48b09452b84b56b564 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 29 Apr 2026 17:38:53 -0600 Subject: [PATCH 01/13] Add Radiation as a top-level EarthSystemModel component (issue #30) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wholesale refactor: radiation moves out of ComponentInterfaces and becomes its own model component, mirroring the land PR (#149) shape. - New src/Radiations/ module with PrescribedRadiation, SurfaceRadiationProperties, InterfaceRadiationFlux, the radiation kernels, and the moved albedo modules. - EarthSystemModel struct: type-param order {R, A, L, I, O, F, C, Arch}; radiation placed above atmosphere ("from the sun"). Default `radiation = nothing` means radiatively decoupled (no upwelling LW, no SW/LW absorption). - StateExchanger gains a radiation slot; component_interfaces takes radiation as a kwarg used only to construct the radiation exchanger. - Kernel split: _assemble_net_ocean_fluxes! and _assemble_net_sea_ice_fluxes! now do turbulent contributions only. New apply_air_sea_radiative_fluxes! and apply_air_sea_ice_radiative_fluxes! kernels (in Radiations/) add radiative contributions on top, dispatch on `coupled_model.radiation` type, and write to per-surface InterfaceRadiationFlux diagnostics. - SkinTemperature consumes radiation via the new `air_sea_interface_radiation_state` (and sea-ice variant) getter, which returns zeros when radiation is off — so SkinTemperature degrades cleanly to a turbulent-only flux balance. - PrescribedAtmosphere drops downwelling_radiation / TwoBandDownwellingRadiation; atmosphere exchanger state shrinks to (u, v, T, p, q, Jᶜ). - New JRA55PrescribedRadiation, ECCOPrescribedRadiation, OSPapaPrescribedRadiation data-wrangling constructors. - Reactant ext updated for the new type-param order. Tests, examples, and docs migrations to follow. Co-Authored-By: Claude Opus 4.7 (1M context) --- ext/NumericalEarthReactantExt.jl | 6 +- .../interpolate_atmospheric_state.jl | 24 +-- src/Atmospheres/prescribed_atmosphere.jl | 57 ++----- .../prescribed_atmosphere_regridder.jl | 14 +- src/DataWrangling/ECCO/ECCO.jl | 3 +- src/DataWrangling/ECCO/ECCO_atmosphere.jl | 16 +- src/DataWrangling/ECCO/ECCO_radiation.jl | 44 +++++ src/DataWrangling/JRA55/JRA55.jl | 13 +- .../JRA55/JRA55_prescribed_atmosphere.jl | 26 ++- .../JRA55/JRA55_prescribed_radiation.jl | 42 +++++ src/DataWrangling/OSPapa/OSPapa.jl | 4 +- .../OSPapa/OSPapa_prescribed_atmosphere.jl | 3 - .../OSPapa/OSPapa_prescribed_radiation.jl | 43 +++++ src/EarthSystemModels/EarthSystemModels.jl | 10 +- .../InterfaceComputations.jl | 27 ++- .../atmosphere_ocean_fluxes.jl | 47 ++--- .../atmosphere_sea_ice_fluxes.jl | 37 ++-- .../component_interfaces.jl | 58 ++----- .../compute_interface_state.jl | 8 +- .../InterfaceComputations/interface_states.jl | 25 +-- .../InterfaceComputations/radiation.jl | 114 ------------- .../InterfaceComputations/state_exchanger.jl | 26 +-- src/EarthSystemModels/earth_system_model.jl | 153 ++++++----------- .../time_step_earth_system_model.jl | 52 +++--- src/NumericalEarth.jl | 10 +- src/Oceans/assemble_net_ocean_fluxes.jl | 84 ++------- src/Radiations/Radiations.jl | 51 ++++++ .../air_sea_interface_radiation_state.jl | 28 +++ .../apply_air_sea_ice_radiative_fluxes.jl | 92 ++++++++++ .../apply_air_sea_radiative_fluxes.jl | 110 ++++++++++++ src/Radiations/interface_radiation_flux.jl | 34 ++++ src/Radiations/interpolate_radiation_state.jl | 69 ++++++++ .../latitude_dependent_albedo.jl | 0 src/Radiations/prescribed_radiation.jl | 160 ++++++++++++++++++ .../prescribed_radiation_regridder.jl | 51 ++++++ src/Radiations/radiation_kernels.jl | 24 +++ .../surface_radiation_properties.jl | 29 ++++ .../tabulated_albedo.jl | 0 src/SeaIces/assemble_net_sea_ice_fluxes.jl | 47 +---- 39 files changed, 1071 insertions(+), 570 deletions(-) create mode 100644 src/DataWrangling/ECCO/ECCO_radiation.jl create mode 100644 src/DataWrangling/JRA55/JRA55_prescribed_radiation.jl create mode 100644 src/DataWrangling/OSPapa/OSPapa_prescribed_radiation.jl delete mode 100644 src/EarthSystemModels/InterfaceComputations/radiation.jl create mode 100644 src/Radiations/Radiations.jl create mode 100644 src/Radiations/air_sea_interface_radiation_state.jl create mode 100644 src/Radiations/apply_air_sea_ice_radiative_fluxes.jl create mode 100644 src/Radiations/apply_air_sea_radiative_fluxes.jl create mode 100644 src/Radiations/interface_radiation_flux.jl create mode 100644 src/Radiations/interpolate_radiation_state.jl rename src/{EarthSystemModels/InterfaceComputations => Radiations}/latitude_dependent_albedo.jl (100%) create mode 100644 src/Radiations/prescribed_radiation.jl create mode 100644 src/Radiations/prescribed_radiation_regridder.jl create mode 100644 src/Radiations/radiation_kernels.jl create mode 100644 src/Radiations/surface_radiation_properties.jl rename src/{EarthSystemModels/InterfaceComputations => Radiations}/tabulated_albedo.jl (100%) diff --git a/ext/NumericalEarthReactantExt.jl b/ext/NumericalEarthReactantExt.jl index 3a5ccab54..93c3a6f06 100644 --- a/ext/NumericalEarthReactantExt.jl +++ b/ext/NumericalEarthReactantExt.jl @@ -13,9 +13,9 @@ const OceananigansReactantExt = Base.get_extension( Oceananigans, :OceananigansReactantExt ) -const ReactantOSIM{I, A, L, O, F, C} = Union{ - EarthSystemModel{I, A, L, O, F, C, <:ReactantState}, - EarthSystemModel{I, A, L, O, F, C, <:Distributed{ReactantState}}, +const ReactantOSIM{R, A, L, I, O, F, C} = Union{ + EarthSystemModel{R, A, L, I, O, F, C, <:ReactantState}, + EarthSystemModel{R, A, L, I, O, F, C, <:Distributed{ReactantState}}, } reconcile_state!(model::ReactantOSIM) = nothing diff --git a/src/Atmospheres/interpolate_atmospheric_state.jl b/src/Atmospheres/interpolate_atmospheric_state.jl index 56cf48727..2f0b365ec 100644 --- a/src/Atmospheres/interpolate_atmospheric_state.jl +++ b/src/Atmospheres/interpolate_atmospheric_state.jl @@ -27,9 +27,6 @@ function interpolate_state!(exchanger, grid, atmosphere::PrescribedAtmosphere, c atmosphere_tracers = (T = atmosphere.tracers.T.data, q = atmosphere.tracers.q.data) - ℐꜜˢʷ = atmosphere.downwelling_radiation.shortwave - ℐꜜˡʷ = atmosphere.downwelling_radiation.longwave - downwelling_radiation = (shortwave=ℐꜜˢʷ.data, longwave=ℐꜜˡʷ.data) freshwater_flux = map(ϕ -> ϕ.data, atmosphere.freshwater_flux) atmosphere_pressure = atmosphere.pressure.data @@ -44,14 +41,12 @@ function interpolate_state!(exchanger, grid, atmosphere::PrescribedAtmosphere, c # Simplify NamedTuple to reduce parameter space consumption. # See https://github.com/CliMA/NumericalEarth.jl/issues/116. - atmosphere_data = (u = atmosphere_fields.u.data, - v = atmosphere_fields.v.data, - T = atmosphere_fields.T.data, - p = atmosphere_fields.p.data, - q = atmosphere_fields.q.data, - ℐꜜˢʷ = atmosphere_fields.ℐꜜˢʷ.data, - ℐꜜˡʷ = atmosphere_fields.ℐꜜˡʷ.data, - Jᶜ = atmosphere_fields.Jᶜ.data) + atmosphere_data = (u = atmosphere_fields.u.data, + v = atmosphere_fields.v.data, + T = atmosphere_fields.T.data, + p = atmosphere_fields.p.data, + q = atmosphere_fields.q.data, + Jᶜ = atmosphere_fields.Jᶜ.data) kernel_parameters = interface_kernel_parameters(grid) @@ -72,7 +67,6 @@ function interpolate_state!(exchanger, grid, atmosphere::PrescribedAtmosphere, c atmosphere_velocities, atmosphere_tracers, atmosphere_pressure, - downwelling_radiation, freshwater_flux, atmosphere_backend, atmosphere_time_indexing) @@ -99,7 +93,6 @@ end atmos_velocities, atmos_tracers, atmos_pressure, - downwelling_radiation, prescribed_freshwater_flux, atmos_backend, atmos_time_indexing) @@ -121,9 +114,6 @@ end qᵃᵗ = interp_atmos_time_series(atmos_tracers.q, atmos_args...) pᵃᵗ = interp_atmos_time_series(atmos_pressure, atmos_args...) - ℐꜜˢʷ = interp_atmos_time_series(downwelling_radiation.shortwave, atmos_args...) - ℐꜜˡʷ = interp_atmos_time_series(downwelling_radiation.longwave, atmos_args...) - # Usually precipitation Mh = interp_atmos_time_series(prescribed_freshwater_flux, atmos_args...) @@ -138,8 +128,6 @@ end surface_atmos_state.T[i, j, 1] = Tᵃᵗ surface_atmos_state.p[i, j, 1] = pᵃᵗ surface_atmos_state.q[i, j, 1] = qᵃᵗ - surface_atmos_state.ℐꜜˢʷ[i, j, 1] = ℐꜜˢʷ - surface_atmos_state.ℐꜜˡʷ[i, j, 1] = ℐꜜˡʷ surface_atmos_state.Jᶜ[i, j, 1] = Mh end end diff --git a/src/Atmospheres/prescribed_atmosphere.jl b/src/Atmospheres/prescribed_atmosphere.jl index b753a506e..bbb5158ca 100644 --- a/src/Atmospheres/prescribed_atmosphere.jl +++ b/src/Atmospheres/prescribed_atmosphere.jl @@ -2,14 +2,13 @@ ##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic) ##### -mutable struct PrescribedAtmosphere{FT, G, T, U, P, C, F, R, TP, TI} +mutable struct PrescribedAtmosphere{FT, G, T, U, P, C, F, TP, TI} grid :: G clock :: Clock{T} velocities :: U pressure :: P tracers :: C freshwater_flux :: F - downwelling_radiation :: R thermodynamics_parameters :: TP times :: TI surface_layer_height :: FT @@ -43,12 +42,6 @@ function default_atmosphere_tracers(grid, times) return (T=Ta, q=qa) end -function default_downwelling_radiation(grid, times) - ℐꜜˡʷ = FieldTimeSeries{Center, Center, Nothing}(grid, times) - ℐꜜˢʷ = FieldTimeSeries{Center, Center, Nothing}(grid, times) - return TwoBandDownwellingRadiation(shortwave=ℐꜜˢʷ, longwave=ℐꜜˡʷ) -end - function default_freshwater_flux(grid, times) rain = FieldTimeSeries{Center, Center, Nothing}(grid, times) snow = FieldTimeSeries{Center, Center, Nothing}(grid, times) @@ -93,27 +86,29 @@ update_net_fluxes!(coupled_model, ::PrescribedAtmosphere) = nothing PrescribedAtmosphere(grid, times=[zero(grid)]; clock = Clock{Float64}(time = 0), surface_layer_height = 10, # meters - boundary_layer_height = 512 # meters, + boundary_layer_height = 512, # meters thermodynamics_parameters = AtmosphereThermodynamicsParameters(eltype(grid)), - velocities = default_atmosphere_velocities(grid, times), - tracers = default_atmosphere_tracers(grid, times), - pressure = default_atmosphere_pressure(grid, times), - freshwater_flux = default_freshwater_flux(grid, times), - downwelling_radiation = default_downwelling_radiation(grid, times)) + velocities = default_atmosphere_velocities(grid, times), + tracers = default_atmosphere_tracers(grid, times), + pressure = default_atmosphere_pressure(grid, times), + freshwater_flux = default_freshwater_flux(grid, times)) Return a representation of a prescribed time-evolving atmospheric state with data given at `times`. + +Note: downwelling shortwave / longwave radiation is now part of the +top-level `radiation` component (see `PrescribedRadiation`, +`JRA55PrescribedRadiation`). """ function PrescribedAtmosphere(grid, times=[zero(grid)]; clock = Clock{Float64}(time = 0), surface_layer_height = 10, boundary_layer_height = 512, thermodynamics_parameters = AtmosphereThermodynamicsParameters(eltype(grid)), - velocities = default_atmosphere_velocities(grid, times), - tracers = default_atmosphere_tracers(grid, times), - pressure = default_atmosphere_pressure(grid, times), - freshwater_flux = default_freshwater_flux(grid, times), - downwelling_radiation = default_downwelling_radiation(grid, times)) + velocities = default_atmosphere_velocities(grid, times), + tracers = default_atmosphere_tracers(grid, times), + pressure = default_atmosphere_pressure(grid, times), + freshwater_flux = default_freshwater_flux(grid, times)) FT = eltype(grid) if isnothing(thermodynamics_parameters) @@ -126,7 +121,6 @@ function PrescribedAtmosphere(grid, times=[zero(grid)]; pressure, tracers, freshwater_flux, - downwelling_radiation, thermodynamics_parameters, times, convert(FT, surface_layer_height), @@ -136,36 +130,17 @@ function PrescribedAtmosphere(grid, times=[zero(grid)]; return atmosphere end -struct TwoBandDownwellingRadiation{SW, LW} - shortwave :: SW - longwave :: LW -end - -""" - TwoBandDownwellingRadiation(shortwave=nothing, longwave=nothing) - -Return a two-band model for downwelling radiation (split into a shortwave band -and a longwave band) that passes through the atmosphere and arrives at the surface of ocean -or sea ice. -""" -TwoBandDownwellingRadiation(; shortwave=nothing, longwave=nothing) = - TwoBandDownwellingRadiation(shortwave, longwave) - -Adapt.adapt_structure(to, tsdr::TwoBandDownwellingRadiation) = - TwoBandDownwellingRadiation(adapt(to, tsdr.shortwave), - adapt(to, tsdr.longwave)) - ##### ##### Chekpointing ##### import Oceananigans: prognostic_state, restore_prognostic_state! -function prognostic_state(atmos::PrescribedAtmosphere) +function prognostic_state(atmos::PrescribedAtmosphere) return (; clock = prognostic_state(atmos.clock)) end -function restore_prognostic_state!(atmos::PrescribedAtmosphere, state) +function restore_prognostic_state!(atmos::PrescribedAtmosphere, state) restore_prognostic_state!(atmos.clock, state.clock) update_state!(atmos) return atmos diff --git a/src/Atmospheres/prescribed_atmosphere_regridder.jl b/src/Atmospheres/prescribed_atmosphere_regridder.jl index da93d1766..9ed5ebe1f 100644 --- a/src/Atmospheres/prescribed_atmosphere_regridder.jl +++ b/src/Atmospheres/prescribed_atmosphere_regridder.jl @@ -2,14 +2,12 @@ function ComponentExchanger(atmosphere::PrescribedAtmosphere, grid) regridder = atmosphere_regridder(atmosphere, grid) - state = (; u = Field{Center, Center, Nothing}(grid), - v = Field{Center, Center, Nothing}(grid), - T = Field{Center, Center, Nothing}(grid), - p = Field{Center, Center, Nothing}(grid), - q = Field{Center, Center, Nothing}(grid), - ℐꜜˢʷ = Field{Center, Center, Nothing}(grid), - ℐꜜˡʷ = Field{Center, Center, Nothing}(grid), - Jᶜ = Field{Center, Center, Nothing}(grid)) + state = (; u = Field{Center, Center, Nothing}(grid), + v = Field{Center, Center, Nothing}(grid), + T = Field{Center, Center, Nothing}(grid), + p = Field{Center, Center, Nothing}(grid), + q = Field{Center, Center, Nothing}(grid), + Jᶜ = Field{Center, Center, Nothing}(grid)) return ComponentExchanger(state, regridder) end diff --git a/src/DataWrangling/ECCO/ECCO.jl b/src/DataWrangling/ECCO/ECCO.jl index 576e81014..b85ecbf7a 100644 --- a/src/DataWrangling/ECCO/ECCO.jl +++ b/src/DataWrangling/ECCO/ECCO.jl @@ -2,7 +2,7 @@ module ECCO export ECCOMetadatum, ECCO_immersed_grid, adjusted_ECCO_tracers, initialize! export ECCO2Monthly, ECCO4Monthly, ECCO2Daily -export ECCOPrescribedAtmosphere +export ECCOPrescribedAtmosphere, ECCOPrescribedRadiation export ECCO2DarwinMonthly, ECCO4DarwinMonthly export retrieve_data @@ -370,6 +370,7 @@ end inpainted_metadata_path(metadata::ECCOMetadatum) = joinpath(metadata.dir, inpainted_metadata_filename(metadata)) include("ECCO_atmosphere.jl") +include("ECCO_radiation.jl") ##### ##### Column Field for ECCO datasets (which always download globally) diff --git a/src/DataWrangling/ECCO/ECCO_atmosphere.jl b/src/DataWrangling/ECCO/ECCO_atmosphere.jl index 3481c4e03..6f54ea1d4 100644 --- a/src/DataWrangling/ECCO/ECCO_atmosphere.jl +++ b/src/DataWrangling/ECCO/ECCO_atmosphere.jl @@ -1,6 +1,6 @@ using NumericalEarth.DataWrangling: DatasetBackend using Oceananigans.OutputReaders -using NumericalEarth.Atmospheres: PrescribedAtmosphere, TwoBandDownwellingRadiation +using NumericalEarth.Atmospheres: PrescribedAtmosphere """ ECCOPrescribedAtmosphere([architecture = CPU(), FT = Float32]; @@ -19,7 +19,10 @@ The atmospheric data will be held in `FieldTimeSeries` objects containing - air temperature and humidity: T, q - surface pressure: p - freshwater flux: rain -- downwelling radiation: ℐꜜˢʷ, ℐꜜˡʷ + +Note: downwelling shortwave / longwave radiation is now part of the +top-level `radiation` component. Use [`ECCOPrescribedRadiation`](@ref) to +load ECCO SW/LW into a `PrescribedRadiation`. """ function ECCOPrescribedAtmosphere(architecture = CPU(), FT = Float32; dataset = ECCO4Monthly(), @@ -36,8 +39,6 @@ function ECCOPrescribedAtmosphere(architecture = CPU(), FT = Float32; Ta_meta = Metadata(:air_temperature; dataset, start_date, end_date, dir) qa_meta = Metadata(:air_specific_humidity; dataset, start_date, end_date, dir) pa_meta = Metadata(:sea_level_pressure; dataset, start_date, end_date, dir) - ℐꜜˡʷ_meta = Metadata(:downwelling_longwave; dataset, start_date, end_date, dir) - ℐꜜˢʷ_meta = Metadata(:downwelling_shortwave; dataset, start_date, end_date, dir) Fr_meta = Metadata(:rain_freshwater_flux; dataset, start_date, end_date, dir) kw = (; time_indices_in_memory, time_indexing) @@ -48,10 +49,8 @@ function ECCOPrescribedAtmosphere(architecture = CPU(), FT = Float32; Ta = FieldTimeSeries(Ta_meta, architecture; kw...) qa = FieldTimeSeries(qa_meta, architecture; kw...) pa = FieldTimeSeries(pa_meta, architecture; kw...) - ℐꜜˡʷ = FieldTimeSeries(ℐꜜˡʷ_meta, architecture; kw...) - ℐꜜˢʷ = FieldTimeSeries(ℐꜜˢʷ_meta, architecture; kw...) Fr = FieldTimeSeries(Fr_meta, architecture; kw...) - + freshwater_flux = (; rain = Fr) times = ua.times @@ -61,8 +60,6 @@ function ECCOPrescribedAtmosphere(architecture = CPU(), FT = Float32; tracers = (T = Ta, q = qa) pressure = pa - downwelling_radiation = TwoBandDownwellingRadiation(shortwave=ℐꜜˢʷ, longwave=ℐꜜˡʷ) - FT = eltype(ua) surface_layer_height = convert(FT, surface_layer_height) @@ -70,7 +67,6 @@ function ECCOPrescribedAtmosphere(architecture = CPU(), FT = Float32; velocities, freshwater_flux, tracers, - downwelling_radiation, surface_layer_height, pressure) diff --git a/src/DataWrangling/ECCO/ECCO_radiation.jl b/src/DataWrangling/ECCO/ECCO_radiation.jl new file mode 100644 index 000000000..23cc78155 --- /dev/null +++ b/src/DataWrangling/ECCO/ECCO_radiation.jl @@ -0,0 +1,44 @@ +using NumericalEarth.Radiations: PrescribedRadiation, SurfaceRadiationProperties + +""" + ECCOPrescribedRadiation([architecture = CPU(), FT = Float32]; + dataset = ECCO4Monthly(), + start_date = first_date(dataset, :downwelling_shortwave), + end_date = last_date(dataset, :downwelling_shortwave), + dir = default_download_directory(dataset), + time_indices_in_memory = 10, + time_indexing = Cyclical(), + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), + stefan_boltzmann_constant = 5.67e-8, + other_kw...) + +Return a [`PrescribedRadiation`](@ref) backed by ECCO downwelling shortwave +and longwave fields. +""" +function ECCOPrescribedRadiation(architecture = CPU(), FT = Float32; + dataset = ECCO4Monthly(), + start_date = first_date(dataset, :downwelling_shortwave), + end_date = last_date(dataset, :downwelling_shortwave), + dir = default_download_directory(dataset), + time_indexing = Cyclical(), + time_indices_in_memory = 10, + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), + stefan_boltzmann_constant = 5.67e-8, + other_kw...) + + ℐꜜˢʷ_meta = Metadata(:downwelling_shortwave; dataset, start_date, end_date, dir) + ℐꜜˡʷ_meta = Metadata(:downwelling_longwave; dataset, start_date, end_date, dir) + + kw = (; time_indices_in_memory, time_indexing) + kw = merge(kw, other_kw) + + ℐꜜˢʷ = FieldTimeSeries(ℐꜜˢʷ_meta, architecture; kw...) + ℐꜜˡʷ = FieldTimeSeries(ℐꜜˡʷ_meta, architecture; kw...) + + return PrescribedRadiation(ℐꜜˢʷ, ℐꜜˡʷ; + ocean_surface, + sea_ice_surface, + stefan_boltzmann_constant) +end diff --git a/src/DataWrangling/JRA55/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl index 5751b9dcb..77eaabb07 100644 --- a/src/DataWrangling/JRA55/JRA55.jl +++ b/src/DataWrangling/JRA55/JRA55.jl @@ -1,6 +1,11 @@ module JRA55 -export JRA55FieldTimeSeries, JRA55PrescribedAtmosphere, JRA55PrescribedLand, RepeatYearJRA55, MultiYearJRA55 +export JRA55FieldTimeSeries, + JRA55PrescribedAtmosphere, + JRA55PrescribedLand, + JRA55PrescribedRadiation, + RepeatYearJRA55, + MultiYearJRA55 using Oceananigans using Oceananigans.Units @@ -14,9 +19,8 @@ using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBac using NumericalEarth -using NumericalEarth.Atmospheres: - PrescribedAtmosphere, - TwoBandDownwellingRadiation +using NumericalEarth.Atmospheres: PrescribedAtmosphere +using NumericalEarth.Radiations: PrescribedRadiation, SurfaceRadiationProperties using GPUArraysCore: @allowscalar @@ -40,5 +44,6 @@ include("JRA55_metadata.jl") include("JRA55_field_time_series.jl") include("JRA55_prescribed_atmosphere.jl") include("JRA55_prescribed_land.jl") +include("JRA55_prescribed_radiation.jl") end # module diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index ae395238d..373566c54 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -15,8 +15,11 @@ JRA55PrescribedAtmosphere(arch::Distributed, FT = Float32; kw...) = other_kw...) Return a [`PrescribedAtmosphere`](@ref) representing JRA55 reanalysis data. -The atmospheric data will be held in `JRA55FieldTimeSeries` objects containing. -For a detailed description of the keyword arguments, see the [`JRA55FieldTimeSeries`](@ref) constructor. +The atmospheric data will be held in `JRA55FieldTimeSeries` objects. + +Note: downwelling shortwave / longwave radiation is now part of the +top-level `radiation` component. Use [`JRA55PrescribedRadiation`](@ref) to +load JRA55 SW/LW into a `PrescribedRadiation`. """ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; dataset = RepeatYearJRA55(), @@ -30,15 +33,13 @@ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; kw = (; time_indexing, backend, start_date, end_date, dataset) kw = merge(kw, other_kw) - ua = JRA55FieldTimeSeries(:eastward_velocity, architecture, FT; kw...) - va = JRA55FieldTimeSeries(:northward_velocity, architecture, FT; kw...) - Ta = JRA55FieldTimeSeries(:temperature, architecture, FT; kw...) - qa = JRA55FieldTimeSeries(:specific_humidity, architecture, FT; kw...) - pa = JRA55FieldTimeSeries(:sea_level_pressure, architecture, FT; kw...) - Fra = JRA55FieldTimeSeries(:rain_freshwater_flux, architecture, FT; kw...) - Fsn = JRA55FieldTimeSeries(:snow_freshwater_flux, architecture, FT; kw...) - ℐꜜˡʷ = JRA55FieldTimeSeries(:downwelling_longwave_radiation, architecture, FT; kw...) - ℐꜜˢʷ = JRA55FieldTimeSeries(:downwelling_shortwave_radiation, architecture, FT; kw...) + ua = JRA55FieldTimeSeries(:eastward_velocity, architecture, FT; kw...) + va = JRA55FieldTimeSeries(:northward_velocity, architecture, FT; kw...) + Ta = JRA55FieldTimeSeries(:temperature, architecture, FT; kw...) + qa = JRA55FieldTimeSeries(:specific_humidity, architecture, FT; kw...) + pa = JRA55FieldTimeSeries(:sea_level_pressure, architecture, FT; kw...) + Fra = JRA55FieldTimeSeries(:rain_freshwater_flux, architecture, FT; kw...) + Fsn = JRA55FieldTimeSeries(:snow_freshwater_flux, architecture, FT; kw...) freshwater_flux = (rain = Fra, snow = Fsn) @@ -54,8 +55,6 @@ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; pressure = pa - downwelling_radiation = TwoBandDownwellingRadiation(shortwave=ℐꜜˢʷ, longwave=ℐꜜˡʷ) - FT = eltype(ua) surface_layer_height = convert(FT, surface_layer_height) @@ -63,7 +62,6 @@ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; velocities, freshwater_flux, tracers, - downwelling_radiation, surface_layer_height, pressure) diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_radiation.jl b/src/DataWrangling/JRA55/JRA55_prescribed_radiation.jl new file mode 100644 index 000000000..70a30f064 --- /dev/null +++ b/src/DataWrangling/JRA55/JRA55_prescribed_radiation.jl @@ -0,0 +1,42 @@ +JRA55PrescribedRadiation(arch::Distributed, FT = Float32; kw...) = + JRA55PrescribedRadiation(child_architecture(arch); kw...) + +""" + JRA55PrescribedRadiation([architecture = CPU(), FT = Float32]; + dataset = RepeatYearJRA55(), + start_date = first_date(dataset, :downwelling_shortwave_radiation), + end_date = last_date(dataset, :downwelling_shortwave_radiation), + backend = JRA55NetCDFBackend(10), + time_indexing = Cyclical(), + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), + stefan_boltzmann_constant = 5.67e-8, + other_kw...) + +Return a [`PrescribedRadiation`](@ref) backed by JRA55 downwelling shortwave +and longwave `JRA55FieldTimeSeries`. Surface radiative properties (albedo, +emissivity) for ocean and sea-ice surfaces default to standard values; pass +`ocean_surface = nothing` (or `sea_ice_surface = nothing`) to omit a surface. +""" +function JRA55PrescribedRadiation(architecture = CPU(), FT = Float32; + dataset = RepeatYearJRA55(), + start_date = first_date(dataset, :downwelling_shortwave_radiation), + end_date = last_date(dataset, :downwelling_shortwave_radiation), + backend = JRA55NetCDFBackend(10), + time_indexing = Cyclical(), + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), + stefan_boltzmann_constant = 5.67e-8, + other_kw...) + + kw = (; time_indexing, backend, start_date, end_date, dataset) + kw = merge(kw, other_kw) + + ℐꜜˢʷ = JRA55FieldTimeSeries(:downwelling_shortwave_radiation, architecture, FT; kw...) + ℐꜜˡʷ = JRA55FieldTimeSeries(:downwelling_longwave_radiation, architecture, FT; kw...) + + return PrescribedRadiation(ℐꜜˢʷ, ℐꜜˡʷ; + ocean_surface, + sea_ice_surface, + stefan_boltzmann_constant) +end diff --git a/src/DataWrangling/OSPapa/OSPapa.jl b/src/DataWrangling/OSPapa/OSPapa.jl index 0499ac0d5..056145019 100644 --- a/src/DataWrangling/OSPapa/OSPapa.jl +++ b/src/DataWrangling/OSPapa/OSPapa.jl @@ -1,6 +1,7 @@ module OSPapa export OSPapaPrescribedAtmosphere +export OSPapaPrescribedRadiation export os_papa_prescribed_fluxes export os_papa_prescribed_flux_boundary_conditions export OSPapaHourly @@ -14,7 +15,7 @@ using Downloads using Thermodynamics: q_vap_from_RH, Liquid using NumericalEarth.DataWrangling: download_progress -using NumericalEarth.Atmospheres: PrescribedAtmosphere, TwoBandDownwellingRadiation, AtmosphereThermodynamicsParameters +using NumericalEarth.Atmospheres: PrescribedAtmosphere, AtmosphereThermodynamicsParameters using NumericalEarth.Oceans: reference_density, heat_capacity using NumericalEarth.DataWrangling: @@ -80,6 +81,7 @@ end include("OSPapa_ocean_observations.jl") include("OSPapa_flux_observations.jl") include("OSPapa_prescribed_atmosphere.jl") +include("OSPapa_prescribed_radiation.jl") include("OSPapa_prescribed_fluxes.jl") end # module diff --git a/src/DataWrangling/OSPapa/OSPapa_prescribed_atmosphere.jl b/src/DataWrangling/OSPapa/OSPapa_prescribed_atmosphere.jl index c06d3f747..9990eee11 100644 --- a/src/DataWrangling/OSPapa/OSPapa_prescribed_atmosphere.jl +++ b/src/DataWrangling/OSPapa/OSPapa_prescribed_atmosphere.jl @@ -69,8 +69,6 @@ function OSPapaPrescribedAtmosphere(architecture = CPU(), FT = Float32; va = ospapa_fts(:northward_wind) Ta = ospapa_fts(:air_temperature) # K (Celsius conversion) Pa = ospapa_fts(:sea_level_pressure) # Pa (Millibar conversion) - swa = ospapa_fts(:shortwave_radiation) - lwa = ospapa_fts(:longwave_radiation) rain = ospapa_fts(:rain) # kg/m²/s (MillimetersPerHour conversion) thermo_params = AtmosphereThermodynamicsParameters(FT) @@ -82,7 +80,6 @@ function OSPapaPrescribedAtmosphere(architecture = CPU(), FT = Float32; tracers = (T=Ta, q=qa), pressure = Pa, freshwater_flux = (; rain), - downwelling_radiation = TwoBandDownwellingRadiation(shortwave=swa, longwave=lwa), thermodynamics_parameters = thermo_params, surface_layer_height = convert(FT, surface_layer_height)) end diff --git a/src/DataWrangling/OSPapa/OSPapa_prescribed_radiation.jl b/src/DataWrangling/OSPapa/OSPapa_prescribed_radiation.jl new file mode 100644 index 000000000..7b980e57e --- /dev/null +++ b/src/DataWrangling/OSPapa/OSPapa_prescribed_radiation.jl @@ -0,0 +1,43 @@ +using NumericalEarth.Radiations: PrescribedRadiation, SurfaceRadiationProperties + +""" + OSPapaPrescribedRadiation(architecture = CPU(), FT = Float32; + start_date = first_date(OSPapaHourly(), :shortwave_radiation), + end_date = last_date(OSPapaHourly(), :shortwave_radiation), + dir = download_OSPapa_cache, + max_gap_hours = 72, + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = nothing, + stefan_boltzmann_constant = 5.67e-8) + +Construct a `PrescribedRadiation` from Ocean Station Papa buoy SW/LW +observations on a single-column grid. +""" +function OSPapaPrescribedRadiation(architecture = CPU(), FT = Float32; + start_date = first_date(OSPapaHourly(), :shortwave_radiation), + end_date = last_date(OSPapaHourly(), :shortwave_radiation), + dir = download_OSPapa_cache, + max_gap_hours = 72, + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = nothing, + stefan_boltzmann_constant = 5.67e-8) + + mdkw = (; dataset = OSPapaHourly(), start_date, end_date, dir) + surface_grid = RectilinearGrid(architecture, FT; size=(), topology=(Flat, Flat, Flat)) + + function ospapa_fts(name) + md = Metadata(name; mdkw...) + download_dataset(md) + fts = FieldTimeSeries(md, surface_grid; time_indices_in_memory = length(md)) + fill_gaps!(fts; max_gap = max_gap_hours) + return fts + end + + swa = ospapa_fts(:shortwave_radiation) + lwa = ospapa_fts(:longwave_radiation) + + return PrescribedRadiation(swa, lwa; + ocean_surface, + sea_ice_surface, + stefan_boltzmann_constant) +end diff --git a/src/EarthSystemModels/EarthSystemModels.jl b/src/EarthSystemModels/EarthSystemModels.jl index 5f55ea644..80de85734 100644 --- a/src/EarthSystemModels/EarthSystemModels.jl +++ b/src/EarthSystemModels/EarthSystemModels.jl @@ -8,8 +8,6 @@ export SimilarityTheoryFluxes, CoefficientBasedFluxes, FreezingLimitedOceanTemperature, - Radiation, - LatitudeDependentAlbedo, SkinTemperature, BulkTemperature, compute_atmosphere_ocean_fluxes!, @@ -80,10 +78,10 @@ const NoOceanInterface = ComponentInterfaces{<:Nothing, <:AtmosphereInterface, const NoAtmosInterface = ComponentInterfaces{<:Nothing, <:Nothing, <:SeaIceOceanInterface} const NoInterface = ComponentInterfaces{<:Nothing, <:Nothing, <:Nothing} -const NoSeaIceInterfaceModel = EarthSystemModel{I, A, L, O, <:NoSeaIceInterface} where {I, A, L, O} -const NoAtmosInterfaceModel = EarthSystemModel{I, A, L, O, <:NoAtmosInterface} where {I, A, L, O} -const NoOceanInterfaceModel = EarthSystemModel{I, A, L, O, <:NoOceanInterface} where {I, A, L, O} -const NoInterfaceModel = EarthSystemModel{I, A, L, O, <:NoInterface} where {I, A, L, O} +const NoSeaIceInterfaceModel = EarthSystemModel{R, A, L, I, O, <:NoSeaIceInterface} where {R, A, L, I, O} +const NoAtmosInterfaceModel = EarthSystemModel{R, A, L, I, O, <:NoAtmosInterface} where {R, A, L, I, O} +const NoOceanInterfaceModel = EarthSystemModel{R, A, L, I, O, <:NoOceanInterface} where {R, A, L, I, O} +const NoInterfaceModel = EarthSystemModel{R, A, L, I, O, <:NoInterface} where {R, A, L, I, O} InterfaceComputations.compute_atmosphere_sea_ice_fluxes!(::NoSeaIceInterfaceModel) = nothing InterfaceComputations.compute_sea_ice_ocean_fluxes!(::NoSeaIceInterfaceModel) = nothing diff --git a/src/EarthSystemModels/InterfaceComputations/InterfaceComputations.jl b/src/EarthSystemModels/InterfaceComputations/InterfaceComputations.jl index ed93f8c9c..62fb8f15d 100644 --- a/src/EarthSystemModels/InterfaceComputations/InterfaceComputations.jl +++ b/src/EarthSystemModels/InterfaceComputations/InterfaceComputations.jl @@ -6,9 +6,7 @@ using Oceananigans.Utils: KernelParameters using Adapt export - Radiation, ComponentInterfaces, - LatitudeDependentAlbedo, SimilarityTheoryFluxes, MomentumRoughnessLength, ScalarRoughnessLength, @@ -41,6 +39,26 @@ import Oceananigans.Simulations: initialize! net_fluxes(::Nothing) = nothing +##### +##### Radiation hooks: declared here so the turbulent flux kernels can +##### resolve them at parse time. The `Radiations` module extends them +##### with concrete methods for `PrescribedRadiation`. +##### + +# `nothing` fallback (radiation is off). Concrete methods for +# `PrescribedRadiation` (and future radiation types) are added in `Radiations`. +@inline kernel_radiation_properties(::Nothing) = nothing + +@inline function air_sea_interface_radiation_state(::Nothing, ::Nothing, i, j, k, grid, time) + z = zero(eltype(grid)) + return (σ = z, α = z, ϵ = z, ℐꜜˢʷ = z, ℐꜜˡʷ = z) +end + +@inline function air_sea_ice_interface_radiation_state(::Nothing, ::Nothing, i, j, k, grid, time) + z = zero(eltype(grid)) + return (σ = z, α = z, ϵ = z, ℐꜜˢʷ = z, ℐꜜˡʷ = z) +end + ##### ##### Utilities ##### @@ -63,11 +81,6 @@ function interface_kernel_parameters(grid) return kernel_parameters end -# Radiation -include("radiation.jl") -include("latitude_dependent_albedo.jl") -include("tabulated_albedo.jl") - # Turbulent fluxes include("roughness_lengths.jl") include("interface_states.jl") diff --git a/src/EarthSystemModels/InterfaceComputations/atmosphere_ocean_fluxes.jl b/src/EarthSystemModels/InterfaceComputations/atmosphere_ocean_fluxes.jl index a32f36c01..f0ea3af2b 100644 --- a/src/EarthSystemModels/InterfaceComputations/atmosphere_ocean_fluxes.jl +++ b/src/EarthSystemModels/InterfaceComputations/atmosphere_ocean_fluxes.jl @@ -11,7 +11,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) # Simplify NamedTuple to reduce parameter space consumption. # See https://github.com/CliMA/NumericalEarth.jl/issues/116. - atmosphere_data = merge(atmosphere_fields, + atmosphere_data = merge(atmosphere_fields, (; h_bℓ = boundary_layer_height(coupled_model.atmosphere))) flux_formulation = coupled_model.interfaces.atmosphere_ocean_interface.flux_formulation @@ -23,6 +23,15 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) surface_layer_height = surface_layer_height(coupled_model.atmosphere), gravitational_acceleration = coupled_model.interfaces.properties.gravitational_acceleration) + # Radiation state for the interface solve (used by SkinTemperature). + # When `radiation === nothing` these are `nothing`s and the getter + # returns zero-valued radiative state, so SkinTemperature degrades to + # a turbulent-only flux balance. + radiation = coupled_model.radiation + radiation_kernel_props = kernel_radiation_properties(radiation) + radiation_exchanger = exchanger.radiation + radiation_state = isnothing(radiation_exchanger) ? nothing : radiation_exchanger.state + kernel_parameters = interface_kernel_parameters(grid) launch!(arch, grid, kernel_parameters, @@ -36,12 +45,14 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) atmosphere_data, interface_properties, atmosphere_properties, - ocean_properties) + ocean_properties, + radiation_kernel_props, + radiation_state) return nothing end -""" Compute turbulent fluxes between an atmosphere and a interface state using similarity theory """ +""" Compute turbulent fluxes between an atmosphere and an interface state using similarity theory """ @kernel function _compute_atmosphere_ocean_interface_state!(interface_fluxes, interface_temperature, grid, @@ -51,7 +62,9 @@ end atmosphere_state, interface_properties, atmosphere_properties, - ocean_properties) + ocean_properties, + radiation_kernel_props, + radiation_exchanger_state) i, j = @index(Global, NTuple) kᴺ = size(grid, 3) # index of the top ocean cell @@ -63,11 +76,8 @@ end Tᵃᵗ = atmosphere_state.T[i, j, 1] pᵃᵗ = atmosphere_state.p[i, j, 1] qᵃᵗ = atmosphere_state.q[i, j, 1] - ℐꜜˢʷ = atmosphere_state.ℐꜜˢʷ[i, j, 1] - ℐꜜˡʷ = atmosphere_state.ℐꜜˡʷ[i, j, 1] - # Extract state variables at cell centers - # Ocean state + # Ocean state at cell centers uᵒᶜ = ℑxᶜᵃᵃ(i, j, kᴺ, grid, interior_state.u) vᵒᶜ = ℑyᵃᶜᵃ(i, j, kᴺ, grid, interior_state.v) Tᵒᶜ = interior_state.T[i, j, kᴺ] @@ -76,8 +86,6 @@ end end # Build thermodynamic and dynamic states in the atmosphere and interface. - # Notation: - # ⋅ 𝒰 ≡ "dynamic" state vector (thermodynamics + reference height + velocity) ℂᵃᵗ = atmosphere_properties.thermodynamics_parameters zᵃᵗ = atmosphere_properties.surface_layer_height # elevation of atmos variables relative to interface @@ -90,7 +98,12 @@ end h_bℓ = atmosphere_state.h_bℓ) local_interior_state = (u=uᵒᶜ, v=vᵒᶜ, T=Tᵒᶜ, S=Sᵒᶜ) - downwelling_radiation = (; ℐꜜˢʷ, ℐꜜˡʷ) + + # Local radiative state at this cell. Returns zero-valued state when + # radiation is off. + radiation_state = air_sea_interface_radiation_state(radiation_kernel_props, + radiation_exchanger_state, + i, j, kᴺ, grid, time) # Estimate initial interface state FT = typeof(Tᵒᶜ) @@ -106,16 +119,6 @@ end needs_to_converge = stop_criteria isa ConvergenceStopCriteria not_water = inactive_node(i, j, kᴺ, grid, Center(), Center(), Center()) - # Compute local radiative properties and rebuild the interface properties - α = stateindex(interface_properties.radiation.α, i, j, kᴺ, grid, time, (Center, Center, Center), ℐꜜˢʷ) - ϵ = stateindex(interface_properties.radiation.ϵ, i, j, kᴺ, grid, time, (Center, Center, Center)) - σ = interface_properties.radiation.σ - - interface_properties = InterfaceProperties((; α, ϵ, σ), - interface_properties.specific_humidity_formulation, - interface_properties.temperature_formulation, - interface_properties.velocity_formulation) - if needs_to_converge && not_water interface_state = zero_interface_state(FT) else @@ -123,7 +126,7 @@ end initial_interface_state, local_atmosphere_state, local_interior_state, - downwelling_radiation, + radiation_state, interface_properties, atmosphere_properties, ocean_properties) diff --git a/src/EarthSystemModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl b/src/EarthSystemModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl index 1292d6311..420b6ca82 100644 --- a/src/EarthSystemModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl +++ b/src/EarthSystemModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl @@ -14,9 +14,7 @@ function compute_atmosphere_sea_ice_fluxes!(coupled_model) atmosphere_fields = exchanger.atmosphere.state - # Simplify NamedTuple to reduce parameter space consumption. - # See https://github.com/CliMA/NumericalEarth.jl/issues/116. - atmosphere_data = merge(atmosphere_fields, + atmosphere_data = merge(atmosphere_fields, (; h_bℓ = boundary_layer_height(coupled_model.atmosphere))) flux_formulation = coupled_model.interfaces.atmosphere_sea_ice_interface.flux_formulation @@ -30,6 +28,11 @@ function compute_atmosphere_sea_ice_fluxes!(coupled_model) surface_layer_height = surface_layer_height(coupled_model.atmosphere), gravitational_acceleration = coupled_model.interfaces.properties.gravitational_acceleration) + radiation = coupled_model.radiation + radiation_kernel_props = kernel_radiation_properties(radiation) + radiation_exchanger = exchanger.radiation + radiation_state = isnothing(radiation_exchanger) ? nothing : radiation_exchanger.state + kernel_parameters = interface_kernel_parameters(grid) launch!(arch, grid, kernel_parameters, @@ -44,12 +47,14 @@ function compute_atmosphere_sea_ice_fluxes!(coupled_model) interface_properties, atmosphere_properties, sea_ice_properties, - ocean_properties) + ocean_properties, + radiation_kernel_props, + radiation_state) return nothing end -""" Compute turbulent fluxes between an atmosphere and a interface state using similarity theory """ +""" Compute turbulent fluxes between an atmosphere and an interface state using similarity theory """ @kernel function _compute_atmosphere_sea_ice_interface_state!(interface_fluxes, interface_temperature, grid, @@ -60,11 +65,14 @@ end interface_properties, atmosphere_properties, sea_ice_properties, - ocean_properties) + ocean_properties, + radiation_kernel_props, + radiation_exchanger_state) i, j = @index(Global, NTuple) kᴺ = size(grid, 3) # index of the top ocean cell FT = eltype(grid) + time = Time(clock.time) @inbounds begin uᵃᵗ = atmosphere_state.u[i, j, 1] @@ -72,10 +80,7 @@ end Tᵃᵗ = atmosphere_state.T[i, j, 1] pᵃᵗ = atmosphere_state.p[i, j, 1] qᵃᵗ = atmosphere_state.q[i, j, 1] - ℐꜜˢʷ = atmosphere_state.ℐꜜˢʷ[i, j, 1] - ℐꜜˡʷ = atmosphere_state.ℐꜜˡʷ[i, j, 1] - # Extract state variables at cell centers # Ocean properties below sea ice Tᵒᶜ = interior_state.Tᵒᶜ[i, j, kᴺ] Tᵒᶜ = convert_to_kelvin(ocean_properties.temperature_units, Tᵒᶜ) @@ -91,9 +96,6 @@ end Tₛ = convert_to_kelvin(sea_ice_properties.temperature_units, Tₛ) end - # Build thermodynamic and dynamic states in the atmosphere and interface. - # Notation: - # ⋅ 𝒰 ≡ "dynamic" state vector (thermodynamics + reference height + velocity) ℂᵃᵗ = atmosphere_properties.thermodynamics_parameters zᵃᵗ = atmosphere_properties.surface_layer_height # elevation of atmos variables relative to interface @@ -105,9 +107,14 @@ end q = qᵃᵗ, h_bℓ = atmosphere_state.h_bℓ) - downwelling_radiation = (; ℐꜜˢʷ, ℐꜜˡʷ) local_interior_state = (u=uˢⁱ, v=vˢⁱ, T=Tᵒᶜ, S=Sᵒᶜ, h=hˢⁱ, hc=hc) - + + # Local radiative state at this cell. Returns zero-valued state when + # radiation is off. + radiation_state = air_sea_ice_interface_radiation_state(radiation_kernel_props, + radiation_exchanger_state, + i, j, kᴺ, grid, time) + # Estimate initial interface state (FP32 compatible) u★ = convert(FT, 1f-4) @@ -131,7 +138,7 @@ end initial_interface_state, local_atmosphere_state, local_interior_state, - downwelling_radiation, + radiation_state, interface_properties, atmosphere_properties, sea_ice_properties) diff --git a/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl b/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl index 65d6adbe8..f04b33de7 100644 --- a/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl +++ b/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl @@ -70,22 +70,18 @@ struct AtmosphereOceanFluxes{F} friction_velocity :: F temperature_scale :: F water_vapor_scale :: F - upwelling_longwave :: F - downwelling_longwave :: F - downwelling_shortwave :: F end function AtmosphereOceanFluxes(grid) F = Field{Center, Center, Nothing} return AtmosphereOceanFluxes(F(grid), F(grid), F(grid), - F(grid), F(grid), F(grid), F(grid), F(grid), F(grid), F(grid), F(grid)) end -AtmosphereOceanFluxes(::Nothing) = AtmosphereOceanFluxes(ntuple(_ -> ZeroField(), 11)...) +AtmosphereOceanFluxes(::Nothing) = AtmosphereOceanFluxes(ntuple(_ -> ZeroField(), 8)...) -Adapt.adapt_structure(to, fluxes::AtmosphereOceanFluxes) = +Adapt.adapt_structure(to, fluxes::AtmosphereOceanFluxes) = AtmosphereOceanFluxes(Adapt.adapt(to, fluxes.latent_heat), Adapt.adapt(to, fluxes.sensible_heat), Adapt.adapt(to, fluxes.water_vapor), @@ -93,12 +89,9 @@ Adapt.adapt_structure(to, fluxes::AtmosphereOceanFluxes) = Adapt.adapt(to, fluxes.y_momentum), Adapt.adapt(to, fluxes.friction_velocity), Adapt.adapt(to, fluxes.temperature_scale), - Adapt.adapt(to, fluxes.water_vapor_scale), - Adapt.adapt(to, fluxes.upwelling_longwave), - Adapt.adapt(to, fluxes.downwelling_longwave), - Adapt.adapt(to, fluxes.downwelling_shortwave)) + Adapt.adapt(to, fluxes.water_vapor_scale)) -on_architecture(arch, fluxes::AtmosphereOceanFluxes) = +on_architecture(arch, fluxes::AtmosphereOceanFluxes) = AtmosphereOceanFluxes(on_architecture(arch, fluxes.latent_heat), on_architecture(arch, fluxes.sensible_heat), on_architecture(arch, fluxes.water_vapor), @@ -106,10 +99,7 @@ on_architecture(arch, fluxes::AtmosphereOceanFluxes) = on_architecture(arch, fluxes.y_momentum), on_architecture(arch, fluxes.friction_velocity), on_architecture(arch, fluxes.temperature_scale), - on_architecture(arch, fluxes.water_vapor_scale), - on_architecture(arch, fluxes.upwelling_longwave), - on_architecture(arch, fluxes.downwelling_longwave), - on_architecture(arch, fluxes.downwelling_shortwave)) + on_architecture(arch, fluxes.water_vapor_scale)) struct AtmosphereSeaIceFluxes{F} latent_heat :: F @@ -174,7 +164,8 @@ on_architecture(arch, fluxes::SeaIceOceanFluxes) = # ZeroFluxes is returned by computed_fluxes(::Nothing) for absent interfaces. # It contains the union of all flux field names across interface types. struct ZeroFluxes{Z} - # Atmosphere-ocean and atmosphere-sea-ice flux fields + # Atmosphere-ocean and atmosphere-sea-ice flux fields (turbulent only; + # radiative diagnostic fields live on the radiation component) latent_heat :: Z sensible_heat :: Z water_vapor :: Z @@ -183,16 +174,13 @@ struct ZeroFluxes{Z} friction_velocity :: Z temperature_scale :: Z water_vapor_scale :: Z - upwelling_longwave :: Z - downwelling_longwave :: Z - downwelling_shortwave :: Z # Sea ice-ocean flux fields interface_heat :: Z frazil_heat :: Z salt :: Z end -ZeroFluxes() = ZeroFluxes(ntuple(_ -> ZeroField(), 14)...) +ZeroFluxes() = ZeroFluxes(ntuple(_ -> ZeroField(), 11)...) @inline computed_fluxes(::Nothing) = ZeroFluxes() @@ -224,10 +212,9 @@ atmosphere_ocean_interface(grid, ::Nothing, ocean, args...) = nothing atmosphere_ocean_interface(grid, ::Nothing, ::Nothing, args...) = nothing atmosphere_ocean_interface(grid, atmosphere, ::Nothing, args...) = nothing -function atmosphere_ocean_interface(grid, +function atmosphere_ocean_interface(grid, atmosphere, ocean, - radiation, ao_flux_formulation, temperature_formulation, velocity_formulation, @@ -235,13 +222,7 @@ function atmosphere_ocean_interface(grid, ao_fluxes = AtmosphereOceanFluxes(grid) - σ = radiation.stefan_boltzmann_constant - αₐₒ = radiation.reflection.ocean - ϵₐₒ = radiation.emission.ocean - radiation = (σ=σ, α=αₐₒ, ϵ=ϵₐₒ) - - ao_properties = InterfaceProperties(radiation, - specific_humidity_formulation, + ao_properties = InterfaceProperties(specific_humidity_formulation, temperature_formulation, velocity_formulation) @@ -258,26 +239,19 @@ atmosphere_sea_ice_interface(grid, atmos, ::Nothing, args...) = nothing atmosphere_sea_ice_interface(grid, ::Nothing, sea_ice, args...) = nothing atmosphere_sea_ice_interface(grid, ::Nothing, ::Nothing, args...) = nothing -function atmosphere_sea_ice_interface(grid, +function atmosphere_sea_ice_interface(grid, atmosphere, sea_ice, - radiation, ai_flux_formulation, temperature_formulation, velocity_formulation) fluxes = AtmosphereSeaIceFluxes(grid) - σ = radiation.stefan_boltzmann_constant - αₐᵢ = radiation.reflection.sea_ice - ϵₐᵢ = radiation.emission.sea_ice - radiation = (σ=σ, α=αₐᵢ, ϵ=ϵₐᵢ) - phase = AtmosphericThermodynamics.Ice() specific_humidity_formulation = ImpureSaturationSpecificHumidity(phase) - properties = InterfaceProperties(radiation, - specific_humidity_formulation, + properties = InterfaceProperties(specific_humidity_formulation, temperature_formulation, velocity_formulation) @@ -377,9 +351,9 @@ Keyword Arguments - `gravitational_acceleration`: gravitational acceleration. Default: `default_gravitational_acceleration`. """ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; + radiation = nothing, land = nothing, exchange_grid = exchange_grid(atmosphere, ocean, sea_ice), - radiation = Radiation(), freshwater_density = default_freshwater_density, atmosphere_ocean_fluxes = SimilarityTheoryFluxes(eltype(exchange_grid)), atmosphere_sea_ice_fluxes = atmosphere_sea_ice_similarity_theory(eltype(exchange_grid)), @@ -429,7 +403,6 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; ao_interface = atmosphere_ocean_interface(exchange_grid, atmosphere, ocean, - radiation, atmosphere_ocean_fluxes, atmosphere_ocean_interface_temperature, atmosphere_ocean_velocity_difference, @@ -437,10 +410,9 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; io_interface = sea_ice_ocean_interface(exchange_grid, sea_ice, ocean, sea_ice_ocean_heat_flux) - ai_interface = atmosphere_sea_ice_interface(exchange_grid, + ai_interface = atmosphere_sea_ice_interface(exchange_grid, atmosphere, sea_ice, - radiation, atmosphere_sea_ice_fluxes, atmosphere_sea_ice_interface_temperature, atmosphere_sea_ice_velocity_difference) @@ -449,7 +421,7 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; sea_ice = net_fluxes(sea_ice), atmosphere = net_fluxes(atmosphere)) - exchanger = StateExchanger(exchange_grid, atmosphere, land, ocean, sea_ice) + exchanger = StateExchanger(exchange_grid, radiation, atmosphere, land, ocean, sea_ice) properties = (; gravitational_acceleration) diff --git a/src/EarthSystemModels/InterfaceComputations/compute_interface_state.jl b/src/EarthSystemModels/InterfaceComputations/compute_interface_state.jl index e52b5a53a..b8703a79d 100644 --- a/src/EarthSystemModels/InterfaceComputations/compute_interface_state.jl +++ b/src/EarthSystemModels/InterfaceComputations/compute_interface_state.jl @@ -32,7 +32,7 @@ end initial_interface_state, atmosphere_state, interior_state, - downwelling_radiation, + radiation_state, interface_properties, atmosphere_properties, interior_properties) @@ -47,7 +47,7 @@ end Ψₛ⁻ = Ψₛⁿ Ψₛⁿ = iterate_interface_state(flux_formulation, Ψₛ⁻, Ψₐ, Ψᵢ, - downwelling_radiation, + radiation_state, interface_properties, atmosphere_properties, interior_properties) @@ -70,7 +70,7 @@ and interior properties `ℙₛ`, `ℙₐ`, and `ℙᵢ`. approximate_interface_state, atmosphere_state, interior_state, - downwelling_radiation, + radiation_state, interface_properties, atmosphere_properties, interior_properties) @@ -79,7 +79,7 @@ and interior properties `ℙₛ`, `ℙₐ`, and `ℙᵢ`. approximate_interface_state, atmosphere_state, interior_state, - downwelling_radiation, + radiation_state, interface_properties, atmosphere_properties, interior_properties) diff --git a/src/EarthSystemModels/InterfaceComputations/interface_states.jl b/src/EarthSystemModels/InterfaceComputations/interface_states.jl index 4f1ae6c2d..255f00bbb 100644 --- a/src/EarthSystemModels/InterfaceComputations/interface_states.jl +++ b/src/EarthSystemModels/InterfaceComputations/interface_states.jl @@ -9,8 +9,7 @@ using Thermodynamics: Liquid, Ice ##### Interface properties ##### -struct InterfaceProperties{R, Q, T, V} - radiation :: R +struct InterfaceProperties{Q, T, V} specific_humidity_formulation :: Q temperature_formulation :: T velocity_formulation :: V @@ -313,7 +312,7 @@ end interface_state, atmosphere_state, interior_state, - downwelling_radiation, + radiation_state, interface_properties, atmosphere_properties, interior_properties) @@ -329,16 +328,18 @@ end #ℰv = 0 #AtmosphericThermodynamics.latent_heat_vapor(ℂᵃᵗ, Tᵃᵗ) ℒⁱ = AtmosphericThermodynamics.latent_heat_sublim(ℂᵃᵗ, Tᵃᵗ) - # upwelling radiation is calculated explicitly + # upwelling radiation is calculated explicitly. radiation_state is + # produced by `air_sea_interface_radiation_state` (or its sea-ice + # variant) and contains zero-valued σ/α/ϵ/SW/LW when radiation is off. Tₛ⁻ = interface_state.T # approximate interface temperature from previous iteration - σ = interface_properties.radiation.σ - ϵ = interface_properties.radiation.ϵ - α = interface_properties.radiation.α - - ℐꜜˢʷ = downwelling_radiation.ℐꜜˢʷ - ℐꜜˡʷ = downwelling_radiation.ℐꜜˡʷ - ℐꜛˡʷ = emitted_longwave_radiation(Tₛ⁻, σ, ϵ) - Qd = net_absorbed_interface_radiation(ℐꜜˢʷ, ℐꜜˡʷ, α, ϵ) + σ = radiation_state.σ + ϵ = radiation_state.ϵ + α = radiation_state.α + + ℐꜜˢʷ = radiation_state.ℐꜜˢʷ + ℐꜜˡʷ = radiation_state.ℐꜜˡʷ + ℐꜛˡʷ = σ * ϵ * Tₛ⁻^4 + Qd = - (1 - α) * ℐꜜˢʷ - ϵ * ℐꜜˡʷ u★ = interface_state.u★ θ★ = interface_state.θ★ diff --git a/src/EarthSystemModels/InterfaceComputations/radiation.jl b/src/EarthSystemModels/InterfaceComputations/radiation.jl deleted file mode 100644 index 0e60d56af..000000000 --- a/src/EarthSystemModels/InterfaceComputations/radiation.jl +++ /dev/null @@ -1,114 +0,0 @@ -using Oceananigans.Grids: φnode - -@inline hack_cosd(φ) = cos(π * φ / 180) -@inline hack_sind(φ) = sin(π * φ / 180) - -struct Radiation{FT, E, R} - emission :: E - reflection :: 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)) - -""" - Radiation([arch = CPU(), FT=Float64]; - ocean_emissivity = 0.97, - sea_ice_emissivity = 1.0, - ocean_albedo = 0.05, - 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: `0.05`. -- `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=Oceananigans.defaults.FloatType; - ocean_emissivity = 0.97, - sea_ice_emissivity = 1.0, - ocean_albedo = 0.05, - sea_ice_albedo = 0.7, - stefan_boltzmann_constant = 5.67e-8) - - ocean_emissivity isa Number && (ocean_emissivity = convert(FT, ocean_emissivity)) - sea_ice_emissivity isa Number && (sea_ice_emissivity = convert(FT, sea_ice_emissivity)) - ocean_albedo isa Number && (ocean_albedo = convert(FT, ocean_albedo)) - sea_ice_albedo isa Number && (sea_ice_albedo = convert(FT, sea_ice_albedo)) - - emission = SurfaceProperties(ocean_emissivity, sea_ice_emissivity) - reflection = SurfaceProperties(ocean_albedo, sea_ice_albedo) - - return Radiation(emission, - reflection, - convert(FT, stefan_boltzmann_constant)) -end - -Base.summary(r::Radiation{FT}) where FT = "Radiation{$FT}" - -function Base.show(io::IO, r::Radiation) - σ = r.stefan_boltzmann_constant - - print(io, summary(r), ":", '\n') - print(io, "├── stefan_boltzmann_constant: ", prettysummary(σ), '\n') - print(io, "├── emission: ", summary(r.emission), '\n') - print(io, "│ ├── ocean: ", prettysummary(r.emission.ocean), '\n') - print(io, "│ └── sea_ice: ", prettysummary(r.emission.ocean), '\n') - print(io, "└── reflection: ", summary(r.reflection), '\n') - print(io, " ├── ocean: ", prettysummary(r.reflection.ocean), '\n') - print(io, " └── sea_ice: ", prettysummary(r.reflection.sea_ice)) -end - -struct SurfaceProperties{O, I} - ocean :: O - sea_ice :: I -end - -Adapt.adapt_structure(to, s :: SurfaceProperties) = - SurfaceProperties(Adapt.adapt(to, s.ocean), - Adapt.adapt(to, s.sea_ice)) - -Base.summary(properties::SurfaceProperties) = "SurfaceProperties" - -function Base.show(io::IO, properties::SurfaceProperties) - print(io, "SurfaceProperties:", '\n') - print(io, "├── ocean: ", summary(properties.ocean), '\n') - print(io, "└── sea_ice: ", summary(properties.sea_ice)) -end - -const CCC = (Center, Center, Center) - -@inline function emitted_longwave_radiation(i, j, k, grid, time, T, σ, ϵ) - ϵi = stateindex(ϵ, i, j, k, grid, time, CCC) - return σ * ϵi * T^4 -end - -# Split the individual bands -@inline function absorbed_longwave_radiation(i, j, k, grid, time, ϵ, ℐꜜˡʷ) - ϵi = stateindex(ϵ, i, j, k, grid, time, CCC) - return - ϵi * ℐꜜˡʷ -end - -@inline function transmitted_shortwave_radiation(i, j, k, grid, time, α, ℐꜜˢʷ) - αi = stateindex(α, i, j, k, grid, time, CCC, ℐꜜˢʷ) - return - (1 - αi) * ℐꜜˢʷ -end - -# Inside the solver we lose both spatial and temporal information, but the -# radiative properties have already been computed correctly -@inline net_absorbed_interface_radiation(ℐꜜˢʷ, ℐꜜˡʷ, α, ϵ) = - (1 - α) * ℐꜜˢʷ - ϵ * ℐꜜˡʷ -@inline emitted_longwave_radiation(T, σ, ϵ) = σ * ϵ * T^4 diff --git a/src/EarthSystemModels/InterfaceComputations/state_exchanger.jl b/src/EarthSystemModels/InterfaceComputations/state_exchanger.jl index fadf03585..85830cb4d 100644 --- a/src/EarthSystemModels/InterfaceComputations/state_exchanger.jl +++ b/src/EarthSystemModels/InterfaceComputations/state_exchanger.jl @@ -2,8 +2,9 @@ ComponentExchanger(component, exchange_grid) Holds a regridder and a buffer of `state` fields used to bring data from a -component (atmosphere, land, ocean, sea ice) onto a shared `exchange_grid`, -where atmosphere--ocean and atmosphere--sea-ice fluxes are computed. +component (radiation, atmosphere, land, ocean, sea ice) onto a shared +`exchange_grid`, where atmosphere--ocean and atmosphere--sea-ice fluxes are +computed. """ struct ComponentExchanger{S, EX} state :: S @@ -11,35 +12,39 @@ struct ComponentExchanger{S, EX} end """ - StateExchanger(grid, atmosphere, land, ocean, sea_ice) + StateExchanger(grid, radiation, atmosphere, land, ocean, sea_ice) Container for one `ComponentExchanger` per component. The `grid` is the shared exchange grid onto which each component's state is regridded each time step. """ -struct StateExchanger{G, A, L, O, S} +struct StateExchanger{G, R, A, L, O, S} grid :: G + radiation :: R atmosphere :: A land :: L ocean :: O sea_ice :: S - function StateExchanger(grid, atmosphere, land, ocean, sea_ice) + function StateExchanger(grid, radiation, atmosphere, land, ocean, sea_ice) + radiation_exchanger = ComponentExchanger(radiation, grid) atmosphere_exchanger = ComponentExchanger(atmosphere, grid) land_exchanger = ComponentExchanger(land, grid) ocean_exchanger = ComponentExchanger(ocean, grid) sea_ice_exchanger = ComponentExchanger(sea_ice, grid) G = typeof(grid) + R = typeof(radiation_exchanger) A = typeof(atmosphere_exchanger) L = typeof(land_exchanger) O = typeof(ocean_exchanger) S = typeof(sea_ice_exchanger) - return new{G, A, L, O, S}(grid, - atmosphere_exchanger, - land_exchanger, - ocean_exchanger, - sea_ice_exchanger) + return new{G, R, A, L, O, S}(grid, + radiation_exchanger, + atmosphere_exchanger, + land_exchanger, + ocean_exchanger, + sea_ice_exchanger) end end @@ -47,6 +52,7 @@ end ComponentExchanger(::Nothing, grid) = nothing function initialize!(exchanger::StateExchanger, model) + initialize!(exchanger.radiation, exchanger.grid, model.radiation) initialize!(exchanger.atmosphere, exchanger.grid, model.atmosphere) initialize!(exchanger.land, exchanger.grid, model.land) initialize!(exchanger.ocean, exchanger.grid, model.ocean) diff --git a/src/EarthSystemModels/earth_system_model.jl b/src/EarthSystemModels/earth_system_model.jl index 113cce6b5..834aeb206 100644 --- a/src/EarthSystemModels/earth_system_model.jl +++ b/src/EarthSystemModels/earth_system_model.jl @@ -4,9 +4,10 @@ using Oceananigans: SeawaterBuoyancy using ClimaSeaIce.SeaIceThermodynamics: melting_temperature using KernelAbstractions: @kernel, @index -mutable struct EarthSystemModel{I, A, L, O, F, C, Arch} <: AbstractModel{Nothing, Arch} +mutable struct EarthSystemModel{R, A, L, I, O, F, C, Arch} <: AbstractModel{Nothing, Arch} architecture :: Arch clock :: C + radiation :: R atmosphere :: A land :: L sea_ice :: I @@ -38,6 +39,7 @@ function Base.show(io::IO, cm::ESM) ocean_summary = summary(cm.ocean) end + print(io, "├── radiation: ", summary(cm.radiation), "\n") print(io, "├── atmosphere: ", summary(cm.atmosphere), "\n") print(io, "├── land: ", summary(cm.land), "\n") print(io, "├── sea_ice: ", sea_ice_summary, "\n") @@ -80,9 +82,16 @@ reference_density(unsupported) = heat_capacity(unsupported) = throw(ArgumentError("Cannot deduce the heat capacity from $(typeof(unsupported))")) +# Hook called after `interfaces` is constructed and the exchange grid is known. +# Concrete radiation types (e.g. `PrescribedRadiation`) overload this to +# allocate `interface_fluxes` per-surface on the exchange grid. +allocate_interface_fluxes!(::Any, exchange_grid, surfaces) = nothing +allocate_interface_fluxes!(::Nothing, exchange_grid, surfaces) = nothing + """ EarthSystemModel(atmosphere, ocean, sea_ice; - radiation = Radiation(), + radiation = nothing, + land = nothing, clock = Clock{Float64}(time=0), ocean_reference_density = reference_density(ocean), ocean_heat_capacity = heat_capacity(ocean), @@ -109,7 +118,10 @@ Arguments Keyword Arguments ================== -- `radiation`: Radiation component used to compute surface fluxes at the bottom of the atmosphere. +- `radiation`: Radiation component. Defaults to `nothing` (radiatively decoupled surface). + Pass a `PrescribedRadiation` (e.g. `JRA55PrescribedRadiation(...)`) to enable radiative + forcing. +- `land`: Land component. Defaults to `nothing`. - `clock`: Keeps track of time. - `ocean_reference_density`: Reference density for the ocean. Defaults to value from ocean model. - `ocean_heat_capacity`: Heat capacity for the ocean. Defaults to value from ocean model. @@ -117,53 +129,10 @@ Keyword Arguments - `sea_ice_heat_capacity`: Heat capacity for sea ice. Defaults to value from sea ice model. - `interfaces`: Component interfaces for coupling. Defaults to `nothing` and will be constructed automatically. To customize the sea ice-ocean heat flux formulation, create interfaces manually using `ComponentInterfaces`. - -Stability Functions -==================== - -The model uses similarity theory for turbulent fluxes between components. You can customize the stability functions -by creating a new [`SimilarityTheoryFluxes`](@ref) object with your desired stability functions. For example: - -```jldoctest earth_system_model -using NumericalEarth -using Oceananigans - -grid = RectilinearGrid(size=10, z=(-100, 0), topology=(Flat, Flat, Bounded)) -ocean = ocean_simulation(grid, timestepper = :QuasiAdamsBashforth2) - -# Three choices for stability function: -# "No stability function", which also apply to neutral boundary layers -stability_functions = nothing - -# Atmosphere-sea ice specific stability functions -stability_functions = NumericalEarth.EarthSystemModels.atmosphere_sea_ice_stability_functions(Float64) - -# Edson et al. (2013) stability functions -stability_functions = NumericalEarth.EarthSystemModels.atmosphere_ocean_stability_functions(Float64) - -atmosphere_ocean_fluxes = SimilarityTheoryFluxes(; stability_functions) -interfaces = NumericalEarth.EarthSystemModels.ComponentInterfaces(nothing, ocean; atmosphere_ocean_fluxes) -model = OceanOnlyModel(ocean; interfaces) - -# output -EarthSystemModel{CPU}(time = 0 seconds, iteration = 0) -├── atmosphere: Nothing -├── land: Nothing -├── sea_ice: FreezingLimitedOceanTemperature{ClimaSeaIce.SeaIceThermodynamics.LinearLiquidus{Float64}} -├── ocean: HydrostaticFreeSurfaceModel{CPU, RectilinearGrid}(time = 0 seconds, iteration = 0) -└── interfaces: ComponentInterfaces -``` - -The available stability function options include: -- `atmosphere_ocean_stability_functions`: Based on [Edson et al. (2013)](@cite edson2013exchange) -- `atmosphere_sea_ice_stability_functions`: Specifically designed for atmosphere-sea ice interactions -- `nothing`: No stability functions will be used -- Custom stability functions can be created by defining functions of the "stability parameter" - (the flux Richardson number), `ζ`. """ function EarthSystemModel(atmosphere, ocean, sea_ice; + radiation = nothing, land = nothing, - radiation = Radiation(), clock = Clock{Float64}(time=0), ocean_reference_density = reference_density(ocean), ocean_heat_capacity = heat_capacity(ocean), @@ -193,23 +162,28 @@ function EarthSystemModel(atmosphere, ocean, sea_ice; # Contains information about flux contributions: bulk formula, prescribed fluxes, etc. if isnothing(interfaces) && !(isnothing(atmosphere) && isnothing(sea_ice)) interfaces = ComponentInterfaces(atmosphere, ocean, sea_ice; + radiation, land, ocean_reference_density, ocean_heat_capacity, sea_ice_reference_density, - sea_ice_heat_capacity, - radiation) + sea_ice_heat_capacity) end arch = architecture(interfaces.exchanger.grid) + # Allocate per-surface InterfaceRadiationFlux on the exchange grid. + surfaces = present_surfaces(ocean, sea_ice) + allocate_interface_fluxes!(radiation, interfaces.exchanger.grid, surfaces) + earth_system_model = EarthSystemModel(arch, - clock, - atmosphere, - land, - sea_ice, - ocean, - interfaces) + clock, + radiation, + atmosphere, + land, + sea_ice, + ocean, + interfaces) # Make sure the initial temperature of the ocean # is not below freezing and above melting near the surface @@ -219,8 +193,17 @@ function EarthSystemModel(atmosphere, ocean, sea_ice; return earth_system_model end +# Determine which surfaces are present in the model — used to allocate +# per-surface diagnostic radiation flux buffers. +function present_surfaces(ocean, sea_ice) + surfaces = Symbol[] + isnothing(ocean) || push!(surfaces, :ocean) + isnothing(sea_ice) || push!(surfaces, :sea_ice) + return Tuple(surfaces) +end + """ - OceanOnlyModel(ocean; atmosphere=nothing, radiation=Radiation(), kw...) + OceanOnlyModel(ocean; atmosphere=nothing, radiation=nothing, kw...) Construct an ocean-only model without a sea ice component. This is a convenience constructor for [`EarthSystemModel`](@ref) that sets `sea_ice` @@ -229,58 +212,19 @@ to `FreezingLimitedOceanTemperature` (a simple freezing limiter that does not ev The `atmosphere` keyword can be used to specify a prescribed atmospheric forcing (e.g., `JRA55PrescribedAtmosphere`). All other keyword arguments are forwarded to `EarthSystemModel`. - -```jldoctest -using NumericalEarth -using Oceananigans - -grid = RectilinearGrid(size=10, z=(-100, 0), topology=(Flat, Flat, Bounded)) -ocean = ocean_simulation(grid, timestepper = :QuasiAdamsBashforth2) -model = OceanOnlyModel(ocean) - -# output -EarthSystemModel{CPU}(time = 0 seconds, iteration = 0) -├── atmosphere: Nothing -├── land: Nothing -├── sea_ice: FreezingLimitedOceanTemperature{ClimaSeaIce.SeaIceThermodynamics.LinearLiquidus{Float64}} -├── ocean: HydrostaticFreeSurfaceModel{CPU, RectilinearGrid}(time = 0 seconds, iteration = 0) -└── interfaces: ComponentInterfaces -``` """ -OceanOnlyModel(ocean; atmosphere=nothing, land=nothing, kw...) = - EarthSystemModel(atmosphere, ocean, default_sea_ice(); land, kw...) +OceanOnlyModel(ocean; atmosphere=nothing, land=nothing, radiation=nothing, kw...) = + EarthSystemModel(atmosphere, ocean, default_sea_ice(); radiation, land, kw...) """ - OceanSeaIceModel(ocean, sea_ice; atmosphere=nothing, radiation=Radiation(), kw...) + OceanSeaIceModel(ocean, sea_ice; atmosphere=nothing, radiation=nothing, kw...) Construct a coupled ocean--sea ice model. This is a convenience constructor for [`EarthSystemModel`](@ref) with an explicit sea ice component and an optional prescribed atmosphere. - -The `atmosphere` keyword can be used to specify a prescribed atmospheric forcing -(e.g., `JRA55PrescribedAtmosphere`). All other keyword arguments are forwarded -to `EarthSystemModel`. - -```jldoctest -using NumericalEarth -using Oceananigans - -grid = RectilinearGrid(size=10, z=(-100, 0), topology=(Flat, Flat, Bounded)) -ocean = ocean_simulation(grid, timestepper = :QuasiAdamsBashforth2) -sea_ice = FreezingLimitedOceanTemperature() -model = OceanSeaIceModel(ocean, sea_ice) - -# output -EarthSystemModel{CPU}(time = 0 seconds, iteration = 0) -├── atmosphere: Nothing -├── land: Nothing -├── sea_ice: FreezingLimitedOceanTemperature{ClimaSeaIce.SeaIceThermodynamics.LinearLiquidus{Float64}} -├── ocean: HydrostaticFreeSurfaceModel{CPU, RectilinearGrid}(time = 0 seconds, iteration = 0) -└── interfaces: ComponentInterfaces -``` """ -OceanSeaIceModel(ocean, sea_ice; atmosphere=nothing, land=nothing, kw...) = - EarthSystemModel(atmosphere, ocean, sea_ice; land, kw...) +OceanSeaIceModel(ocean, sea_ice; atmosphere=nothing, land=nothing, radiation=nothing, kw...) = + EarthSystemModel(atmosphere, ocean, sea_ice; radiation, land, kw...) """ AtmosphereOceanModel(atmosphere, ocean; kw...) @@ -289,8 +233,8 @@ Construct a coupled atmosphere--ocean model. Convenience constructor for [`EarthSystemModel`](@ref) with an atmosphere and ocean but no sea ice. All keyword arguments are forwarded to `EarthSystemModel`. """ -AtmosphereOceanModel(atmosphere, ocean; land=nothing, kw...) = - EarthSystemModel(atmosphere, ocean, nothing; land, kw...) +AtmosphereOceanModel(atmosphere, ocean; land=nothing, radiation=nothing, kw...) = + EarthSystemModel(atmosphere, ocean, nothing; radiation, land, kw...) time(coupled_model::EarthSystemModel) = coupled_model.clock.time @@ -334,6 +278,7 @@ above_freezing_ocean_temperature!(ocean, grid, ::Nothing) = nothing function prognostic_state(osm::EarthSystemModel) return (clock = prognostic_state(osm.clock), + radiation = prognostic_state(osm.radiation), ocean = prognostic_state(osm.ocean), atmosphere = prognostic_state(osm.atmosphere), land = prognostic_state(osm.land), @@ -343,6 +288,10 @@ end function restore_prognostic_state!(osm::EarthSystemModel, state) restore_prognostic_state!(osm.clock, state.clock) + # Backwards-compatible: older checkpoints may not have a `radiation` entry + if hasproperty(state, :radiation) + restore_prognostic_state!(osm.radiation, state.radiation) + end restore_prognostic_state!(osm.ocean, state.ocean) restore_prognostic_state!(osm.atmosphere, state.atmosphere) restore_prognostic_state!(osm.land, state.land) diff --git a/src/EarthSystemModels/time_step_earth_system_model.jl b/src/EarthSystemModels/time_step_earth_system_model.jl index bf041418e..acd174ae8 100644 --- a/src/EarthSystemModels/time_step_earth_system_model.jl +++ b/src/EarthSystemModels/time_step_earth_system_model.jl @@ -7,26 +7,26 @@ using ClimaSeaIce: SeaIceModel, SeaIceThermodynamics using Oceananigans.Grids: φnode using Printf +# Hooks called from `update_state!` to apply radiative contributions on top of +# turbulent fluxes. Concrete radiation types overload these (no-op when +# `coupled_model.radiation === nothing`). +apply_air_sea_radiative_fluxes!(::Any) = nothing +apply_air_sea_ice_radiative_fluxes!(::Any) = nothing + function time_step!(coupled_model::EarthSystemModel, Δt; callbacks=[]) maybe_prepare_first_time_step!(coupled_model, callbacks) - - ocean = coupled_model.ocean - sea_ice = coupled_model.sea_ice - atmosphere = coupled_model.atmosphere - land = coupled_model.land - - # Eventually, split out into OceanOnlyModel - !isnothing(sea_ice) && time_step!(sea_ice, Δt) - # TODO after ice time-step: - # - Adjust ocean heat flux if the ice completely melts? - !isnothing(ocean) && time_step!(ocean, Δt) + radiation = coupled_model.radiation + atmosphere = coupled_model.atmosphere + land = coupled_model.land + sea_ice = coupled_model.sea_ice + ocean = coupled_model.ocean - # Time step the atmosphere + !isnothing(radiation) && time_step!(radiation, Δt) !isnothing(atmosphere) && time_step!(atmosphere, Δt) - - # Time step land - !isnothing(land) && time_step!(land, Δt) + !isnothing(land) && time_step!(land, Δt) + !isnothing(sea_ice) && time_step!(sea_ice, Δt) + !isnothing(ocean) && time_step!(ocean, Δt) # TODO: # - Store fractional ice-free / ice-covered _time_ for more @@ -39,31 +39,37 @@ end function update_state!(coupled_model::EarthSystemModel, callbacks=[]) - # The four components - ocean = coupled_model.ocean - sea_ice = coupled_model.sea_ice + radiation = coupled_model.radiation atmosphere = coupled_model.atmosphere land = coupled_model.land + sea_ice = coupled_model.sea_ice + ocean = coupled_model.ocean exchanger = coupled_model.interfaces.exchanger grid = exchanger.grid - # This function needs to be specialized to allow different component models + # Phase 1: bring all component states onto the exchange grid + interpolate_state!(exchanger.radiation, grid, radiation, coupled_model) interpolate_state!(exchanger.atmosphere, grid, atmosphere, coupled_model) interpolate_state!(exchanger.land, grid, land, coupled_model) - interpolate_state!(exchanger.ocean, grid, ocean, coupled_model) interpolate_state!(exchanger.sea_ice, grid, sea_ice, coupled_model) + interpolate_state!(exchanger.ocean, grid, ocean, coupled_model) - # Compute interface states + # Phase 2: compute interface turbulent fluxes compute_atmosphere_ocean_fluxes!(coupled_model) compute_atmosphere_sea_ice_fluxes!(coupled_model) compute_sea_ice_ocean_fluxes!(coupled_model) - # This function needs to be specialized to allow different component models + # Phase 3: assemble net component fluxes (turbulent only) + update_net_fluxes!(coupled_model, radiation) update_net_fluxes!(coupled_model, atmosphere) update_net_fluxes!(coupled_model, land) - update_net_fluxes!(coupled_model, ocean) update_net_fluxes!(coupled_model, sea_ice) + update_net_fluxes!(coupled_model, ocean) + + # Phase 4: add radiative contributions on top + apply_air_sea_radiative_fluxes!(coupled_model) + apply_air_sea_ice_radiative_fluxes!(coupled_model) return nothing end diff --git a/src/NumericalEarth.jl b/src/NumericalEarth.jl index fc5731492..0e8c5873e 100644 --- a/src/NumericalEarth.jl +++ b/src/NumericalEarth.jl @@ -15,8 +15,14 @@ export SlabOcean, default_sea_ice, FreezingLimitedOceanTemperature, - Radiation, + PrescribedRadiation, + SurfaceRadiationProperties, + InterfaceRadiationFlux, LatitudeDependentAlbedo, + TabulatedAlbedo, + JRA55PrescribedRadiation, + ECCOPrescribedRadiation, + OSPapaPrescribedRadiation, SimilarityTheoryFluxes, CoefficientBasedFluxes, MomentumRoughnessLength, @@ -111,6 +117,7 @@ include("EarthSystemModels/EarthSystemModels.jl") include("Oceans/Oceans.jl") include("Atmospheres/Atmospheres.jl") include("Lands/Lands.jl") +include("Radiations/Radiations.jl") include("SeaIces/SeaIces.jl") include("InitialConditions/InitialConditions.jl") include("DataWrangling/DataWrangling.jl") @@ -124,6 +131,7 @@ using .InitialConditions using .EarthSystemModels using .Atmospheres using .Lands +using .Radiations using .Oceans using .SeaIces using .Diagnostics diff --git a/src/Oceans/assemble_net_ocean_fluxes.jl b/src/Oceans/assemble_net_ocean_fluxes.jl index 5fe6f81fe..6c364a434 100644 --- a/src/Oceans/assemble_net_ocean_fluxes.jl +++ b/src/Oceans/assemble_net_ocean_fluxes.jl @@ -6,16 +6,13 @@ using NumericalEarth.EarthSystemModels: EarthSystemModel, NoOceanInterfaceModel, using NumericalEarth.EarthSystemModels.InterfaceComputations: interface_kernel_parameters, computed_fluxes, - sea_ice_concentration, - convert_to_kelvin, - emitted_longwave_radiation, - absorbed_longwave_radiation, - transmitted_shortwave_radiation + sea_ice_concentration @inline τᶜᶜᶜ(i, j, k, grid, ρᵒᶜ⁻¹, ℵ, ρτᶜᶜᶜ) = @inbounds ρᵒᶜ⁻¹ * (1 - ℵ[i, j, k]) * ρτᶜᶜᶜ[i, j, k] ##### -##### Generic flux assembler +##### Generic flux assembler — turbulent + sea-ice contributions only. +##### Radiative contributions are added later by `apply_air_sea_radiative_fluxes!`. ##### # Fallback for an ocean-only model (it has no interfaces!) @@ -24,7 +21,6 @@ update_net_fluxes!(coupled_model::Union{NoOceanInterfaceModel, NoInterfaceModel} update_net_fluxes!(coupled_model, ocean::Simulation{<:HydrostaticFreeSurfaceModel}) = update_net_ocean_fluxes!(coupled_model, ocean, ocean.model.grid) -# A generic ocean flux assembler for a coupled model with both an atmosphere and sea ice function update_net_ocean_fluxes!(coupled_model, ocean_model, grid) sea_ice = coupled_model.sea_ice arch = architecture(grid) @@ -34,13 +30,7 @@ function update_net_ocean_fluxes!(coupled_model, ocean_model, grid) atmos_ocean_fluxes = computed_fluxes(coupled_model.interfaces.atmosphere_ocean_interface) sea_ice_ocean_fluxes = computed_fluxes(coupled_model.interfaces.sea_ice_ocean_interface) - # Simplify NamedTuple to reduce parameter space consumption. - # See https://github.com/CliMA/NumericalEarth.jl/issues/116. atmosphere_fields = coupled_model.interfaces.exchanger.atmosphere.state - - downwelling_radiation = (ℐꜜˢʷ = atmosphere_fields.ℐꜜˢʷ.data, - ℐꜜˡʷ = atmosphere_fields.ℐꜜˡʷ.data) - freshwater_flux = atmosphere_fields.Jᶜ.data # Extract land freshwater flux if land component is present @@ -49,27 +39,19 @@ function update_net_ocean_fluxes!(coupled_model, ocean_model, grid) ice_concentration = sea_ice_concentration(sea_ice) ocean_surface_salinity = EarthSystemModels.ocean_surface_salinity(ocean_model) - atmos_ocean_properties = coupled_model.interfaces.atmosphere_ocean_interface.properties ocean_properties = coupled_model.interfaces.ocean_properties - ocean_surface_temperature = coupled_model.interfaces.atmosphere_ocean_interface.temperature - penetrating_radiation = get_radiative_forcing(ocean_model) - launch!(arch, grid, :xy, _assemble_net_ocean_fluxes!, net_ocean_fluxes, - penetrating_radiation, grid, clock, atmos_ocean_fluxes, sea_ice_ocean_fluxes, ocean_surface_salinity, - ocean_surface_temperature, ice_concentration, - downwelling_radiation, freshwater_flux, land_freshwater_flux, - atmos_ocean_properties, ocean_properties) return nothing @@ -79,23 +61,18 @@ end Base.@propagate_inbounds get_land_freshwater_flux(i, j, flux) = flux[i, j, 1] @kernel function _assemble_net_ocean_fluxes!(net_ocean_fluxes, - penetrating_radiation, grid, clock, atmos_ocean_fluxes, sea_ice_ocean_fluxes, ocean_surface_salinity, - ocean_surface_temperature, sea_ice_concentration, - downwelling_radiation, freshwater_flux, land_freshwater_flux, - atmos_ocean_properties, ocean_properties) i, j = @index(Global, NTuple) kᴺ = size(grid, 3) - time = Time(clock.time) ρτˣᵃᵒ = atmos_ocean_fluxes.x_momentum # atmosphere - ocean zonal momentum flux ρτʸᵃᵒ = atmos_ocean_fluxes.y_momentum # atmosphere - ocean meridional momentum flux ρτˣⁱᵒ = sea_ice_ocean_fluxes.x_momentum # sea_ice - ocean zonal momentum flux @@ -104,54 +81,24 @@ Base.@propagate_inbounds get_land_freshwater_flux(i, j, flux) = flux[i, j, 1] @inbounds begin ℵᵢ = sea_ice_concentration[i, j, 1] Sᵒᶜ = ocean_surface_salinity[i, j, 1] - Tₛ = ocean_surface_temperature[i, j, 1] - Tₛ = convert_to_kelvin(ocean_properties.temperature_units, Tₛ) - - Jᶜ = freshwater_flux[i, j, 1] + get_land_freshwater_flux(i, j, land_freshwater_flux) # Prescribed freshwater flux (atmos + land) - ℐꜜˢʷ = downwelling_radiation.ℐꜜˢʷ[i, j, 1] # Downwelling shortwave radiation - ℐꜜˡʷ = downwelling_radiation.ℐꜜˡʷ[i, j, 1] # Downwelling longwave radiation - 𝒬ᵀ = atmos_ocean_fluxes.sensible_heat[i, j, 1] # sensible or "conductive" heat flux - 𝒬ᵛ = atmos_ocean_fluxes.latent_heat[i, j, 1] # latent heat flux - Jᵛ = atmos_ocean_fluxes.water_vapor[i, j, 1] # mass flux of water vapor - end - - # Compute radiation fluxes (radiation is multiplied by the fraction of ocean, 1 - sea ice concentration) - σ = atmos_ocean_properties.radiation.σ - α = atmos_ocean_properties.radiation.α - ϵ = atmos_ocean_properties.radiation.ϵ - ℐꜛˡʷ = emitted_longwave_radiation(i, j, kᴺ, grid, time, Tₛ, σ, ϵ) - ℐₐˡʷ = absorbed_longwave_radiation(i, j, kᴺ, grid, time, ϵ, ℐꜜˡʷ) - - # Compute the interior + surface absorbed shortwave radiation - ℐₜˢʷ = transmitted_shortwave_radiation(i, j, kᴺ, grid, time, α, ℐꜜˢʷ) - ℐₐˡʷ *= (1 - ℵᵢ) - ℐₜˢʷ *= (1 - ℵᵢ) - - Qss = shortwave_radiative_forcing(i, j, grid, penetrating_radiation, ℐₜˢʷ, ocean_properties) - - # Compute the total heat flux - ΣQao = (ℐꜛˡʷ + 𝒬ᵀ + 𝒬ᵛ) * (1 - ℵᵢ) + ℐₐˡʷ + Qss - - @inbounds begin - # Write radiative components of the heat flux for diagnostic purposes - atmos_ocean_fluxes.upwelling_longwave[i, j, 1] = ℐꜛˡʷ - atmos_ocean_fluxes.downwelling_longwave[i, j, 1] = - ℐₐˡʷ - atmos_ocean_fluxes.downwelling_shortwave[i, j, 1] = - ℐₜˢʷ + Jᶜ = freshwater_flux[i, j, 1] + get_land_freshwater_flux(i, j, land_freshwater_flux) + 𝒬ᵀ = atmos_ocean_fluxes.sensible_heat[i, j, 1] + 𝒬ᵛ = atmos_ocean_fluxes.latent_heat[i, j, 1] + Jᵛ = atmos_ocean_fluxes.water_vapor[i, j, 1] end - # Convert from a mass flux to a volume flux (aka velocity) - # by dividing with the ocean reference density. - # Also switch the sign, for some reason we are given freshwater flux as positive down. + # Turbulent contributions to surface heat flux (radiation added later) + ΣQao = (𝒬ᵀ + 𝒬ᵛ) * (1 - ℵᵢ) + + # Convert mass flux to volume flux; sign-flip (prescribed flux is positive down) ρᵒᶜ⁻¹ = 1 / ocean_properties.reference_density ΣFao = - Jᶜ * ρᵒᶜ⁻¹ - # Add the contribution from the turbulent water vapor flux, which has - # a different sign convention as the prescribed water mass fluxes (positive upwards) + # Add turbulent water vapor flux (positive upward sign convention) Jᵛᵒᶜ = Jᵛ * ρᵒᶜ⁻¹ ΣFao += Jᵛᵒᶜ - # Compute fluxes for u, v, T, and S from momentum, heat, and freshwater fluxes τˣ = net_ocean_fluxes.u τʸ = net_ocean_fluxes.v Jᵀ = net_ocean_fluxes.T @@ -166,7 +113,7 @@ Base.@propagate_inbounds get_land_freshwater_flux(i, j, flux) = flux[i, j, 1] Jᵀao = ΣQao * ρᵒᶜ⁻¹ * cᵒᶜ⁻¹ Jᵀio = 𝒬ⁱⁿᵗ * ρᵒᶜ⁻¹ * cᵒᶜ⁻¹ - # salinity flux > 0 extracts salinity from the ocean --- the opposite of a water vapor flux + # salinity flux > 0 extracts salinity (opposite of water vapor flux sign) Jˢao = - Sᵒᶜ * ΣFao τˣᵃᵒ = ℑxᶠᵃᵃ(i, j, 1, grid, τᶜᶜᶜ, ρᵒᶜ⁻¹, ℵ, ρτˣᵃᵒ) @@ -174,12 +121,11 @@ Base.@propagate_inbounds get_land_freshwater_flux(i, j, flux) = flux[i, j, 1] τˣⁱᵒ = ρτˣⁱᵒ[i, j, 1] * ρᵒᶜ⁻¹ * ℑxᶠᵃᵃ(i, j, 1, grid, ℵ) τʸⁱᵒ = ρτʸⁱᵒ[i, j, 1] * ρᵒᶜ⁻¹ * ℑyᵃᶠᵃ(i, j, 1, grid, ℵ) - # Stresses τˣ[i, j, 1] = ifelse(inactive, zero(grid), τˣᵃᵒ + τˣⁱᵒ) τʸ[i, j, 1] = ifelse(inactive, zero(grid), τʸᵃᵒ + τʸⁱᵒ) - # Tracer fluxes - Jᵀ[i, j, 1] = ifelse(inactive, zero(grid), Jᵀao + Jᵀio) # Jᵀao is already multiplied by the sea ice concentration + # Tracer fluxes — radiative contributions added later by apply_air_sea_radiative_fluxes! + Jᵀ[i, j, 1] = ifelse(inactive, zero(grid), Jᵀao + Jᵀio) Jˢ[i, j, 1] = ifelse(inactive, zero(grid), (1 - ℵᵢ) * Jˢao + Jˢio) end end diff --git a/src/Radiations/Radiations.jl b/src/Radiations/Radiations.jl new file mode 100644 index 000000000..bee972c39 --- /dev/null +++ b/src/Radiations/Radiations.jl @@ -0,0 +1,51 @@ +module Radiations + +export PrescribedRadiation, + SurfaceRadiationProperties, + InterfaceRadiationFlux, + LatitudeDependentAlbedo, + TabulatedAlbedo + +using Oceananigans +using Oceananigans.Architectures: architecture +using Oceananigans.Fields: Center, Face, Field, ZeroField, FractionalIndices, instantiate, interpolator +using Oceananigans.Grids: grid_name, prettysummary, ηnode, _node, topology, Flat, on_architecture +using Oceananigans.OutputReaders: FieldTimeSeries, update_field_time_series!, extract_field_time_series, cpu_interpolating_time_indices +using Oceananigans.TimeSteppers: Clock, tick! +using Oceananigans.Units: Time +using Oceananigans.Utils: launch! + +using Adapt +using KernelAbstractions: @kernel, @index + +import NumericalEarth: stateindex +using NumericalEarth.EarthSystemModels.InterfaceComputations: interface_kernel_parameters + +import Oceananigans.TimeSteppers: time_step!, update_state! +import Oceananigans.Architectures: on_architecture + +import NumericalEarth.EarthSystemModels: interpolate_state!, + update_net_fluxes!, + apply_air_sea_radiative_fluxes!, + apply_air_sea_ice_radiative_fluxes!, + allocate_interface_fluxes! + +import NumericalEarth.EarthSystemModels.InterfaceComputations: ComponentExchanger, + initialize!, + kernel_radiation_properties, + air_sea_interface_radiation_state, + air_sea_ice_interface_radiation_state + +include("surface_radiation_properties.jl") +include("interface_radiation_flux.jl") +include("radiation_kernels.jl") +include("latitude_dependent_albedo.jl") +include("tabulated_albedo.jl") +include("prescribed_radiation.jl") +include("prescribed_radiation_regridder.jl") +include("interpolate_radiation_state.jl") +include("air_sea_interface_radiation_state.jl") +include("apply_air_sea_radiative_fluxes.jl") +include("apply_air_sea_ice_radiative_fluxes.jl") + +end # module Radiations diff --git a/src/Radiations/air_sea_interface_radiation_state.jl b/src/Radiations/air_sea_interface_radiation_state.jl new file mode 100644 index 000000000..4cd43c115 --- /dev/null +++ b/src/Radiations/air_sea_interface_radiation_state.jl @@ -0,0 +1,28 @@ +# PrescribedRadiation-aware methods for the radiation getter functions +# declared (with `nothing` fallbacks) in InterfaceComputations. + +@inline kernel_radiation_properties(r::PrescribedRadiation) = + (σ = r.stefan_boltzmann_constant, + surface_properties = r.surface_properties) + +@inline function air_sea_interface_radiation_state(rk, exchanger_state, + i, j, k, grid, time) + σ = rk.σ + @inbounds ℐꜜˢʷ = exchanger_state.ℐꜜˢʷ[i, j, 1] + @inbounds ℐꜜˡʷ = exchanger_state.ℐꜜˡʷ[i, j, 1] + s = rk.surface_properties.ocean + α = stateindex(s.albedo, i, j, k, grid, time, (Center, Center, Center), ℐꜜˢʷ) + ϵ = stateindex(s.emissivity, i, j, k, grid, time, (Center, Center, Center)) + return (; σ, α, ϵ, ℐꜜˢʷ, ℐꜜˡʷ) +end + +@inline function air_sea_ice_interface_radiation_state(rk, exchanger_state, + i, j, k, grid, time) + σ = rk.σ + @inbounds ℐꜜˢʷ = exchanger_state.ℐꜜˢʷ[i, j, 1] + @inbounds ℐꜜˡʷ = exchanger_state.ℐꜜˡʷ[i, j, 1] + s = rk.surface_properties.sea_ice + α = stateindex(s.albedo, i, j, k, grid, time, (Center, Center, Center), ℐꜜˢʷ) + ϵ = stateindex(s.emissivity, i, j, k, grid, time, (Center, Center, Center)) + return (; σ, α, ϵ, ℐꜜˢʷ, ℐꜜˡʷ) +end diff --git a/src/Radiations/apply_air_sea_ice_radiative_fluxes.jl b/src/Radiations/apply_air_sea_ice_radiative_fluxes.jl new file mode 100644 index 000000000..f9ce64236 --- /dev/null +++ b/src/Radiations/apply_air_sea_ice_radiative_fluxes.jl @@ -0,0 +1,92 @@ +using ClimaSeaIce: SeaIceModel + +""" + apply_air_sea_ice_radiative_fluxes!(coupled_model) + +Add the radiative contribution to the net sea-ice top heat flux and write +the diagnostic radiative fluxes (upwelling LW, absorbed LW, transmitted SW) +into `coupled_model.radiation.interface_fluxes.sea_ice`. + +When `coupled_model.radiation === nothing`, this is a no-op. +Also a no-op when sea-ice is not a `Simulation{<:SeaIceModel}`. +""" +apply_air_sea_ice_radiative_fluxes!(::EarthSystemModel{<:Nothing}) = nothing + +apply_air_sea_ice_radiative_fluxes!(coupled_model::EarthSystemModel) = + _apply_air_sea_ice_radiative_fluxes_dispatch!(coupled_model, coupled_model.sea_ice) + +# No sea-ice or non-prognostic sea-ice: nothing to do. +_apply_air_sea_ice_radiative_fluxes_dispatch!(coupled_model, ::Any) = nothing + +function _apply_air_sea_ice_radiative_fluxes_dispatch!(coupled_model::EarthSystemModel, + sea_ice::Simulation{<:SeaIceModel}) + radiation = coupled_model.radiation + interface_fluxes = radiation.interface_fluxes + haskey(interface_fluxes, :sea_ice) || return nothing + + grid = sea_ice.model.grid + arch = architecture(grid) + clock = coupled_model.clock + + top_heat_flux = coupled_model.interfaces.net_fluxes.sea_ice.top.heat + radiation_state = coupled_model.interfaces.exchanger.radiation.state + rk = kernel_radiation_properties(radiation) + + ice_concentration = sea_ice_concentration(sea_ice) + surface_temperature = coupled_model.interfaces.atmosphere_sea_ice_interface.temperature + sea_ice_properties = coupled_model.interfaces.sea_ice_properties + + launch!(arch, grid, :xy, + _apply_air_sea_ice_radiative_fluxes!, + top_heat_flux, + interface_fluxes.sea_ice, + grid, + clock, + rk, + radiation_state, + ice_concentration, + surface_temperature, + sea_ice_properties) + + return nothing +end + +@kernel function _apply_air_sea_ice_radiative_fluxes!(top_heat_flux, + interface_radiative_flux, + grid, + clock, + rk, + radiation_state, + ice_concentration, + surface_temperature, + sea_ice_properties) + + i, j = @index(Global, NTuple) + kᴺ = size(grid, 3) + time = Time(clock.time) + + @inbounds begin + ℵᵢ = ice_concentration[i, j, 1] + Ts = surface_temperature[i, j, kᴺ] + end + Ts = convert_to_kelvin(sea_ice_properties.temperature_units, Ts) + + rs = air_sea_ice_interface_radiation_state(rk, radiation_state, i, j, kᴺ, grid, time) + + ℐꜛˡʷ = rs.σ * rs.ϵ * Ts^4 + ℐₐˡʷ = - rs.ϵ * rs.ℐꜜˡʷ + ℐₜˢʷ = - (1 - rs.α) * rs.ℐꜜˢʷ + + # Sea-ice radiation contributes only where ice exists. + ice_present = ℵᵢ > 0 + ΣQ_rad_ice = (ℐꜛˡʷ + ℐₐˡʷ + ℐₜˢʷ) * ice_present + + inactive = inactive_node(i, j, kᴺ, grid, Center(), Center(), Center()) + + @inbounds begin + top_heat_flux[i, j, 1] += ifelse(inactive, zero(grid), ΣQ_rad_ice) + interface_radiative_flux.upwelling_longwave[i, j, 1] = ℐꜛˡʷ + interface_radiative_flux.downwelling_longwave[i, j, 1] = - ℐₐˡʷ + interface_radiative_flux.downwelling_shortwave[i, j, 1] = - ℐₜˢʷ + end +end diff --git a/src/Radiations/apply_air_sea_radiative_fluxes.jl b/src/Radiations/apply_air_sea_radiative_fluxes.jl new file mode 100644 index 000000000..8441d2b63 --- /dev/null +++ b/src/Radiations/apply_air_sea_radiative_fluxes.jl @@ -0,0 +1,110 @@ +using Oceananigans.Grids: inactive_node +using NumericalEarth.EarthSystemModels: EarthSystemModel +using NumericalEarth.EarthSystemModels.InterfaceComputations: convert_to_kelvin, sea_ice_concentration +using NumericalEarth.Oceans: shortwave_radiative_forcing, get_radiative_forcing + +""" + apply_air_sea_radiative_fluxes!(coupled_model) + +Add the radiative contribution to the net ocean heat flux `Jᵀ` and write +the diagnostic radiative fluxes (upwelling LW, absorbed LW, transmitted SW) +into `coupled_model.radiation.interface_fluxes.ocean`. + +When `coupled_model.radiation === nothing`, this is a no-op. +""" +apply_air_sea_radiative_fluxes!(::EarthSystemModel{<:Nothing}) = nothing + +function apply_air_sea_radiative_fluxes!(coupled_model::EarthSystemModel) + ocean = coupled_model.ocean + isnothing(ocean) && return nothing + + # No atmosphere--ocean interface (no atmosphere or no ocean): nothing to do. + ao_interface = coupled_model.interfaces.atmosphere_ocean_interface + isnothing(ao_interface) && return nothing + + radiation = coupled_model.radiation + interface_fluxes = radiation.interface_fluxes + isnothing(interface_fluxes) && return nothing + haskey(interface_fluxes, :ocean) || return nothing + + grid = ocean.model.grid + arch = architecture(grid) + clock = coupled_model.clock + + net_ocean_fluxes = coupled_model.interfaces.net_fluxes.ocean + radiation_state = coupled_model.interfaces.exchanger.radiation.state + rk = kernel_radiation_properties(radiation) + + sea_ice = coupled_model.sea_ice + ice_concentration = sea_ice_concentration(sea_ice) + + interface_temperature = ao_interface.temperature + ocean_properties = coupled_model.interfaces.ocean_properties + penetrating_radiation = get_radiative_forcing(ocean.model) + + launch!(arch, grid, :xy, + _apply_air_sea_radiative_fluxes!, + net_ocean_fluxes, + interface_fluxes.ocean, + penetrating_radiation, + grid, + clock, + rk, + radiation_state, + ice_concentration, + interface_temperature, + ocean_properties) + + return nothing +end + +@kernel function _apply_air_sea_radiative_fluxes!(net_ocean_fluxes, + interface_radiative_flux, + penetrating_radiation, + grid, + clock, + rk, + radiation_state, + ice_concentration, + ocean_surface_temperature, + ocean_properties) + + i, j = @index(Global, NTuple) + kᴺ = size(grid, 3) + time = Time(clock.time) + + @inbounds begin + ℵᵢ = ice_concentration[i, j, 1] + Tₛ = ocean_surface_temperature[i, j, 1] + end + Tₛ = convert_to_kelvin(ocean_properties.temperature_units, Tₛ) + + rs = air_sea_interface_radiation_state(rk, radiation_state, i, j, kᴺ, grid, time) + + ℐꜛˡʷ = rs.σ * rs.ϵ * Tₛ^4 + ℐₐˡʷ = - rs.ϵ * rs.ℐꜜˡʷ + ℐₜˢʷ = - (1 - rs.α) * rs.ℐꜜˢʷ + + # Multiply by ocean fraction (only the parts not blocked by ice) + ℐₐˡʷ *= (1 - ℵᵢ) + ℐₜˢʷ *= (1 - ℵᵢ) + ℐꜛˡʷ_ocean = ℐꜛˡʷ * (1 - ℵᵢ) + + Qss = shortwave_radiative_forcing(i, j, grid, penetrating_radiation, ℐₜˢʷ, ocean_properties) + + # Total radiative contribution to surface heat flux + ΣQ_rad = ℐꜛˡʷ_ocean + ℐₐˡʷ + Qss + + ρᵒᶜ⁻¹ = 1 / ocean_properties.reference_density + cᵒᶜ⁻¹ = 1 / ocean_properties.heat_capacity + Jᵀ_rad = ΣQ_rad * ρᵒᶜ⁻¹ * cᵒᶜ⁻¹ + + inactive = inactive_node(i, j, kᴺ, grid, Center(), Center(), Center()) + + @inbounds begin + net_ocean_fluxes.T[i, j, 1] += ifelse(inactive, zero(grid), Jᵀ_rad) + interface_radiative_flux.upwelling_longwave[i, j, 1] = ℐꜛˡʷ + interface_radiative_flux.downwelling_longwave[i, j, 1] = - ℐₐˡʷ + interface_radiative_flux.downwelling_shortwave[i, j, 1] = - ℐₜˢʷ + end +end diff --git a/src/Radiations/interface_radiation_flux.jl b/src/Radiations/interface_radiation_flux.jl new file mode 100644 index 000000000..85bf1d376 --- /dev/null +++ b/src/Radiations/interface_radiation_flux.jl @@ -0,0 +1,34 @@ +""" + InterfaceRadiationFlux{F} + +Container for the diagnostic radiative fluxes at an air–surface interface. +The same struct type is instantiated per surface (ocean, sea ice, snow, ...). + +Fields +====== +- `upwelling_longwave :: F` ϵσT⁴ +- `downwelling_longwave :: F` ϵℐꜜˡʷ (absorbed by the surface) +- `downwelling_shortwave :: F` (1−α)ℐꜜˢʷ (transmitted into the surface) +""" +struct InterfaceRadiationFlux{F} + upwelling_longwave :: F + downwelling_longwave :: F + downwelling_shortwave :: F +end + +function InterfaceRadiationFlux(grid) + F = Field{Center, Center, Nothing} + return InterfaceRadiationFlux(F(grid), F(grid), F(grid)) +end + +InterfaceRadiationFlux(::Nothing) = InterfaceRadiationFlux(ntuple(_ -> ZeroField(), 3)...) + +Adapt.adapt_structure(to, fluxes::InterfaceRadiationFlux) = + InterfaceRadiationFlux(Adapt.adapt(to, fluxes.upwelling_longwave), + Adapt.adapt(to, fluxes.downwelling_longwave), + Adapt.adapt(to, fluxes.downwelling_shortwave)) + +on_architecture(arch, fluxes::InterfaceRadiationFlux) = + InterfaceRadiationFlux(on_architecture(arch, fluxes.upwelling_longwave), + on_architecture(arch, fluxes.downwelling_longwave), + on_architecture(arch, fluxes.downwelling_shortwave)) diff --git a/src/Radiations/interpolate_radiation_state.jl b/src/Radiations/interpolate_radiation_state.jl new file mode 100644 index 000000000..277149bb0 --- /dev/null +++ b/src/Radiations/interpolate_radiation_state.jl @@ -0,0 +1,69 @@ +using NumericalEarth.Atmospheres: interp_atmos_time_series + +"""Interpolate the prescribed downwelling radiation onto the exchange grid.""" +function interpolate_state!(exchanger, grid, radiation::PrescribedRadiation, coupled_model) + arch = architecture(grid) + clock = coupled_model.clock + + ℐꜜˢʷ = radiation.downwelling_shortwave + ℐꜜˡʷ = radiation.downwelling_longwave + downwelling = (shortwave = ℐꜜˢʷ.data, longwave = ℐꜜˡʷ.data) + + radiation_times = ℐꜜˢʷ.times + radiation_backend = ℐꜜˢʷ.backend + radiation_time_indexing = ℐꜜˢʷ.time_indexing + + space_fractional_indices = exchanger.regridder + state = exchanger.state + state_data = (ℐꜜˢʷ = state.ℐꜜˢʷ.data, + ℐꜜˡʷ = state.ℐꜜˡʷ.data) + + t = clock.time + time_interpolator = cpu_interpolating_time_indices(arch, radiation_times, + radiation_time_indexing, t) + + kernel_parameters = interface_kernel_parameters(grid) + + launch!(arch, grid, kernel_parameters, + _interpolate_radiation_state!, + state_data, + space_fractional_indices, + time_interpolator, + grid, + downwelling, + radiation_backend, + radiation_time_indexing) + + return nothing +end + +@inline get_fractional_index(i, j, ::Nothing) = nothing +@inline get_fractional_index(i, j, frac) = @inbounds frac[i, j, 1] + +@kernel function _interpolate_radiation_state!(state, + space_fractional_indices, + time_interpolator, + exchange_grid, + downwelling, + rad_backend, + rad_time_indexing) + + i, j = @index(Global, NTuple) + + ii = space_fractional_indices.i + jj = space_fractional_indices.j + fi = get_fractional_index(i, j, ii) + fj = get_fractional_index(i, j, jj) + + x_itp = FractionalIndices(fi, fj, nothing) + t_itp = time_interpolator + args = (x_itp, t_itp, rad_backend, rad_time_indexing) + + ℐꜜˢʷ = interp_atmos_time_series(downwelling.shortwave, args...) + ℐꜜˡʷ = interp_atmos_time_series(downwelling.longwave, args...) + + @inbounds begin + state.ℐꜜˢʷ[i, j, 1] = ℐꜜˢʷ + state.ℐꜜˡʷ[i, j, 1] = ℐꜜˡʷ + end +end diff --git a/src/EarthSystemModels/InterfaceComputations/latitude_dependent_albedo.jl b/src/Radiations/latitude_dependent_albedo.jl similarity index 100% rename from src/EarthSystemModels/InterfaceComputations/latitude_dependent_albedo.jl rename to src/Radiations/latitude_dependent_albedo.jl diff --git a/src/Radiations/prescribed_radiation.jl b/src/Radiations/prescribed_radiation.jl new file mode 100644 index 000000000..23978633b --- /dev/null +++ b/src/Radiations/prescribed_radiation.jl @@ -0,0 +1,160 @@ +""" + PrescribedRadiation{G, T, FT, SW, LW, S, IF, TI} + +Top-level radiation component holding prescribed downwelling shortwave and +longwave radiation as `FieldTimeSeries`, plus per-surface radiative properties +(albedo, emissivity) and the Stefan–Boltzmann constant. Diagnostic radiative +fluxes (one `InterfaceRadiationFlux` per surface) are populated by the +`apply_air_sea_*_radiative_fluxes!` kernels at every step; `interface_fluxes` +is `nothing` until the radiation is paired with an `EarthSystemModel` (which +allocates the per-surface buffers on the exchange grid). +""" +mutable struct PrescribedRadiation{G, T, FT, SW, LW, S, TI} + grid :: G + clock :: Clock{T} + downwelling_shortwave :: SW + downwelling_longwave :: LW + surface_properties :: S + stefan_boltzmann_constant :: FT + # NamedTuple of `InterfaceRadiationFlux`, allocated at `EarthSystemModel` + # construction time once the exchange grid is known. Untyped so the field + # can be reassigned from `nothing` to a populated NamedTuple. + interface_fluxes + times :: TI +end + +function Base.summary(r::PrescribedRadiation) + Nx, Ny, Nz = size(r.grid) + Nt = length(r.times) + sz_str = string(Nx, "×", Ny, "×", Nz, "×", Nt) + return string(sz_str, " PrescribedRadiation") +end + +function Base.show(io::IO, r::PrescribedRadiation) + print(io, summary(r), " on ", grid_name(r.grid), ":", '\n') + print(io, "├── times: ", prettysummary(r.times), '\n') + print(io, "├── stefan_boltzmann_constant: ", prettysummary(r.stefan_boltzmann_constant), '\n') + print(io, "└── surface_properties: ", keys(r.surface_properties)) +end + +# Filter out surfaces whose property kwarg was passed as `nothing`. +@inline function _filter_surface_properties(; ocean=nothing, sea_ice=nothing, snow=nothing, land=nothing) + pairs = () + isnothing(ocean) || (pairs = (pairs..., :ocean => ocean)) + isnothing(sea_ice) || (pairs = (pairs..., :sea_ice => sea_ice)) + isnothing(snow) || (pairs = (pairs..., :snow => snow)) + isnothing(land) || (pairs = (pairs..., :land => land)) + return NamedTuple(pairs) +end + +""" + PrescribedRadiation(downwelling_shortwave, downwelling_longwave; + clock = nothing, + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), + snow_surface = nothing, + land_surface = nothing, + stefan_boltzmann_constant = 5.67e-8) + +Construct a `PrescribedRadiation` component from `FieldTimeSeries` of +downwelling shortwave and longwave radiation. Grid + times are inferred from +the shortwave FTS. + +Pass `*_surface = nothing` to omit that surface from `surface_properties`. +""" +function PrescribedRadiation(downwelling_shortwave::FieldTimeSeries, + downwelling_longwave::FieldTimeSeries; + clock = nothing, + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), + snow_surface = nothing, + land_surface = nothing, + stefan_boltzmann_constant = 5.67e-8) + + grid = downwelling_shortwave.grid + times = downwelling_shortwave.times + FT = eltype(downwelling_shortwave) + + if isnothing(clock) + clock = Clock{FT}(time = 0) + end + + surface_properties = _filter_surface_properties(ocean = ocean_surface, + sea_ice = sea_ice_surface, + snow = snow_surface, + land = land_surface) + + radiation = PrescribedRadiation(grid, + clock, + downwelling_shortwave, + downwelling_longwave, + surface_properties, + convert(FT, stefan_boltzmann_constant), + nothing, # interface_fluxes — populated at ESM construction + times) + update_state!(radiation) + return radiation +end + +""" + PrescribedRadiation(grid, times = [zero(grid)]; kwargs...) + +Construct a `PrescribedRadiation` with zero downwelling shortwave and longwave +fields on `grid`. Useful for emission-only mode (the surface radiates ϵσT⁴ but +no incoming radiation is absorbed). All other keyword arguments are forwarded +to the FTS-form constructor. +""" +function PrescribedRadiation(grid, times = [zero(eltype(grid))]; kwargs...) + sw = FieldTimeSeries{Center, Center, Nothing}(grid, times) + lw = FieldTimeSeries{Center, Center, Nothing}(grid, times) + return PrescribedRadiation(sw, lw; kwargs...) +end + +@inline function update_state!(radiation::PrescribedRadiation) + time = Time(radiation.clock.time) + ftses = extract_field_time_series(radiation) + + for fts in ftses + update_field_time_series!(fts, time) + end + return nothing +end + +@inline function time_step!(radiation::PrescribedRadiation, Δt) + tick!(radiation.clock, Δt) + update_state!(radiation) + return nothing +end + +# Prescribed radiation has no internal state to update from net fluxes. +update_net_fluxes!(coupled_model, ::PrescribedRadiation) = nothing + +""" + allocate_interface_fluxes!(radiation, exchange_grid, surfaces) + +Populate `radiation.interface_fluxes` with one `InterfaceRadiationFlux` +per surface present in the model. +""" +function allocate_interface_fluxes!(radiation::PrescribedRadiation, exchange_grid, surfaces) + pairs = (surface => InterfaceRadiationFlux(exchange_grid) for surface in surfaces) + radiation.interface_fluxes = NamedTuple(pairs) + return nothing +end + +##### +##### Checkpointing +##### + +import Oceananigans: prognostic_state, restore_prognostic_state! + +function prognostic_state(radiation::PrescribedRadiation) + return (; clock = prognostic_state(radiation.clock)) +end + +function restore_prognostic_state!(radiation::PrescribedRadiation, state) + restore_prognostic_state!(radiation.clock, state.clock) + update_state!(radiation) + return radiation +end + +restore_prognostic_state!(radiation::PrescribedRadiation, ::Nothing) = radiation diff --git a/src/Radiations/prescribed_radiation_regridder.jl b/src/Radiations/prescribed_radiation_regridder.jl new file mode 100644 index 000000000..5316fb5eb --- /dev/null +++ b/src/Radiations/prescribed_radiation_regridder.jl @@ -0,0 +1,51 @@ +function ComponentExchanger(radiation::PrescribedRadiation, grid) + + regridder = radiation_regridder(radiation, grid) + + state = (; ℐꜜˢʷ = Field{Center, Center, Nothing}(grid), + ℐꜜˡʷ = Field{Center, Center, Nothing}(grid)) + + return ComponentExchanger(state, regridder) +end + +function radiation_regridder(radiation::PrescribedRadiation, exchange_grid) + rad_grid = radiation.grid + arch = architecture(exchange_grid) + + FT = eltype(rad_grid) + TX, TY, TZ = topology(exchange_grid) + fi = TX() isa Flat ? nothing : Field{Center, Center, Nothing}(exchange_grid, FT) + fj = TY() isa Flat ? nothing : Field{Center, Center, Nothing}(exchange_grid, FT) + return (i = fi, j = fj) +end + +function initialize!(exchanger::ComponentExchanger, grid, radiation::PrescribedRadiation) + frac_indices = exchanger.regridder + # Skip horizontal regridding when both fractional-index buffers are + # absent (purely Flat horizontal exchange grid). + if isnothing(frac_indices.i) && isnothing(frac_indices.j) + return nothing + end + rad_grid = radiation.grid + kernel_parameters = interface_kernel_parameters(grid) + launch!(architecture(grid), grid, kernel_parameters, + _compute_radiation_fractional_indices!, frac_indices, grid, rad_grid) + return nothing +end + +@kernel function _compute_radiation_fractional_indices!(indices_tuple, exchange_grid, rad_grid) + i, j = @index(Global, NTuple) + kᴺ = size(exchange_grid, 3) + X = _node(i, j, kᴺ + 1, exchange_grid, Center(), Center(), Face()) + fractional_indices_ij = FractionalIndices(X, rad_grid, Center(), Center(), Center()) + fi = indices_tuple.i + fj = indices_tuple.j + @inbounds begin + if !isnothing(fi) + fi[i, j, 1] = fractional_indices_ij.i + end + if !isnothing(fj) + fj[i, j, 1] = fractional_indices_ij.j + end + end +end diff --git a/src/Radiations/radiation_kernels.jl b/src/Radiations/radiation_kernels.jl new file mode 100644 index 000000000..439d8277e --- /dev/null +++ b/src/Radiations/radiation_kernels.jl @@ -0,0 +1,24 @@ +@inline hack_cosd(φ) = cos(π * φ / 180) +@inline hack_sind(φ) = sin(π * φ / 180) + +const CCC = (Center, Center, Center) + +@inline function emitted_longwave_radiation(i, j, k, grid, time, T, σ, ϵ) + ϵi = stateindex(ϵ, i, j, k, grid, time, CCC) + return σ * ϵi * T^4 +end + +@inline function absorbed_longwave_radiation(i, j, k, grid, time, ϵ, ℐꜜˡʷ) + ϵi = stateindex(ϵ, i, j, k, grid, time, CCC) + return - ϵi * ℐꜜˡʷ +end + +@inline function transmitted_shortwave_radiation(i, j, k, grid, time, α, ℐꜜˢʷ) + αi = stateindex(α, i, j, k, grid, time, CCC, ℐꜜˢʷ) + return - (1 - αi) * ℐꜜˢʷ +end + +# Inside the solver we lose both spatial and temporal information, but the +# radiative properties have already been computed correctly +@inline net_absorbed_interface_radiation(ℐꜜˢʷ, ℐꜜˡʷ, α, ϵ) = - (1 - α) * ℐꜜˢʷ - ϵ * ℐꜜˡʷ +@inline emitted_longwave_radiation(T, σ, ϵ) = σ * ϵ * T^4 diff --git a/src/Radiations/surface_radiation_properties.jl b/src/Radiations/surface_radiation_properties.jl new file mode 100644 index 000000000..7fddf6869 --- /dev/null +++ b/src/Radiations/surface_radiation_properties.jl @@ -0,0 +1,29 @@ +struct SurfaceRadiationProperties{A, E} + albedo :: A + emissivity :: E +end + +""" + SurfaceRadiationProperties(albedo, emissivity) + +Bundle the radiative properties of a single surface (ocean, sea ice, snow, land) +that participate in radiative flux computation: shortwave reflectivity (`albedo`) +and longwave emissivity (`emissivity`). + +`albedo` may be a `Number`, a `LatitudeDependentAlbedo`, a `TabulatedAlbedo`, or +any other object for which `stateindex` is defined. `emissivity` may be a `Number` +or any other `stateindex`-able object. +""" +SurfaceRadiationProperties(; albedo, emissivity) = SurfaceRadiationProperties(albedo, emissivity) + +Adapt.adapt_structure(to, s::SurfaceRadiationProperties) = + SurfaceRadiationProperties(Adapt.adapt(to, s.albedo), + Adapt.adapt(to, s.emissivity)) + +Base.summary(::SurfaceRadiationProperties) = "SurfaceRadiationProperties" + +function Base.show(io::IO, s::SurfaceRadiationProperties) + print(io, summary(s), ":", '\n') + print(io, "├── albedo: ", prettysummary(s.albedo), '\n') + print(io, "└── emissivity: ", prettysummary(s.emissivity)) +end diff --git a/src/EarthSystemModels/InterfaceComputations/tabulated_albedo.jl b/src/Radiations/tabulated_albedo.jl similarity index 100% rename from src/EarthSystemModels/InterfaceComputations/tabulated_albedo.jl rename to src/Radiations/tabulated_albedo.jl diff --git a/src/SeaIces/assemble_net_sea_ice_fluxes.jl b/src/SeaIces/assemble_net_sea_ice_fluxes.jl index 17d1e10c0..0021cbffb 100644 --- a/src/SeaIces/assemble_net_sea_ice_fluxes.jl +++ b/src/SeaIces/assemble_net_sea_ice_fluxes.jl @@ -1,9 +1,6 @@ using NumericalEarth.EarthSystemModels.InterfaceComputations: computed_fluxes, interface_kernel_parameters, - convert_to_kelvin, - emitted_longwave_radiation, - absorbed_longwave_radiation, - transmitted_shortwave_radiation + convert_to_kelvin update_net_fluxes!(coupled_model, ::FreezingLimitedOceanTemperature) = nothing @@ -18,21 +15,12 @@ function update_net_fluxes!(coupled_model, sea_ice::Simulation{<:SeaIceModel}) sea_ice_ocean_fluxes = computed_fluxes(coupled_model.interfaces.sea_ice_ocean_interface) atmosphere_sea_ice_fluxes = computed_fluxes(coupled_model.interfaces.atmosphere_sea_ice_interface) - # Simplify NamedTuple to reduce parameter space consumption. - # See https://github.com/CliMA/NumericalEarth.jl/issues/116. atmosphere_fields = coupled_model.interfaces.exchanger.atmosphere.state - - downwelling_radiation = (ℐꜜˢʷ = atmosphere_fields.ℐꜜˢʷ.data, - ℐꜜˡʷ = atmosphere_fields.ℐꜜˡʷ.data) - freshwater_flux = atmosphere_fields.Jᶜ.data - atmos_sea_ice_properties = coupled_model.interfaces.atmosphere_sea_ice_interface.properties sea_ice_properties = coupled_model.interfaces.sea_ice_properties - - sea_ice_surface_temperature = coupled_model.interfaces.atmosphere_sea_ice_interface.temperature ice_concentration = sea_ice_concentration(sea_ice) - + launch!(arch, grid, :xy, _assemble_net_sea_ice_fluxes!, top_fluxes, @@ -43,10 +31,7 @@ function update_net_fluxes!(coupled_model, sea_ice::Simulation{<:SeaIceModel}) sea_ice_ocean_fluxes, freshwater_flux, ice_concentration, - sea_ice_surface_temperature, - downwelling_radiation, - sea_ice_properties, - atmos_sea_ice_properties) + sea_ice_properties) return nothing end @@ -59,24 +44,15 @@ end sea_ice_ocean_fluxes, freshwater_flux, # Where do we add this one? ice_concentration, - surface_temperature, - downwelling_radiation, - sea_ice_properties, - atmos_sea_ice_properties) + sea_ice_properties) i, j = @index(Global, NTuple) kᴺ = size(grid, 3) - time = Time(clock.time) @inbounds begin - Ts = surface_temperature[i, j, kᴺ] - Ts = convert_to_kelvin(sea_ice_properties.temperature_units, Ts) ℵi = ice_concentration[i, j, 1] - - ℐꜜˢʷ = downwelling_radiation.ℐꜜˢʷ[i, j, 1] - ℐꜜˡʷ = downwelling_radiation.ℐꜜˡʷ[i, j, 1] - 𝒬ᵀ = atmosphere_sea_ice_fluxes.sensible_heat[i, j, 1] # sensible heat flux - 𝒬ᵛ = atmosphere_sea_ice_fluxes.latent_heat[i, j, 1] # latent heat flux + 𝒬ᵀ = atmosphere_sea_ice_fluxes.sensible_heat[i, j, 1] # sensible heat flux + 𝒬ᵛ = atmosphere_sea_ice_fluxes.latent_heat[i, j, 1] # latent heat flux 𝒬ᶠʳᶻ = sea_ice_ocean_fluxes.frazil_heat[i, j, 1] # frazil heat flux 𝒬ⁱⁿᵗ = sea_ice_ocean_fluxes.interface_heat[i, j, 1] # interfacial heat flux end @@ -84,15 +60,8 @@ end ρτˣ = atmosphere_sea_ice_fluxes.x_momentum # zonal momentum flux ρτʸ = atmosphere_sea_ice_fluxes.y_momentum # meridional momentum flux - # Compute radiation fluxes - σ = atmos_sea_ice_properties.radiation.σ - α = atmos_sea_ice_properties.radiation.α - ϵ = atmos_sea_ice_properties.radiation.ϵ - ℐꜛˡʷ = emitted_longwave_radiation(i, j, kᴺ, grid, time, Ts, σ, ϵ) - ℐₜˢʷ = transmitted_shortwave_radiation(i, j, kᴺ, grid, time, α, ℐꜜˢʷ) - ℐₐˡʷ = absorbed_longwave_radiation(i, j, kᴺ, grid, time, ϵ, ℐꜜˡʷ) - - ΣQt = (ℐₜˢʷ + ℐₐˡʷ + ℐꜛˡʷ + 𝒬ᵀ + 𝒬ᵛ) * (ℵi > 0) # If ℵi == 0 there is no heat flux from the top! + # Turbulent contributions only (radiation added later by apply_air_sea_ice_radiative_fluxes!) + ΣQt = (𝒬ᵀ + 𝒬ᵛ) * (ℵi > 0) ΣQb = 𝒬ᶠʳᶻ + 𝒬ⁱⁿᵗ # Mask fluxes over land for convenience From b9260d8e6e63d2fee2cb629ab8be8d39e0515337 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 29 Apr 2026 17:44:52 -0600 Subject: [PATCH 02/13] Migrate tests to top-level radiation component - Replace Radiation(arch) with JRA55PrescribedRadiation(arch; backend) in test_ocean_only_model.jl, test_ocean_sea_ice_model.jl, test_sea_ice_ocean_heat_fluxes.jl, test_checkpointer.jl, test_reactant.jl. - Replace 'no radiation' Radiation(emissivity=0, albedo=1) and Radiation() defaults with radiation=nothing in test_surface_fluxes.jl, test_diagnostics_2.jl, test_speedy_coupling.jl. - Update test_ecco_atmosphere.jl and test_ospapa.jl to also build ECCOPrescribedRadiation / OSPapaPrescribedRadiation and assert against radiation.downwelling_shortwave / longwave. - New test_radiations.jl covers PrescribedRadiation construction, time_step!, pairing with OceanOnlyModel (verifies interface_fluxes allocation), and JRA55PrescribedRadiation loading. Co-Authored-By: Claude Opus 4.7 (1M context) --- test/Manifest.toml | 2409 ++++++++++++++++++++++++ test/test_checkpointer.jl | 3 +- test/test_diagnostics_2.jl | 2 +- test/test_ecco_atmosphere.jl | 17 +- test/test_ocean_only_model.jl | 4 +- test/test_ocean_sea_ice_model.jl | 2 +- test/test_ospapa.jl | 16 +- test/test_radiations.jl | 82 + test/test_reactant.jl | 3 +- test/test_sea_ice_ocean_heat_fluxes.jl | 8 +- test/test_speedy_coupling.jl | 3 +- test/test_surface_fluxes.jl | 11 +- 12 files changed, 2531 insertions(+), 29 deletions(-) create mode 100644 test/Manifest.toml create mode 100644 test/test_radiations.jl diff --git a/test/Manifest.toml b/test/Manifest.toml new file mode 100644 index 000000000..aa421621b --- /dev/null +++ b/test/Manifest.toml @@ -0,0 +1,2409 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.6" +manifest_format = "2.0" +project_hash = "b66e32e367c83f4abfda540176d6a679e11da82b" + +[[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.AbstractNumbers]] +deps = ["SpecialFunctions"] +git-tree-sha1 = "c0aa4b519104fecca9bc146c9843393f7cbd3c99" +uuid = "85c772de-338a-5e7f-b815-41e76c26ac1f" +version = "0.2.5" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] +git-tree-sha1 = "2eeb2c9bef11013efc6f8f97f32ee59b146b09fb" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.44" + + [deps.Accessors.extensions] + AxisKeysExt = "AxisKeys" + IntervalSetsExt = "IntervalSets" + LinearAlgebraExt = "LinearAlgebra" + StaticArraysExt = "StaticArrays" + StructArraysExt = "StructArrays" + TestExt = "Test" + UnitfulExt = "Unitful" + + [deps.Accessors.weakdeps] + AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "0761717147821d696c9470a7a86364b2fbd22fd8" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.5.2" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra"] +git-tree-sha1 = "54f895554d05c83e3dd59f6a396671dae8999573" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.24.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceAMDGPUExt = "AMDGPU" + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"] + ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceMetalExt = "Metal" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + 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" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.AssociatedLegendrePolynomials]] +git-tree-sha1 = "c5b6a5ac656586d038dd04441b6e165a21c80f09" +uuid = "2119f1ac-fb78-50f5-8cc0-dda848ebdb19" +version = "1.0.2" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "b8651b2eb5796a386b0398a20b519a6a6150f75c" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "1.1.3" + + [deps.Atomix.extensions] + AtomixCUDAExt = "CUDA" + AtomixMetalExt = "Metal" + AtomixOpenCLExt = "OpenCL" + AtomixoneAPIExt = "oneAPI" + + [deps.Atomix.weakdeps] + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" + oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random"] +git-tree-sha1 = "e386db8b4753b42caac75ac81d0a4fe161a68a97" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.6.1" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BitInformation]] +deps = ["Distributions", "Random", "StatsBase"] +git-tree-sha1 = "2cf994e66a0886a91ba108cb3cfc044363f0bb01" +uuid = "de688a37-743e-4ac2-a6f0-bd62414d1aa7" +version = "0.6.3" + +[[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 = "535c80f1c0847a4c967ea945fca21becc9de1522" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.7+0" + +[[deps.Breeze]] +deps = ["Adapt", "Dates", "DocStringExtensions", "GPUArraysCore", "InteractiveUtils", "JLD2", "KernelAbstractions", "Oceananigans", "Printf", "Statistics"] +git-tree-sha1 = "4c487a3a17edd7ab11075f28fcd40332129343cd" +repo-rev = "main" +repo-url = "https://github.com/NumericalEarth/Breeze.jl/" +uuid = "660aa2fb-d4c8-4359-a52c-9c057bc511da" +version = "0.4.8" + + [deps.Breeze.extensions] + BreezeCloudMicrophysicsExt = ["CloudMicrophysics", "SpecialFunctions"] + BreezeRRTMGPExt = ["ClimaComms", "RRTMGP"] + BreezeReactantExt = "Reactant" + + [deps.Breeze.weakdeps] + ClimaComms = "3a4d1b5c-c61d-41fd-a00a-5873ba7a1b0d" + CloudMicrophysics = "6a9e3e04-43cd-43ba-94b9-e8782df3c71b" + RRTMGP = "a01a1ee8-cea4-48fc-987c-fc7878d79da1" + Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.BufferedStreams]] +git-tree-sha1 = "6863c5b7fc997eadcabdbaf6c5f201dc30032643" +uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" +version = "1.2.2" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.CDSAPI]] +deps = ["Dates", "HTTP", "JSON", "ScopedValues"] +git-tree-sha1 = "5cc0e84538b4619208d63002e273056633f33553" +uuid = "8a7b9de3-9c00-473e-88b4-7eccd7ef2fea" +version = "2.2.2" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "b2c9f2d3b8014323c0a8f2b401b68fa6bb08ed06" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.2.8" + +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Preferences", "Static"] +git-tree-sha1 = "f3a21d7fc84ba618a779d1ed2fcca2e682865bab" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.7" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Compiler_jll", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] +git-tree-sha1 = "c876673fd63ca14d8e02dff5aa720fbea93e6584" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.11.2" + + [deps.CUDA.extensions] + ChainRulesCoreExt = "ChainRulesCore" + EnzymeCoreExt = "EnzymeCore" + SparseMatricesCSRExt = "SparseMatricesCSR" + SpecialFunctionsExt = "SpecialFunctions" + + [deps.CUDA.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + SparseMatricesCSR = "a0a7dd2c-ebf4-11e9-1f05-cf50bc540ca1" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.CUDA_Compiler_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "CUDA_Runtime_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "b977706846cb0a75d3842a1fed810ab2e6ab2f94" +uuid = "d1e2174e-dfdc-576e-b43e-73b79eb1aca8" +version = "0.4.3+0" + +[[deps.CUDA_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "TOML"] +git-tree-sha1 = "3b759ec65ac87ad192c2925114fa5c126657a5bd" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "13.2.1+0" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "4fd010410c0c91c8b9bd6194a9ebdebecd9a8107" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "2.0.0" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "c0314d9fb0ebd00e404feba4c3fbc04c9975abc1" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.21.0+1" + +[[deps.CatViews]] +deps = ["Random", "Test"] +git-tree-sha1 = "23d1f1e10d4e24374112fcf800ac981d14a54b24" +uuid = "81a5f4ea-a946-549a-aa7e-2a7f63a27d31" +version = "1.0.0" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "12177ad6b3cad7fd50c8b3825ce24a99ad61c18f" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.26.1" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ChunkCodecCore]] +git-tree-sha1 = "1a3ad7e16a321667698a19e77362b35a1e94c544" +uuid = "0b6fb165-00bc-4d37-ab8b-79f91016dbe1" +version = "1.0.1" + +[[deps.ChunkCodecLibZlib]] +deps = ["ChunkCodecCore", "Zlib_jll"] +git-tree-sha1 = "cee8104904c53d39eb94fd06cbe60cb5acde7177" +uuid = "4c0bbee4-addc-4d73-81a0-b6caacae83c8" +version = "1.0.0" + +[[deps.ChunkCodecLibZstd]] +deps = ["ChunkCodecCore", "Zstd_jll"] +git-tree-sha1 = "34d9873079e4cb3d0c62926a225136824677073f" +uuid = "55437552-ac27-4d47-9aa3-63184e8fd398" +version = "1.0.0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "JLD2", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "813f90bc5583311d17767468df8e98209a96aa53" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.4.10" + +[[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 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.CommonDataModel]] +deps = ["CFTime", "DataStructures", "Dates", "DiskArrays", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "bf07704e843daabd2cb2bb1404571656f80bce16" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.4.3" + +[[deps.CommonSolve]] +git-tree-sha1 = "78ea4ddbcf9c241827e7035c3a03e2e456711470" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.6" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.1" + +[[deps.CommonWorldInvalidations]] +git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" +uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" +version = "1.0.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.ComponentArrays]] +deps = ["Adapt", "ArrayInterface", "ChainRulesCore", "ConstructionBase", "Functors", "LinearAlgebra", "StaticArrayInterface", "StaticArraysCore"] +git-tree-sha1 = "342e21057cfa3152eb456ebcda25ed5ce3f0e275" +uuid = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66" +version = "0.15.37" + + [deps.ComponentArrays.extensions] + ComponentArraysGPUArraysExt = "GPUArrays" + ComponentArraysKernelAbstractionsExt = "KernelAbstractions" + ComponentArraysMooncakeExt = "Mooncake" + ComponentArraysOptimisersExt = "Optimisers" + ComponentArraysReactantExt = "Reactant" + ComponentArraysRecursiveArrayToolsExt = "RecursiveArrayTools" + ComponentArraysReverseDiffExt = "ReverseDiff" + ComponentArraysSciMLBaseExt = "SciMLBase" + ComponentArraysTrackerExt = "Tracker" + ComponentArraysZygoteExt = "Zygote" + + [deps.ComponentArrays.weakdeps] + GPUArrays = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" + KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" + Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" + Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2" + Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" + RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.CompositeTypes]] +git-tree-sha1 = "bce26c3dab336582805503bed209faab1c279768" +uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657" +version = "0.1.4" + +[[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 = "21d088c496ea22914fe80906eb5bce65755e5ec8" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.1" + +[[deps.CondaPkg]] +deps = ["JSON", "Markdown", "MicroMamba", "Pidfile", "Pkg", "Preferences", "Scratch", "TOML", "pixi_jll"] +git-tree-sha1 = "0300af904a8c8d41ff715a60a6959136d22b8572" +uuid = "992eb4ea-22a4-4c89-a5bb-47a3300528ab" +version = "0.2.34" + +[[deps.ConstructionBase]] +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.6.0" +weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.CopernicusMarine]] +deps = ["CondaPkg", "PythonCall"] +git-tree-sha1 = "9ec0ad703214ef341cf59496a48060f323eccaf9" +uuid = "cd43e856-93a3-40c8-bc9e-6146cdce14fa" +version = "0.1.1" + +[[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 = ["Distances", "LinearAlgebra", "Printf", "Random", "Statistics", "TaylorSeries"] +git-tree-sha1 = "6ffea589cf350b1582722e57a8de787907d59454" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.3.4" + +[[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", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "5fab31e2e01e70ad66e3e24c968c264d1cf166d6" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.8.2" + +[[deps.DataStructures]] +deps = ["OrderedCollections"] +git-tree-sha1 = "e86f4a2805f7f19bec5129bc9150c38208e5dc23" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.19.4" + +[[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" +version = "1.11.0" + +[[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 = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] +git-tree-sha1 = "e5d9ce1b751ddf9bcd9d36b51249dce8ea73cd55" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.4.19" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.12" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "e421c1938fafab0165b04dc1a9dbe2a26272952c" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.125" + + [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]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.DomainSets]] +deps = ["CompositeTypes", "FunctionMaps", "IntervalSets", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "4599e0cd684f3ff6cbbab73c77553a3d01a8d74d" +uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" +version = "0.7.18" + + [deps.DomainSets.extensions] + DomainSetsMakieExt = "Makie" + DomainSetsRandomExt = "Random" + + [deps.DomainSets.weakdeps] + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.7.0" + +[[deps.EnumX]] +git-tree-sha1 = "c49898e8438c828577f04b92fc9368c388ac783c" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.7" + +[[deps.Enzyme]] +deps = ["CEnum", "EnzymeCore", "Enzyme_jll", "GPUCompiler", "InteractiveUtils", "LLVM", "Libdl", "LinearAlgebra", "ObjectFile", "PrecompileTools", "Preferences", "Printf", "Random", "SparseArrays"] +git-tree-sha1 = "d6dd65421104fa9f7d5cc37283a998937f359a39" +uuid = "7da242da-08ed-463a-9acd-ee780be4f1d9" +version = "0.13.138" + + [deps.Enzyme.extensions] + EnzymeBFloat16sExt = "BFloat16s" + EnzymeChainRulesCoreExt = "ChainRulesCore" + EnzymeGPUArraysCoreExt = "GPUArraysCore" + EnzymeLogExpFunctionsExt = "LogExpFunctions" + EnzymeSpecialFunctionsExt = "SpecialFunctions" + EnzymeStaticArraysExt = "StaticArrays" + + [deps.Enzyme.weakdeps] + ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" + BFloat16s = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.EnzymeCore]] +git-tree-sha1 = "24bbb6fc8fb87eb71c1f8d00184a60fc22c63903" +uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" +version = "0.8.19" +weakdeps = ["Adapt", "ChainRulesCore"] + + [deps.EnzymeCore.extensions] + AdaptExt = "Adapt" + EnzymeCoreChainRulesCoreExt = "ChainRulesCore" + +[[deps.Enzyme_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "4c22000e08aaa862526d9a41cfb7003e4002e653" +uuid = "7cc45869-7501-5eee-bdea-0790c847d4ef" +version = "0.0.256+0" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.ExpressionExplorer]] +git-tree-sha1 = "5f1c005ed214356bbe41d442cc1ccd416e510b7e" +uuid = "21656369-7473-754a-2065-74616d696c43" +version = "1.1.4" + +[[deps.Extents]] +git-tree-sha1 = "b309b36a9e02fe7be71270dd8c0fd873625332b4" +uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" +version = "0.1.6" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "97f08406df914023af55ade2f843c39e99c5d969" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.10.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6866aec60ef98e3164cd8d6855225684207e9dff" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.12+0" + +[[deps.FastGaussQuadrature]] +deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "0044e9f5e49a57e88205e8f30ab73928b05fe5b6" +uuid = "442a2c76-b920-505d-bb47-c5924d526838" +version = "1.1.0" + +[[deps.FieldMetadata]] +git-tree-sha1 = "c279c6eab9767a3f62685e5276c850512e0a1afd" +uuid = "bf96fef3-21d2-5d20-8afa-0e7d4c32a885" +version = "0.3.1" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "6522cfb3b8fe97bec632252263057996cbd3de20" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.18.0" +weakdeps = ["HTTP"] + + [deps.FileIO.extensions] + HTTPExt = "HTTP" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "2f979084d1e13948a3352cf64a25df6bd3b4dca3" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.16.0" +weakdeps = ["PDMats", "SparseArrays", "StaticArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStaticArraysExt = "StaticArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Flatten]] +deps = ["ConstructionBase", "FieldMetadata"] +git-tree-sha1 = "d3541c658c7e452fefba6c933c43842282cdfd3e" +uuid = "4c728ea3-d9ee-5c9a-9642-b6f7d7dc04fa" +version = "0.4.3" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cddeab6487248a39dae1a960fff0ac17b2a28888" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.3.3" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FunctionMaps]] +deps = ["CompositeTypes", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "31bd99a57edf98990d1c21486032963955450e8d" +uuid = "a85aefff-f8ca-4649-a888-c8e5398bc76c" +version = "0.1.2" + +[[deps.Functors]] +deps = ["Compat", "ConstructionBase", "LinearAlgebra", "Random"] +git-tree-sha1 = "60a0339f28a233601cb74468032b5c302d5067de" +uuid = "d9f16b24-f501-4c13-a1f2-28368ffc5196" +version = "0.5.2" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" +version = "1.11.0" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "SparseArrays", "Statistics"] +git-tree-sha1 = "34fd745547978beb471f029f447290ef4dbc7bbd" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "11.5.3" +weakdeps = ["JLD2"] + + [deps.GPUArrays.extensions] + JLD2Ext = "JLD2" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "83cf05ab16a73219e5f6bd1bdfa9848fa24ac627" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.2.0" + +[[deps.GPUCompiler]] +deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "PrecompileTools", "Preferences", "Scratch", "Serialization", "TOML", "Tracy", "UUIDs"] +git-tree-sha1 = "fedfe5e7db7035271c3f58359007f971da1dde87" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "1.9.1" + +[[deps.GPUToolbox]] +deps = ["LLVM"] +git-tree-sha1 = "a589b6c1a0eff953571f5d8b0474f5020831114d" +uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" +version = "1.1.1" + +[[deps.GenericFFT]] +deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "Reexport"] +git-tree-sha1 = "5029b303ba330e2c94ea3237b0e20df44aaab75e" +uuid = "a8297547-1b15-4a5a-a998-a2ac5f1cef28" +version = "0.1.7" + +[[deps.GeoFormatTypes]] +git-tree-sha1 = "7528a7956248c723d01a0a9b0447bf254bf4da52" +uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f" +version = "0.4.5" + +[[deps.GeoInterface]] +deps = ["DataAPI", "Extents", "GeoFormatTypes"] +git-tree-sha1 = "2b0312a0c06b4408773c6dc1829b472ea706f058" +uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" +version = "1.6.1" + + [deps.GeoInterface.extensions] + GeoInterfaceMakieExt = ["Makie", "GeometryBasics"] + GeoInterfaceRecipesBaseExt = "RecipesBase" + + [deps.GeoInterface.weakdeps] + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" + +[[deps.Glob]] +git-tree-sha1 = "83cb0092e2792b9e3a865b6655e88f5b862607e2" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.4.0" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "MPIABI_jll", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "aws_c_s3_jll", "dlfcn_win32_jll", "libaec_jll", "mpif_jll"] +git-tree-sha1 = "45337643a2d97262d5fe72ce1f13e8a662d13d62" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "2.1.2+0" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "51059d23c8bb67911a2e6fd5130229113735fc7e" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.11.0" + +[[deps.HashArrayMappedTries]] +git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" +uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" +version = "0.2.0" + +[[deps.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Preferences", "Static"] +git-tree-sha1 = "af9ab7d1f70739a47f03be78771ebda38c3c71bf" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.18" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XML2_jll", "Xorg_libpciaccess_jll"] +git-tree-sha1 = "baaaebd42ed9ee1bd9173cfd56910e55a8622ee1" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.13.0+1" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "0ee181ec08df7d7c911901ea38baf16f755114dc" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "1.0.0" + +[[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 = "8c193230235bbcee22c8066b0374f63b5683c2d3" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.5" + +[[deps.ImageMorphology]] +deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] +git-tree-sha1 = "895205d762ae24a01689f8cc7ad584b55f1fd005" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.4.7" + +[[deps.InlineStrings]] +git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.5" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + ParsersExt = "Parsers" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" + +[[deps.Inpaintings]] +deps = ["LinearAlgebra", "Match", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "aa4e89ed3dcb4cc854ac386cbdcfa3c3b3de4f87" +uuid = "a3d749fb-087c-5225-80b3-65fbd02ae0fd" +version = "0.3.1" + +[[deps.IntegerMathUtils]] +git-tree-sha1 = "4c1acff2dc6b6967e7e750633c50bc3b8d83e617" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.3" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "ec1debd61c300961f98064cfb21287613ad7f303" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2025.2.0+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[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" +weakdeps = ["Unitful"] + + [deps.Interpolations.extensions] + InterpolationsUnitfulExt = "Unitful" + +[[deps.IntervalSets]] +git-tree-sha1 = "79d6bd28c8d9bccc2229784f1bd637689b256377" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.14" + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + + [deps.IntervalSets.weakdeps] + Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.InverseFunctions]] +git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.17" +weakdeps = ["Dates", "Test"] + + [deps.InverseFunctions.extensions] + InverseFunctionsDatesExt = "Dates" + InverseFunctionsTestExt = "Test" + +[[deps.InvertedIndices]] +git-tree-sha1 = "6da3c4316095de0f5ee2ebd875df8721e7e0bdbe" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.1" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["ChunkCodecLibZlib", "ChunkCodecLibZstd", "FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues"] +git-tree-sha1 = "941f87a0ae1b14d1ac2fa57245425b23a9d7a516" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.6.4" +weakdeps = ["UnPack"] + + [deps.JLD2.extensions] + UnPackExt = "UnPack" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"] +git-tree-sha1 = "67c6f1f085cb2671c93fe34244c9cccde30f7a26" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "1.5.0" + + [deps.JSON.extensions] + JSONArrowExt = ["ArrowTypes"] + + [deps.JSON.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.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] +git-tree-sha1 = "f2e76d3ced51a2a9e185abc0b97494c7273f649f" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.41" +weakdeps = ["EnzymeCore", "LinearAlgebra", "SparseArrays"] + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + LinearAlgebraExt = "LinearAlgebra" + SparseArraysExt = "SparseArrays" + +[[deps.Krylov]] +deps = ["LinearAlgebra", "Printf", "SparseArrays"] +git-tree-sha1 = "c4d19f51afc7ba2afbe32031b8f2d21b11c9e26e" +uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" +version = "0.10.6" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "PrecompileTools", "Preferences", "Printf", "Unicode"] +git-tree-sha1 = "c0cec0c63687dda0115a51fe04d8f75902e181b3" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "9.6.0" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "721fcd02aa06f8b2ed58d8db9914beab7a274b69" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.41+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 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LRUCache]] +git-tree-sha1 = "5519b95a490ff5fe629c4a7aa3b3dfc9160498b3" +uuid = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" +version = "1.6.2" +weakdeps = ["Serialization"] + + [deps.LRUCache.extensions] + SerializationExt = ["Serialization"] + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.LayoutPointers]] +deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "a9eaadb366f5493a5654e843864c13d8b107548c" +uuid = "10f19ff3-798f-405d-979b-55457f8fc047" +version = "0.1.17" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" +version = "1.11.0" + +[[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", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.15.0+0" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.LibTracyClient_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d4e20500d210247322901841d4eafc7a0c52642d" +uuid = "ad6e5548-8b26-5c9f-8ef3-ef0ad883f3a5" +version = "0.13.1+0" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [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" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.LoopVectorization]] +deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] +git-tree-sha1 = "a9fc7883eb9b5f04f46efb9a540833d1fad974b3" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.173" + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + ForwardDiffNNlibExt = ["ForwardDiff", "NNlib"] + SpecialFunctionsExt = "SpecialFunctions" + + [deps.LoopVectorization.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.LowerTriangularArrays]] +deps = ["Adapt", "DocStringExtensions", "GPUArrays", "KernelAbstractions", "LinearAlgebra", "SpeedyWeatherInternals"] +git-tree-sha1 = "bd7e64ab00ef86d7c501dbf728601af434967c65" +uuid = "ed20b33f-a660-45d0-a353-9c8c20bb5814" +version = "0.1.2" + + [deps.LowerTriangularArrays.extensions] + LowerTriangularArraysFiniteDifferencesExt = "FiniteDifferences" + + [deps.LowerTriangularArrays.weakdeps] + FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "191686b1ac1ea9c89fc52e996ad15d1d241d1e33" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.10.1+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "282cadc186e7b2ae0eeadbd7a4dffed4196ae2aa" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2025.2.0+0" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPIABI_jll", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Serialization", "Sockets"] +git-tree-sha1 = "ff6309186ff377782d01f6577d19ae1b5f5185c5" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.26" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPIABI_jll]] +deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "9be143b6045719e8fb019d2b3bc2aebad1184fef" +uuid = "b5ada748-db0f-5fc0-8972-9331c762740c" +version = "0.1.5+0" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "07dbec8aab01696edc0151a401a6cdfe95b9b885" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "5.0.1+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "8e98d5d80b87403c311fd51e8455d4546ba7a5f8" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.12" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "675df097f8eeb28998b2cfe3b25655af73d5f7df" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.5.6+0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Malt]] +deps = ["Distributed", "Logging", "RelocatableFolders", "Serialization", "Sockets"] +git-tree-sha1 = "c2335b4e291f2422e2be8abf8936ccad58a98992" +uuid = "36869731-bdee-424d-aa32-cab38c994e3b" +version = "1.4.1" + +[[deps.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.MappedArrays]] +git-tree-sha1 = "0ee4497a4e80dbd29c058fcee6493f5219556f40" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.3" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.Match]] +deps = ["MacroTools", "OrderedCollections"] +git-tree-sha1 = "58c5c5db26f2f0512facb359991410b7b5982c38" +uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf" +version = "2.4.1" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "8785729fa736197687541f7053f6d8ab7fc44f92" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.10" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ff69a2b1330bcb730b9ac1ab7dd680176f5896b8" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.1010+0" + +[[deps.MeshArrays]] +deps = ["CatViews", "Dates", "Distributed", "GeoInterface", "Glob", "LazyArtifacts", "NearestNeighbors", "Pkg", "Printf", "SharedArrays", "SparseArrays", "Statistics", "Unitful"] +git-tree-sha1 = "aa4d4dac4dd237c53fc9c8dcd1771acb216b357a" +uuid = "cb8c808f-1acf-59a3-9d2b-6e38d009f683" +version = "0.5.5" + + [deps.MeshArrays.extensions] + MeshArraysDataDepsExt = ["DataDeps"] + MeshArraysGeoJSONExt = ["GeoJSON"] + MeshArraysGeometryOpsExt = ["GeometryOps"] + MeshArraysJLD2Ext = ["JLD2"] + MeshArraysMakieExt = ["Makie"] + MeshArraysProjExt = ["Proj"] + MeshArraysShapefileExt = ["Shapefile"] + + [deps.MeshArrays.weakdeps] + DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" + GeoJSON = "61d90e0f-e114-555e-ac52-39dfb47a3ef9" + GeometryOps = "3251bfac-6a57-4b6d-aa61-ac1fef2975ab" + JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + Proj = "c94c279d-25a6-4763-9509-64d165bea63e" + Shapefile = "8e980c4a-a4fe-5da2-b3a7-4b4b0353a2f4" + +[[deps.MicroMamba]] +deps = ["Pkg", "Scratch", "micromamba_jll"] +git-tree-sha1 = "535656ce55266bfed0575cd051acc4f36dc869a0" +uuid = "0b3b1443-0f03-428d-bdfb-f27f9c1191ea" +version = "0.1.15" + +[[deps.MicrosoftMPI_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "bc95bf4149bf535c09602e3acdf950d9b4376227" +uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" +version = "10.1.4+3" + +[[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" +version = "1.11.0" + +[[deps.ModelParameters]] +deps = ["AbstractNumbers", "ConstructionBase", "Flatten", "PrettyTables", "Setfield", "Tables"] +git-tree-sha1 = "6ba99217d1f748115c2edab0bdd56b9fe4e5b795" +uuid = "4744a3fa-6c31-4707-899e-a3298e4618ad" +version = "0.4.6" + + [deps.ModelParameters.extensions] + ModelParametersMakieExt = "Makie" + ModelParametersUnitfulExt = "Unitful" + + [deps.ModelParameters.weakdeps] + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[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 = "2025.11.4" + +[[deps.MuladdMacro]] +git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" +uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +version = "0.2.4" + +[[deps.NCDatasets]] +deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] +git-tree-sha1 = "5eb7747d10437f5acb2675c1f865ffa0353f3f9c" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.15" +weakdeps = ["MPI"] + + [deps.NCDatasets.extensions] + NCDatasetsMPIExt = "MPI" + +[[deps.NVTX]] +deps = ["JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "a9083c3e469e63cca454d1fc3b19472d9d92c14a" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "1.0.3" +weakdeps = ["Colors"] + + [deps.NVTX.extensions] + NVTXColorsExt = "Colors" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "af2232f69447494514c25742ba1503ec7e9877fe" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.2.2+0" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NearestNeighbors]] +deps = ["AbstractTrees", "Distances", "StaticArrays"] +git-tree-sha1 = "e2c3bba08dd6dedfe17a17889131b885b8c082f0" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.27" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPIABI_jll", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML", "XML2_jll", "Zlib_jll", "Zstd_jll", "libaec_jll", "libzip_jll"] +git-tree-sha1 = "8a36db9b934b0e72583e624abc8f3b3d60554f2c" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "401.1000.0+0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.NumericalEarth]] +deps = ["Adapt", "CFTime", "ClimaSeaIce", "CubedSphere", "DataDeps", "Dates", "Distances", "DocStringExtensions", "Downloads", "GPUArraysCore", "Glob", "ImageMorphology", "JLD2", "KernelAbstractions", "MeshArrays", "NCDatasets", "Oceananigans", "OffsetArrays", "PrecompileTools", "Printf", "Scratch", "SeawaterPolynomials", "StaticArrays", "Statistics", "Thermodynamics", "ZipFile"] +path = ".." +uuid = "904d977b-046a-4731-8b86-9235c0d1ef02" +version = "0.3.0" +weakdeps = ["Breeze", "CDSAPI", "CondaPkg", "CopernicusMarine", "PythonCall", "Reactant", "SpeedyWeather", "WorldOceanAtlasTools", "XESMF"] + + [deps.NumericalEarth.extensions] + NumericalEarthBreezeExt = "Breeze" + NumericalEarthCDSAPIExt = "CDSAPI" + NumericalEarthCopernicusMarineExt = "CopernicusMarine" + NumericalEarthReactantExt = "Reactant" + NumericalEarthSpeedyWeatherExt = ["SpeedyWeather", "XESMF"] + NumericalEarthVerosExt = ["PythonCall", "CondaPkg"] + NumericalEarthWOAExt = "WorldOceanAtlasTools" + +[[deps.ObjectFile]] +deps = ["Reexport", "StructIO"] +git-tree-sha1 = "22faba70c22d2f03e60fbc61da99c4ebfc3eb9ba" +uuid = "d8793406-e978-5875-9003-1fc021f44a92" +version = "0.5.0" + +[[deps.OceanGrids]] +deps = ["Inpaintings", "Interpolations", "LinearAlgebra", "NearestNeighbors", "SparseArrays", "Unitful"] +git-tree-sha1 = "7c17f4245c6fe4e69fdeedc49572c2547c9a073f" +uuid = "cfe838f4-859f-11e9-2ea1-df7d4e7c3537" +version = "0.4.6" + +[[deps.Oceananigans]] +deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "865afaee507b963d35c4df498af9f51c487a1198" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.107.3" + + [deps.Oceananigans.extensions] + OceananigansAMDGPUExt = ["AMDGPU", "AbstractFFTs"] + OceananigansCUDAExt = ["CUDA", "GPUArrays", "GPUArraysCore"] + OceananigansEnzymeExt = "Enzyme" + OceananigansMakieExt = "Makie" + OceananigansMetalExt = "Metal" + OceananigansNCDatasetsExt = "NCDatasets" + OceananigansOneAPIExt = "oneAPI" + OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase", "AbstractFFTs"] + OceananigansXESMFExt = ["XESMF"] + + [deps.Oceananigans.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + GPUArrays = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" + Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" + XESMF = "2e0b0046-e7a1-486f-88de-807ee8ffabe5" + oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" + +[[deps.OffsetArrays]] +git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.17.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.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] +git-tree-sha1 = "6d6c0ca4824268c1a7dca1f4721c535ac63d9074" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.11+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "NetworkOptions", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "1d1aaa7d449b58415f97d2839c318b70ffb525a0" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.6.1" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.4+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "e4cff168707d441cd6bf3ff7e4832bdf34278e4a" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.37" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.ParallelTestRunner]] +deps = ["Dates", "IOCapture", "Malt", "Printf", "Random", "Scratch", "Serialization", "Statistics", "Test"] +git-tree-sha1 = "1b6dd742aa3598dbca6bc2cc20a65c9819c1f42f" +uuid = "d3525ed8-44d0-4b2c-a655-542cee43accc" +version = "2.6.0" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pidfile]] +deps = ["FileWatching", "Test"] +git-tree-sha1 = "2d8aaf8ee10df53d0dfb9b8ee44ae7c04ced2b03" +uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307" +version = "1.3.0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.1" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[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 = "645bed98cd47f72f67316fd42fc47dee771aefcd" +uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" +version = "0.2.2" + +[[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 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "8b770b60760d4451834fe79dd483e318eee709c4" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.2" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "624de6279ab7d94fc9f672f0068107eb6619732c" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "3.3.2" + + [deps.PrettyTables.extensions] + PrettyTablesTypstryExt = "Typstry" + + [deps.PrettyTables.weakdeps] + Typstry = "f0ed7684-a786-439e-b1e3-3b82803b501e" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "25cdd1d20cd005b52fc12cb6be3f75faaf59bb9b" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.7" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "fbb92c6c56b34e1a2c4c36058f68f332bec840e7" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.11.0" + +[[deps.ProtoBuf]] +deps = ["BufferedStreams", "EnumX", "TOML"] +git-tree-sha1 = "da18083a52d9d57bbe6dadaacad39731e5f7be39" +uuid = "3349acd9-ac6a-5e09-bcdb-63829b23a429" +version = "1.3.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "4fbbafbc6251b883f4d2705356f3641f3652a7fe" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.4.0" + +[[deps.PythonCall]] +deps = ["CondaPkg", "Dates", "Libdl", "MacroTools", "Markdown", "Pkg", "Serialization", "Tables", "UnsafePointers"] +git-tree-sha1 = "982f3f017f08d31202574ef6bdcf8b3466430bea" +uuid = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" +version = "0.9.31" + + [deps.PythonCall.extensions] + CategoricalArraysExt = "CategoricalArrays" + PyCallExt = "PyCall" + + [deps.PythonCall.weakdeps] + CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597" + PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "5e8e8b0ab68215d7a2b14b9921a946fee794749e" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.3" +weakdeps = ["Enzyme"] + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "4d8c1b7c3329c1885b857abb50d08fa3f4d9e3c8" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.7" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.Random123]] +deps = ["Random", "RandomNumbers"] +git-tree-sha1 = "dbe5fd0b334694e905cb9fda73cd8554333c46e2" +uuid = "74087812-796a-5b5d-8853-05524746bad3" +version = "1.7.1" + +[[deps.RandomNumbers]] +deps = ["Random"] +git-tree-sha1 = "c6ec94d2aaba1ab2ff983052cf6a606ca5985902" +uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" +version = "1.6.0" + +[[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.Reactant]] +deps = ["Adapt", "BFloat16s", "CEnum", "Crayons", "Downloads", "EnumX", "Enzyme", "EnzymeCore", "FileWatching", "Functors", "GPUArraysCore", "GPUCompiler", "HTTP", "JSON", "LLVM", "LLVMOpenMP_jll", "Libdl", "LinearAlgebra", "OrderedCollections", "PrecompileTools", "Preferences", "PrettyTables", "ProtoBuf", "Random", "ReactantCore", "Reactant_jll", "ScopedValues", "Scratch", "Serialization", "Setfield", "Sockets", "StableRNGs", "StructUtils", "StyledStrings", "UUIDs", "p7zip_jll"] +git-tree-sha1 = "e02293894a505abfc68ef5e0743d6035d411c64f" +uuid = "3c362404-f566-11ee-1572-e11a4b42c853" +version = "0.2.254" + + [deps.Reactant.extensions] + ReactantAbstractFFTsExt = "AbstractFFTs" + ReactantArrayInterfaceExt = "ArrayInterface" + ReactantCUDAExt = ["CUDA", "Enzyme", "GPUCompiler", "KernelAbstractions", "LLVM", "Printf"] + ReactantDLFP8TypesExt = "DLFP8Types" + ReactantDatesExt = "Dates" + ReactantFFTWExt = ["FFTW", "AbstractFFTs", "LinearAlgebra"] + ReactantFillArraysExt = "FillArrays" + ReactantFloat8sExt = "Float8s" + ReactantKernelAbstractionsExt = "KernelAbstractions" + ReactantLogExpFunctionsExt = ["IrrationalConstants", "LogExpFunctions"] + ReactantMCMCDiagnosticToolsExt = ["MCMCDiagnosticTools", "Statistics"] + ReactantMPIExt = "MPI" + ReactantNNlibExt = ["NNlib", "Statistics"] + ReactantNPZExt = "NPZ" + ReactantOffsetArraysExt = "OffsetArrays" + ReactantOneHotArraysExt = "OneHotArrays" + ReactantPythonCallExt = "PythonCall" + ReactantRandom123Ext = "Random123" + ReactantSparseArraysExt = "SparseArrays" + ReactantSpecialFunctionsExt = "SpecialFunctions" + ReactantStaticArraysExt = "StaticArrays" + ReactantStatisticsExt = "Statistics" + ReactantStructArraysExt = "StructArrays" + ReactantYaoBlocksExt = "YaoBlocks" + ReactantZygoteExt = "Zygote" + + [deps.Reactant.weakdeps] + AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c" + ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + DLFP8Types = "f4c16678-4a16-415b-82ef-ed337c5d6c7c" + Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" + Float8s = "81dfefd7-55b0-40c6-a251-db853704e186" + IrrationalConstants = "92d709cd-6900-40b7-9082-c6be49f344b6" + KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" + LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" + MCMCDiagnosticTools = "be115224-59cd-429b-ad48-344e309966f0" + MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" + NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" + NPZ = "15e1cf62-19b3-5cfa-8e77-841668bca605" + OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" + OneHotArrays = "0b1bfda6-eb8a-41d2-88d8-f5af5cad476f" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" + Random123 = "74087812-796a-5b5d-8853-05524746bad3" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + YaoBlocks = "418bc28f-b43b-5e0b-a6e7-61bbc1a2c1df" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.ReactantCore]] +deps = ["ExpressionExplorer", "MacroTools"] +git-tree-sha1 = "5b9e0fe7fb2cf3794fd96ac32bf2732aa4bb9776" +uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" +version = "0.1.19" + +[[deps.Reactant_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "2749c35cb1bcc588ad71a50acf19108b9c6e47ed" +uuid = "0192cb87-2b54-54ad-80e0-3be72ad8a3c0" +version = "0.0.371+0" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[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 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.RingGrids]] +deps = ["Adapt", "Artifacts", "DocStringExtensions", "FastGaussQuadrature", "GPUArrays", "KernelAbstractions", "LinearAlgebra", "Pkg", "Printf", "SpeedyWeatherInternals", "Statistics"] +git-tree-sha1 = "fc7e92d38be29d68df9af3d97d2f1d3a7e8fcab4" +uuid = "d1845624-ad4f-453b-8ff4-a8db365bf3a7" +version = "0.1.3" + + [deps.RingGrids.extensions] + RingGridsFiniteDifferencesExt = "FiniteDifferences" + RingGridsGeoMakieExt = "GeoMakie" + RingGridsMakieExt = "Makie" + RingGridsNCDatasetsExt = "NCDatasets" + + [deps.RingGrids.weakdeps] + FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" + GeoMakie = "db073c08-6b98-4ee5-b6a4-5efafb3259c6" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "5b3d50eb374cea306873b371d3f8d3915a018f0b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.9.0" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.RootSolvers]] +deps = ["ForwardDiff", "Printf"] +git-tree-sha1 = "3b6c0089c3dc3d5780786d5007e976fe9d1b7887" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "1.0.2" + +[[deps.Roots]] +deps = ["Accessors", "CommonSolve", "Printf"] +git-tree-sha1 = "3eff988b9bd09543783e2e051b0a1eef11f65c2d" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.3.0" + + [deps.Roots.extensions] + RootsChainRulesCoreExt = "ChainRulesCore" + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + RootsUnitfulExt = "Unitful" + + [deps.Roots.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" + SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" + SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.1" + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + + [deps.Rotations.weakdeps] + RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" + +[[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 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.43" + +[[deps.SciMLPublic]] +git-tree-sha1 = "0ba076dbdce87ba230fff48ca9bca62e1f345c9b" +uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" +version = "1.0.1" + +[[deps.ScopedValues]] +deps = ["HashArrayMappedTries", "Logging"] +git-tree-sha1 = "ac4b837d89a58c848e85e698e2a2514e9d59d8f6" +uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" +version = "1.6.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.SeawaterPolynomials]] +git-tree-sha1 = "e2671e9abe2a2faa51dcecd9d911522931c16012" +uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" +version = "0.3.10" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "ebe7e59b37c400f694f52b58c93d26201387da70" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.9" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "c5391c6ace3bc430ca630251d02ea9687169ca68" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.2" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +version = "1.11.0" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "2700b235561b0335d5bef7097a111dc513b8655e" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.7.2" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.SpeedyTransforms]] +deps = ["AbstractFFTs", "Adapt", "AssociatedLegendrePolynomials", "Atomix", "DocStringExtensions", "FFTW", "FastGaussQuadrature", "GPUArrays", "GenericFFT", "KernelAbstractions", "LinearAlgebra", "LowerTriangularArrays", "Primes", "Printf", "RingGrids", "SpeedyWeatherInternals", "Statistics"] +git-tree-sha1 = "0960dcee70cd2eb5d6858cc63cd91e1419f8fe72" +uuid = "ed023a3f-7a3c-42dd-bab6-68c21c8c3105" +version = "0.1.1" +weakdeps = ["CUDA", "Enzyme"] + + [deps.SpeedyTransforms.extensions] + SpeedyTransformsCUDAExt = "CUDA" + SpeedyTransformsEnzymeExt = "Enzyme" + +[[deps.SpeedyWeather]] +deps = ["AbstractFFTs", "Adapt", "AssociatedLegendrePolynomials", "Atomix", "BitInformation", "CodecZlib", "ComponentArrays", "Dates", "DocStringExtensions", "DomainSets", "FFTW", "FastGaussQuadrature", "GPUArrays", "GenericFFT", "JLD2", "KernelAbstractions", "LinearAlgebra", "LowerTriangularArrays", "NCDatasets", "Primes", "Printf", "ProgressMeter", "Random", "RingGrids", "SpeedyTransforms", "SpeedyWeatherInternals", "Statistics", "TOML"] +git-tree-sha1 = "f59944897672d7fdc8bef0d47f7ec2d1d28793bf" +uuid = "9e226e20-d153-4fed-8a5b-493def4f21a9" +version = "0.17.4" + + [deps.SpeedyWeather.extensions] + SpeedyWeatherEnzymeExt = "Enzyme" + SpeedyWeatherFiniteDifferencesExt = "FiniteDifferences" + SpeedyWeatherGeoMakieExt = "GeoMakie" + SpeedyWeatherUnicodePlotsExt = "UnicodePlots" + + [deps.SpeedyWeather.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" + GeoMakie = "db073c08-6b98-4ee5-b6a4-5efafb3259c6" + UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" + +[[deps.SpeedyWeatherInternals]] +deps = ["ComponentArrays", "ConstructionBase", "Dates", "DocStringExtensions", "DomainSets", "KernelAbstractions", "MacroTools", "ModelParameters"] +git-tree-sha1 = "19ae520aff10b5b94ff06d11cb861c92e9466add" +uuid = "34489162-d270-4603-8b96-37b04f830d73" +version = "0.1.3" + + [deps.SpeedyWeatherInternals.extensions] + SpeedyWeatherInternalsAMDGPUExt = "AMDGPU" + SpeedyWeatherInternalsCUDAExt = "CUDA" + SpeedyWeatherInternalsJLArraysExt = "JLArrays" + SpeedyWeatherInternalsMetalExt = "Metal" + + [deps.SpeedyWeatherInternals.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "4f96c596b8c8258cc7d3b19797854d368f243ddc" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.4" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "be1cf4eb0ac528d96f5115b4ed80c26a8d8ae621" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.2" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] +git-tree-sha1 = "49440414711eddc7227724ae6e570c7d5559a086" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.3.1" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "SciMLPublic", "Static"] +git-tree-sha1 = "aa1ea41b3d45ac449d10477f65e2b40e3197a0d2" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.9.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "246a8bb2e6667f832eea063c3a56aef96429a3db" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.18" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "6ab403037779dae8c514bad259f32a447262455a" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.4" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "178ed29fd5b2a2cfc3bd31c13375ae925623ff36" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.8.0" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "aceda6f4e598d331548e04cc6b2124a6148138e3" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.10" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "91f091a8716a6bb38417a6e6f274602a19aaa685" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.2" +weakdeps = ["ChainRulesCore", "InverseFunctions"] + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "d05693d339e37d6ab134c5ab53c29fce5ee5d7d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.4.4" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "ad8002667372439f2e3611cfd14097e03fa4bccd" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.7.3" +weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = ["GPUArraysCore", "KernelAbstractions"] + StructArraysLinearAlgebraExt = "LinearAlgebra" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.StructIO]] +git-tree-sha1 = "c581be48ae1cbf83e899b14c07a807e1787512cc" +uuid = "53d494c1-5632-5724-8f4c-31dff12d585f" +version = "0.3.1" + +[[deps.StructUtils]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "86f5831495301b2a1387476cb30f86af7ab99194" +uuid = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42" +version = "2.8.0" + + [deps.StructUtils.extensions] + StructUtilsMeasurementsExt = ["Measurements"] + StructUtilsStaticArraysCoreExt = ["StaticArraysCore"] + StructUtilsTablesExt = ["Tables"] + + [deps.StructUtils.weakdeps] + Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.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.8.3+2" + +[[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 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.12.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TaylorSeries]] +deps = ["LinearAlgebra", "Markdown", "SparseArrays"] +git-tree-sha1 = "4a5ddc4036946d3a7900b5776b0872e36d848a29" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.20.10" + + [deps.TaylorSeries.extensions] + TaylorSeriesIAExt = "IntervalArithmetic" + TaylorSeriesJLD2Ext = "JLD2" + TaylorSeriesRATExt = "RecursiveArrayTools" + TaylorSeriesSAExt = "StaticArrays" + + [deps.TaylorSeries.weakdeps] + IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" + JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" + RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[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" +version = "1.11.0" + +[[deps.Thermodynamics]] +deps = ["ForwardDiff", "Random", "RootSolvers"] +git-tree-sha1 = "9f39fc85c78edf969ead08f88a1a0068562aa543" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.15.9" + + [deps.Thermodynamics.extensions] + CreateParametersExt = "ClimaParams" + + [deps.Thermodynamics.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.ThreadingUtilities]] +deps = ["ManualMemory"] +git-tree-sha1 = "d969183d3d244b6c33796b5ed01ab97328f2db85" +uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" +version = "0.5.5" + +[[deps.TiledIteration]] +deps = ["OffsetArrays", "StaticArrayInterface"] +git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" +uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" +version = "0.5.0" + +[[deps.Tracy]] +deps = ["ExprTools", "LibTracyClient_jll", "Libdl"] +git-tree-sha1 = "73e3ff50fd3990874c59fef0f35d10644a1487bc" +uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" +version = "0.1.6" + + [deps.Tracy.extensions] + TracyProfilerExt = "TracyProfiler_jll" + + [deps.Tracy.weakdeps] + TracyProfiler_jll = "0c351ed6-8a68-550e-8b79-de6f926da83c" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "57e1b2c9de4bd6f40ecb9de4ac1797b81970d008" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.28.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + LatexifyExt = ["Latexify", "LaTeXStrings"] + NaNMathExt = "NaNMath" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" + Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" + NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "0f30765c32d66d58e41f4cb5624d4fc8a82ec13b" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.3.1" +weakdeps = ["LLVM"] + + [deps.UnsafeAtomics.extensions] + UnsafeAtomicsLLVM = ["LLVM"] + +[[deps.UnsafePointers]] +git-tree-sha1 = "c81331b3b2e60a982be57c046ec91f599ede674a" +uuid = "e17b2a0c-0bdf-430a-bd0c-3a23cae4ff39" +version = "1.0.0" + +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "d1d9a935a26c475ebffd54e9c7ad11627c43ea85" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.72" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "248a7031b3da79a127f14e5dc5f417e26f9f6db7" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.1.0" + +[[deps.WorldOceanAtlasTools]] +deps = ["DataDeps", "DataFrames", "Downloads", "Match", "NCDatasets", "NearestNeighbors", "OceanGrids", "Statistics", "StatsBase", "Unitful"] +git-tree-sha1 = "134d30d8a0f03a1deb57767a478e230edbfa627f" +uuid = "04f20302-f1b9-11e8-29d9-7d841cb0a64a" +version = "0.6.4" + +[[deps.XESMF]] +deps = ["CondaPkg", "LinearAlgebra", "PythonCall", "SparseArrays"] +git-tree-sha1 = "f572a29a8ddd0ec974f909493ec6b9ca7f7e1c1d" +uuid = "2e0b0046-e7a1-486f-88de-807ee8ffabe5" +version = "0.1.6" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "80d3930c6347cfce7ccf96bd3bafdf079d9c0390" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.13.9+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b29c22e245d092b8b4e8d3c09ad7baa586d9f573" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.3+0" + +[[deps.Xorg_libpciaccess_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "4909eb8f1cbf6bd4b1c30dd18b2ead9019ef2fad" +uuid = "a65dc6b1-eb27-53a1-bb3e-dea574b5389e" +version = "0.18.1+0" + +[[deps.ZipFile]] +deps = ["Libdl", "Printf", "Zlib_jll"] +git-tree-sha1 = "f492b7fe1698e623024e873244f10d89c95c340a" +uuid = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea" +version = "0.10.1" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.aws_c_auth_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_cal_jll", "aws_c_http_jll", "aws_c_sdkutils_jll"] +git-tree-sha1 = "8cab83c96af80a1be968251ce1a0548a7545484d" +uuid = "2b3700d1-4306-52e2-a478-c162f0c514be" +version = "0.9.6+0" + +[[deps.aws_c_cal_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_common_jll"] +git-tree-sha1 = "22c0f42f4a1f0dc5dcfa8fd267c4ac407c455e7a" +uuid = "70f11efc-bab2-57f1-b0f3-22aad4e67c4b" +version = "0.9.13+0" + +[[deps.aws_c_common_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a759cb9bf456ad792cc7898a81ae333cce9ef02a" +uuid = "73048d1d-b8c4-5092-a58d-866c5e8d1e50" +version = "0.12.6+0" + +[[deps.aws_c_compression_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_common_jll"] +git-tree-sha1 = "7910c72f45f44afd297c39fe43b99c56d5ed22ec" +uuid = "73a04cd5-f3d7-5bac-9290-e8adb709f224" +version = "0.3.2+0" + +[[deps.aws_c_http_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_compression_jll", "aws_c_io_jll"] +git-tree-sha1 = "e358d5a001ef7afbd4f8c5225322512819cda2f2" +uuid = "3254fc65-9028-534d-aa9d-d76d128babc6" +version = "0.10.13+0" + +[[deps.aws_c_io_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_cal_jll", "aws_c_common_jll", "s2n_tls_jll"] +git-tree-sha1 = "7e481d474b2087ee8bbf55b81bf9119f21e396d9" +uuid = "13c41daa-f319-5298-b5eb-5754e0170d52" +version = "0.26.3+0" + +[[deps.aws_c_s3_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_auth_jll", "aws_c_common_jll", "aws_c_http_jll", "aws_checksums_jll", "s2n_tls_jll"] +git-tree-sha1 = "3e9917ab25114feba657e71be41cad068b9f6595" +uuid = "bd1f34fb-993f-5903-a121-aaf302eed6d4" +version = "0.11.5+0" + +[[deps.aws_c_sdkutils_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_common_jll"] +git-tree-sha1 = "c43dfba2c1ab9ea9f02f2c80e86fa16f6460244e" +uuid = "1282aa60-004d-510b-9f52-12498d409daa" +version = "0.2.4+1" + +[[deps.aws_checksums_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_common_jll"] +git-tree-sha1 = "2570c8e23f4771a087b12a47edcaaa670ac05a01" +uuid = "b2a88e68-78e7-5e94-8c20-c02986ec140e" +version = "0.2.10+0" + +[[deps.demumble_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6498e3581023f8e530f34760d18f75a69e3a4ea8" +uuid = "1e29f10c-031c-5a83-9565-69cddfc27673" +version = "1.3.0+0" + +[[deps.dlfcn_win32_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e141d67ffe550eadfb5af1bdbdaf138031e4805f" +uuid = "c4b69c83-5512-53e3-94e6-de98773c479f" +version = "1.4.2+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1411bc34c180946d3cef591de1384012afa6edee" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.1.6+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libzip_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "OpenSSL_jll", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "86addc139bca85fdf9e7741e10977c45785727b7" +uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" +version = "1.11.3+0" + +[[deps.micromamba_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "717df6f6892af4ee13279a73aa58474e58a88667" +uuid = "f8abcde7-e9b7-5caa-b8af-a437887ae8e4" +version = "2.3.1+0" + +[[deps.mpif_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIABI_jll", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML"] +git-tree-sha1 = "a8083ee0737c243c8f40a4ba86a0956997facb73" +uuid = "9aeb927a-4695-514f-a259-621a69f20ec0" +version = "0.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "1350188a69a6e46f799d3945beef36435ed7262f" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2022.0.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.7.0+0" + +[[deps.pixi_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "f349584316617063160a947a82638f7611a8ef0f" +uuid = "4d7b5844-a134-5dcd-ac86-c8f19cd51bed" +version = "0.41.3+0" + +[[deps.s2n_tls_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6b99e06a3863de281da6ff0e193a5b3706349054" +uuid = "cddc5d3d-934d-5d3a-9747-62fc12ea3f48" +version = "1.7.2+0" diff --git a/test/test_checkpointer.jl b/test/test_checkpointer.jl index 3d058af42..ce5eb2148 100644 --- a/test/test_checkpointer.jl +++ b/test/test_checkpointer.jl @@ -30,8 +30,9 @@ using Oceananigans.OutputWriters: Checkpointer backend = JRA55NetCDFBackend(4) atmosphere = JRA55PrescribedAtmosphere(arch; backend) land = JRA55PrescribedLand(arch; backend) + radiation = JRA55PrescribedRadiation(arch; backend) - return OceanSeaIceModel(ocean, sea_ice; atmosphere, land) + return OceanSeaIceModel(ocean, sea_ice; atmosphere, land, radiation) end # Reference run: 3 iterations, then continue to 6 diff --git a/test/test_diagnostics_2.jl b/test/test_diagnostics_2.jl index 59e6d1c68..19a7d3efd 100644 --- a/test/test_diagnostics_2.jl +++ b/test/test_diagnostics_2.jl @@ -23,7 +23,7 @@ for arch in test_architectures sea_ice = sea_ice_simulation(grid, ocean) atmosphere = PrescribedAtmosphere(grid, [0.0]) - esm = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation = Radiation()) + esm = OceanSeaIceModel(ocean, sea_ice; atmosphere) T_flux = ocean.model.tracers.T.boundary_conditions.top.condition S_flux = ocean.model.tracers.S.boundary_conditions.top.condition diff --git a/test/test_ecco_atmosphere.jl b/test/test_ecco_atmosphere.jl index 70ac2b8ca..12d120930 100644 --- a/test/test_ecco_atmosphere.jl +++ b/test/test_ecco_atmosphere.jl @@ -2,8 +2,9 @@ include("runtests_setup.jl") include("download_utils.jl") using Statistics: median -using NumericalEarth.Atmospheres: PrescribedAtmosphere, TwoBandDownwellingRadiation -using NumericalEarth.ECCO: ECCOPrescribedAtmosphere, ECCO4Monthly +using NumericalEarth.Atmospheres: PrescribedAtmosphere +using NumericalEarth.Radiations: PrescribedRadiation +using NumericalEarth.ECCO: ECCOPrescribedAtmosphere, ECCOPrescribedRadiation, ECCO4Monthly using NumericalEarth.DataWrangling: download_dataset, metadata_path, higher_bound # Pre-download ECCO4Monthly atmospheric forcing variables through the artifacts @@ -34,7 +35,14 @@ end end_date, time_indices_in_memory = 2) + radiation = ECCOPrescribedRadiation(arch; + dataset, + start_date, + end_date, + time_indices_in_memory = 2) + @test atmosphere isa PrescribedAtmosphere + @test radiation isa PrescribedRadiation # Test that all expected fields are present @test haskey(atmosphere.velocities, :u) @@ -42,12 +50,11 @@ end @test haskey(atmosphere.tracers, :T) @test haskey(atmosphere.tracers, :q) @test !isnothing(atmosphere.pressure) - @test !isnothing(atmosphere.downwelling_radiation) @test haskey(atmosphere.freshwater_flux, :rain) # Test downwelling radiation components - ℐꜜˢʷ = atmosphere.downwelling_radiation.shortwave - ℐꜜˡʷ = atmosphere.downwelling_radiation.longwave + ℐꜜˢʷ = radiation.downwelling_shortwave + ℐꜜˡʷ = radiation.downwelling_longwave @test ℐꜜˢʷ isa FieldTimeSeries @test ℐꜜˡʷ isa FieldTimeSeries diff --git a/test/test_ocean_only_model.jl b/test/test_ocean_only_model.jl index 6254f9e63..09c5e4c4f 100644 --- a/test/test_ocean_only_model.jl +++ b/test/test_ocean_only_model.jl @@ -19,7 +19,7 @@ using Oceananigans.OrthogonalSphericalShellGrids add_callback!(ocean, pushdata) backend = JRA55NetCDFBackend(4) atmosphere = JRA55PrescribedAtmosphere(arch; backend) - radiation = Radiation(arch) + radiation = JRA55PrescribedRadiation(arch; backend) coupled_model = OceanOnlyModel(ocean; atmosphere, radiation) Δt = 60 for n = 1:3 @@ -50,7 +50,7 @@ using Oceananigans.OrthogonalSphericalShellGrids backend = JRA55NetCDFBackend(4) atmosphere = JRA55PrescribedAtmosphere(arch; backend) - radiation = Radiation(arch) + radiation = JRA55PrescribedRadiation(arch; backend) # Fluxes are computed when the model is constructed, so we just test that this works. @test begin diff --git a/test/test_ocean_sea_ice_model.jl b/test/test_ocean_sea_ice_model.jl index 4188435ec..64ae969db 100644 --- a/test/test_ocean_sea_ice_model.jl +++ b/test/test_ocean_sea_ice_model.jl @@ -59,7 +59,7 @@ using ClimaSeaIce.Rheologies backend = JRA55NetCDFBackend(4) atmosphere = JRA55PrescribedAtmosphere(arch; backend) - radiation = Radiation(arch) + radiation = JRA55PrescribedRadiation(arch; backend) # Fluxes are computed when the model is constructed, so we just test that this works. # And that we can time step with sea ice diff --git a/test/test_ospapa.jl b/test/test_ospapa.jl index 81b2cccf9..15a1af718 100644 --- a/test/test_ospapa.jl +++ b/test/test_ospapa.jl @@ -2,6 +2,7 @@ include("runtests_setup.jl") using NumericalEarth.OSPapa using NumericalEarth.Atmospheres: PrescribedAtmosphere +using NumericalEarth.Radiations: PrescribedRadiation using Oceananigans.BoundaryConditions: BoundaryCondition, Flux, getbc using Oceananigans.Units: minutes using CUDA: @allowscalar @@ -18,7 +19,12 @@ const OSPAPA_TEST_END = DateTime(2012, 10, 3) start_date = OSPAPA_TEST_START, end_date = OSPAPA_TEST_END) + radiation = OSPapaPrescribedRadiation(arch; + start_date = OSPAPA_TEST_START, + end_date = OSPAPA_TEST_END) + @test atmosphere isa PrescribedAtmosphere + @test radiation isa PrescribedRadiation # All expected fields are present @test haskey(atmosphere.velocities, :u) @@ -26,12 +32,11 @@ const OSPAPA_TEST_END = DateTime(2012, 10, 3) @test haskey(atmosphere.tracers, :T) @test haskey(atmosphere.tracers, :q) @test !isnothing(atmosphere.pressure) - @test !isnothing(atmosphere.downwelling_radiation) @test haskey(atmosphere.freshwater_flux, :rain) # Radiation sanity checks - ℐꜜˢʷ = atmosphere.downwelling_radiation.shortwave - ℐꜜˡʷ = atmosphere.downwelling_radiation.longwave + ℐꜜˢʷ = radiation.downwelling_shortwave + ℐꜜˡʷ = radiation.downwelling_longwave @allowscalar begin sw_data = interior(ℐꜜˢʷ) @@ -216,8 +221,11 @@ end atmosphere = OSPapaPrescribedAtmosphere(arch; start_date = OSPAPA_TEST_START, end_date = OSPAPA_TEST_END) + radiation = OSPapaPrescribedRadiation(arch; + start_date = OSPAPA_TEST_START, + end_date = OSPAPA_TEST_END) - coupled_model = OceanOnlyModel(ocean; atmosphere, radiation=Radiation(arch)) + coupled_model = OceanOnlyModel(ocean; atmosphere, radiation) simulation = Simulation(coupled_model; Δt=ocean.Δt, stop_iteration=2) @test begin diff --git a/test/test_radiations.jl b/test/test_radiations.jl new file mode 100644 index 000000000..714dbc352 --- /dev/null +++ b/test/test_radiations.jl @@ -0,0 +1,82 @@ +include("runtests_setup.jl") + +using NumericalEarth.Radiations: PrescribedRadiation, + SurfaceRadiationProperties, + InterfaceRadiationFlux + +@testset "PrescribedRadiation construction" begin + for arch in test_architectures + A = typeof(arch) + + # Form B: grid-only constructor (zero downwelling, surface properties only) + @info "Testing PrescribedRadiation(grid) on $A..." + grid = RectilinearGrid(arch, size = 10, z = (-100, 0), topology = (Flat, Flat, Bounded)) + rad = PrescribedRadiation(grid) + @test rad isa PrescribedRadiation + @test rad.surface_properties isa NamedTuple + @test haskey(rad.surface_properties, :ocean) + @test haskey(rad.surface_properties, :sea_ice) + @test rad.surface_properties.ocean isa SurfaceRadiationProperties + @test rad.surface_properties.ocean.albedo == 0.05 + @test rad.surface_properties.ocean.emissivity == 0.97 + @test rad.surface_properties.sea_ice.albedo == 0.7 + @test rad.surface_properties.sea_ice.emissivity == 1.0 + @test rad.stefan_boltzmann_constant ≈ 5.67e-8 + @test isnothing(rad.interface_fluxes) + + # Surfaces can be omitted + @info "Testing PrescribedRadiation(grid; sea_ice_surface=nothing) on $A..." + rad_ocean_only = PrescribedRadiation(grid; sea_ice_surface = nothing) + @test haskey(rad_ocean_only.surface_properties, :ocean) + @test !haskey(rad_ocean_only.surface_properties, :sea_ice) + + # Custom surface properties + custom_ocean = SurfaceRadiationProperties(0.1, 0.95) + rad_custom = PrescribedRadiation(grid; ocean_surface = custom_ocean) + @test rad_custom.surface_properties.ocean.albedo == 0.1 + @test rad_custom.surface_properties.ocean.emissivity == 0.95 + + # time_step! works + @info "Testing time_step!(::PrescribedRadiation) on $A..." + rad2 = PrescribedRadiation(grid) + time_step!(rad2, 60.0) + @test rad2.clock.time == 60.0 + end +end + +@testset "PrescribedRadiation paired with model" begin + for arch in test_architectures + A = typeof(arch) + + @info "Testing OceanOnlyModel with PrescribedRadiation on $A..." + + grid = RectilinearGrid(arch, size = 10, z = (-100, 0), topology = (Flat, Flat, Bounded)) + ocean = ocean_simulation(grid) + radiation = PrescribedRadiation(grid) + model = OceanOnlyModel(ocean; radiation) + + # interface_fluxes are allocated for present surfaces (ocean + sea_ice + # via FreezingLimitedOceanTemperature). + @test !isnothing(model.radiation.interface_fluxes) + @test model.radiation.interface_fluxes.ocean isa InterfaceRadiationFlux + @test model.radiation.interface_fluxes.sea_ice isa InterfaceRadiationFlux + + time_step!(model, 60) + @test iteration(model) == 1 + end +end + +@testset "JRA55PrescribedRadiation" begin + for arch in test_architectures + A = typeof(arch) + @info "Testing JRA55PrescribedRadiation on $A..." + + backend = JRA55NetCDFBackend(2) + radiation = JRA55PrescribedRadiation(arch; backend) + + @test radiation isa PrescribedRadiation + @test radiation.downwelling_shortwave isa FieldTimeSeries + @test radiation.downwelling_longwave isa FieldTimeSeries + @test radiation.surface_properties.ocean isa SurfaceRadiationProperties + end +end diff --git a/test/test_reactant.jl b/test/test_reactant.jl index c37963121..fc32d8dff 100644 --- a/test/test_reactant.jl +++ b/test/test_reactant.jl @@ -36,8 +36,7 @@ end atmos_times = range(0, 360Oceananigans.Units.days, length=10) atmosphere = PrescribedAtmosphere(atmos_grid, atmos_times) - radiation = Radiation(arch) - coupled_model = OceanOnlyModel(ocean; atmosphere, radiation) + coupled_model = OceanOnlyModel(ocean; atmosphere) # Test that Reactant does _not_ initialize in the constructor for EarthSystemModel exchanger = coupled_model.interfaces.exchanger.atmosphere diff --git a/test/test_sea_ice_ocean_heat_fluxes.jl b/test/test_sea_ice_ocean_heat_fluxes.jl index 7506d3d78..46aafd54c 100644 --- a/test/test_sea_ice_ocean_heat_fluxes.jl +++ b/test/test_sea_ice_ocean_heat_fluxes.jl @@ -201,7 +201,7 @@ end backend = JRA55NetCDFBackend(4) atmosphere = JRA55PrescribedAtmosphere(arch; backend) - radiation = Radiation(arch) + radiation = JRA55PrescribedRadiation(arch; backend) for sea_ice_ocean_heat_flux in [IceBathHeatFlux(), ThreeEquationHeatFlux()] @testset "Salt flux with $(nameof(typeof(sea_ice_ocean_heat_flux)))" begin @@ -259,7 +259,7 @@ end backend = JRA55NetCDFBackend(4) atmosphere = JRA55PrescribedAtmosphere(arch; backend) - radiation = Radiation(arch) + radiation = JRA55PrescribedRadiation(arch; backend) for sea_ice_ocean_heat_flux in [IceBathHeatFlux(), ThreeEquationHeatFlux()] @testset "Flux magnitude with $(nameof(typeof(sea_ice_ocean_heat_flux)))" begin @@ -403,7 +403,7 @@ end backend = JRA55NetCDFBackend(4) atmosphere = JRA55PrescribedAtmosphere(arch; backend) - radiation = Radiation(arch) + radiation = JRA55PrescribedRadiation(arch; backend) for sea_ice_ocean_heat_flux in [IceBathHeatFlux(), ThreeEquationHeatFlux()] @testset "Frazil with $(nameof(typeof(sea_ice_ocean_heat_flux)))" begin @@ -454,7 +454,7 @@ end backend = JRA55NetCDFBackend(4) atmosphere = JRA55PrescribedAtmosphere(arch; backend) - radiation = Radiation(arch) + radiation = JRA55PrescribedRadiation(arch; backend) # Test with ThreeEquationHeatFlux (default) @test begin diff --git a/test/test_speedy_coupling.jl b/test/test_speedy_coupling.jl index 59cf8c58b..a49840be8 100644 --- a/test/test_speedy_coupling.jl +++ b/test/test_speedy_coupling.jl @@ -15,8 +15,7 @@ Oceananigans.set!(ocean.model, T=EN4Metadatum(:temperature), S=EN4Metadatum(:sal atmos = NumericalEarth.atmosphere_simulation(spectral_grid) -radiation = Radiation(ocean_emissivity=0.0, sea_ice_emissivity=0.0) -earth_model = EarthSystemModel(atmos, ocean, default_sea_ice(); radiation) +earth_model = EarthSystemModel(atmos, ocean, default_sea_ice()) Qca = atmos.variables.parameterizations.ocean.sensible_heat_flux.data Mva = atmos.variables.parameterizations.ocean.surface_humidity_flux.data diff --git a/test/test_surface_fluxes.jl b/test/test_surface_fluxes.jl index 3ffdd7b60..f1061e018 100644 --- a/test/test_surface_fluxes.jl +++ b/test/test_surface_fluxes.jl @@ -75,15 +75,12 @@ end ρᵃᵗ = Thermodynamics.air_density(ℂᵃᵗ, Tᵃᵗ, pᵃᵗ, qᵃᵗ) ℰv = Thermodynamics.latent_heat_vapor(ℂᵃᵗ, Tᵃᵗ) - # No radiation equivalent - radiation = Radiation(ocean_emissivity=0, ocean_albedo=1) - - # turbulent fluxes that force a specific humidity at the ocean's surface + # No radiation: pass `radiation = nothing` to disable radiative + # contributions wholesale. for atmosphere_ocean_interface_temperature in (BulkTemperature(), SkinTemperature(DiffusiveFlux(1, 1e-2))) @info " Testing zero fluxes with $(atmosphere_ocean_interface_temperature)..." interfaces = ComponentInterfaces(atmosphere, ocean; - radiation, atmosphere_ocean_interface_specific_humidity, atmosphere_ocean_interface_temperature) @@ -246,7 +243,7 @@ end # Always cooling! fill!(atmosphere.tracers.T, 273.15 - 20) - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere) # Test that the temperature has snapped up to freezing @test minimum(ocean.model.tracers.T) == 0 @@ -286,7 +283,7 @@ end fill!(ocean.model.tracers.T, -2.0) # Test that we populate the sea-ice ocean stress - earth = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation=Radiation()) + earth = OceanSeaIceModel(ocean, sea_ice; atmosphere) τˣ = earth.interfaces.sea_ice_ocean_interface.fluxes.x_momentum τʸ = earth.interfaces.sea_ice_ocean_interface.fluxes.y_momentum From 8b7d23f61a2ea89f2928cf1aee3db38f55e80838 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 29 Apr 2026 18:01:54 -0600 Subject: [PATCH 03/13] Migrate examples, experiments, and docs to top-level radiation - examples/{idealized_single_column,global_climate,near_global_ocean, one_degree,single_column_os_papa,meridional_heat_transport_ecco, veros_ocean_forced,generate_surface_fluxes}.jl all use the new PrescribedRadiation / JRA55PrescribedRadiation / OSPapaPrescribedRadiation / ECCOPrescribedRadiation API. - experiments/{arctic,one_degree,coupled,flux_climatology}.jl migrated. - experiments/coupled passes a LatitudeDependentAlbedo through the new SurfaceRadiationProperties bundle. - docs/src/earth_system_model.md doctest output reflects the new 'radiation:' line in the EarthSystemModel show. - Fix FreezingLimitedEarthSystemModel and Single*FreezingLimited type aliases to use the new {R, A, L, I, O, F, C, Arch} type-parameter order. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/src/earth_system_model.md | 4 ++++ examples/generate_surface_fluxes.jl | 9 +++++---- examples/global_climate_simulation.jl | 7 ++++--- .../idealized_single_column_simulation.jl | 12 +++++++---- examples/meridional_heat_transport_ecco.jl | 6 +++--- examples/near_global_ocean_simulation.jl | 20 +++++-------------- examples/one_degree_simulation.jl | 2 +- examples/single_column_os_papa_simulation.jl | 10 +++++++--- examples/veros_ocean_forced_simulation.jl | 5 ++--- experiments/arctic_simulation.jl | 2 +- .../earth_system_coupled_simulation.jl | 7 +++++-- .../flux_climatology/flux_climatology.jl | 2 +- .../one_degree_simulation.jl | 5 +++-- .../freezing_limited_ocean_temperature.jl | 6 +++--- 14 files changed, 52 insertions(+), 45 deletions(-) diff --git a/docs/src/earth_system_model.md b/docs/src/earth_system_model.md index f50e40868..8086b01b2 100644 --- a/docs/src/earth_system_model.md +++ b/docs/src/earth_system_model.md @@ -23,6 +23,7 @@ model = OceanOnlyModel(ocean) # output EarthSystemModel{CPU}(time = 0 seconds, iteration = 0) +├── radiation: Nothing ├── atmosphere: Nothing ├── land: Nothing ├── sea_ice: FreezingLimitedOceanTemperature{ClimaSeaIce.SeaIceThermodynamics.LinearLiquidus{Float64}} @@ -91,6 +92,7 @@ model = OceanSeaIceModel(ocean, sea_ice) # output EarthSystemModel{CPU}(time = 0 seconds, iteration = 0) +├── radiation: Nothing ├── atmosphere: Nothing ├── land: Nothing ├── sea_ice: FreezingLimitedOceanTemperature{ClimaSeaIce.SeaIceThermodynamics.LinearLiquidus{Float64}} @@ -130,6 +132,7 @@ model = OceanOnlyModel(ocean; interfaces) # output EarthSystemModel{CPU}(time = 0 seconds, iteration = 0) +├── radiation: Nothing ├── atmosphere: Nothing ├── land: Nothing ├── sea_ice: FreezingLimitedOceanTemperature{ClimaSeaIce.SeaIceThermodynamics.LinearLiquidus{Float64}} @@ -148,6 +151,7 @@ model = OceanOnlyModel(ocean; interfaces) # output EarthSystemModel{CPU}(time = 0 seconds, iteration = 0) +├── radiation: Nothing ├── atmosphere: Nothing ├── land: Nothing ├── sea_ice: FreezingLimitedOceanTemperature{ClimaSeaIce.SeaIceThermodynamics.LinearLiquidus{Float64}} diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index 3043bef0f..1e09eab1a 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -62,11 +62,12 @@ S_metadata = ECCOMetadatum(:salinity; date=DateTime(1993, 1, 1)) set!(ocean.model; T=T_metadata, S=S_metadata) # Finally, we construct a coupled model, which will compute fluxes during construction. -# We omit `sea_ice` so the model is ocean-only, and use the default `Radiation()` that -# uses the two-band shortwave (visible and UV) + longwave (mid and far infrared) -# decomposition of the radiation spectrum. +# We omit `sea_ice` so the model is ocean-only, and pair the JRA55 atmosphere with a +# matching `JRA55PrescribedRadiation` that supplies downwelling shortwave and +# longwave radiation as well as ocean / sea-ice surface properties. -coupled_model = OceanOnlyModel(ocean; atmosphere, radiation=Radiation(eltype)) +radiation = JRA55PrescribedRadiation(; backend = JRA55NetCDFBackend(2)) +coupled_model = OceanOnlyModel(ocean; atmosphere, radiation) # Now that the surface fluxes are computed, we can extract and visualize them. # The turbulent fluxes are stored in `coupled_model.interfaces.atmosphere_ocean_interface.fluxes`. diff --git a/examples/global_climate_simulation.jl b/examples/global_climate_simulation.jl index 5a40eeac2..95a1e6593 100644 --- a/examples/global_climate_simulation.jl +++ b/examples/global_climate_simulation.jl @@ -98,10 +98,11 @@ nothing #hide nothing #hide # We build the complete coupled `earth_model` and the coupled simulation. -# Since radiation is idealized in this example, we set the emissivities to zero. +# SpeedyWeather drives the air-sea fluxes here, so we leave the top-level +# `radiation` component as `nothing` (radiatively decoupled) to avoid +# double-counting. -radiation = Radiation(ocean_emissivity=0.0, sea_ice_emissivity=0.0) -earth_model = EarthSystemModel(atmosphere, ocean, sea_ice; radiation) +earth_model = EarthSystemModel(atmosphere, ocean, sea_ice) # ## Building and running the simulation # diff --git a/examples/idealized_single_column_simulation.jl b/examples/idealized_single_column_simulation.jl index c6e4a498c..988258bcb 100644 --- a/examples/idealized_single_column_simulation.jl +++ b/examples/idealized_single_column_simulation.jl @@ -18,15 +18,19 @@ qᵃᵗ = 0.01 # specific humidity ℐꜜˢʷ = 400 # shortwave radiation (W m⁻², positive means heating right now) # Build the atmosphere -radiation = Radiation(ocean_albedo=0.1) atmosphere_grid = RectilinearGrid(size=(), topology=(Flat, Flat, Flat)) atmosphere_times = range(0, 1days, length=3) atmosphere = PrescribedAtmosphere(atmosphere_grid, atmosphere_times) +# Build the radiation component (lives on the same grid + times as the atmosphere +# in this single-column setup) and prescribe a constant shortwave forcing. +radiation = PrescribedRadiation(atmosphere_grid, atmosphere_times; + ocean_surface = SurfaceRadiationProperties(0.1, 0.97)) + parent(atmosphere.tracers.T) .= Tᵃᵗ # K parent(atmosphere.velocities.u) .= u₁₀ # m/s parent(atmosphere.tracers.q) .= qᵃᵗ # mass ratio -parent(atmosphere.downwelling_radiation.shortwave) .= ℐꜜˢʷ # W +parent(radiation.downwelling_shortwave) .= ℐꜜˢʷ # W # Build ocean model at rest with initial temperature stratification grid = RectilinearGrid(size=20, z=(-100, 0), topology=(Flat, Flat, Bounded)) @@ -40,8 +44,8 @@ Tᵢ(z) = T₀ + dTdz * z set!(ocean.model, T=Tᵢ, S=S₀) atmosphere_ocean_fluxes = SimilarityTheoryFluxes(stability_functions=nothing) -interfaces = NumericalEarth.EarthSystemModels.ComponentInterfaces(atmosphere, ocean; atmosphere_ocean_fluxes) -model = OceanOnlyModel(ocean; atmosphere, interfaces) +interfaces = NumericalEarth.EarthSystemModels.ComponentInterfaces(atmosphere, ocean; atmosphere_ocean_fluxes, radiation) +model = OceanOnlyModel(ocean; atmosphere, radiation, interfaces) 𝒬ᵛ = model.interfaces.atmosphere_ocean_interface.fluxes.latent_heat 𝒬ᵀ = model.interfaces.atmosphere_ocean_interface.fluxes.sensible_heat diff --git a/examples/meridional_heat_transport_ecco.jl b/examples/meridional_heat_transport_ecco.jl index 58b3e7849..30fba8392 100755 --- a/examples/meridional_heat_transport_ecco.jl +++ b/examples/meridional_heat_transport_ecco.jl @@ -42,9 +42,9 @@ ecco_sea_ice_concentration = Metadatum(:sea_ice_concentration; date, dataset) set!(ocean.model, T=ecco_temperature, S=ecco_salinity) set!(sea_ice.model, h=ecco_sea_ice_thickness, ℵ=ecco_sea_ice_concentration) -radiation = Radiation(arch) -atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(80), - include_rivers_and_icebergs = false) +jra55_backend = JRA55NetCDFBackend(80) +atmosphere = JRA55PrescribedAtmosphere(arch; backend=jra55_backend) +radiation = JRA55PrescribedRadiation(arch; backend=jra55_backend) esm = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) simulation = Simulation(esm; Δt=20minutes, stop_time=5*365days) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index f57a5e8e0..1ec9c3ce0 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -88,24 +88,14 @@ set!(ocean.model, T=Metadatum(:temperature, dataset=ECCO4Monthly()), # ### Prescribed atmosphere and radiation # -# Next we build a prescribed atmosphere state and radiation model, -# which will drive the ocean simulation. We use the default `Radiation` model, - -# 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. - -radiation = Radiation(arch) - -# The atmospheric data is prescribed using the JRA55 dataset. -# The JRA55 dataset provides atmospheric data such as temperature, humidity, and winds -# to calculate turbulent fluxes using bulk formulae, see [`InterfaceComputations`](@ref NumericalEarth.EarthSystemModels.InterfaceComputations). -# The number of snapshots that are loaded into memory is determined by -# the `backend`. Here, we load 41 snapshots at a time into memory. +# Next we build a prescribed atmosphere state and radiation component, +# which together drive the ocean simulation. The atmospheric data and +# downwelling shortwave / longwave radiation are both prescribed using JRA55. +# The number of snapshots loaded into memory is set by the backend. jra55_backend = JRA55NetCDFBackend(41) atmosphere = JRA55PrescribedAtmosphere(arch; backend=jra55_backend) +radiation = JRA55PrescribedRadiation(arch; backend=jra55_backend) land = JRA55PrescribedLand(arch; backend=jra55_backend) # ## The coupled simulation diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index a08bba029..b67ad3f40 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -95,9 +95,9 @@ set!(sea_ice.model, h=ecco_sea_ice_thickness, ℵ=ecco_sea_ice_concentration) # ### Atmospheric forcing # We force the simulation with a JRA55-do atmospheric reanalysis. -radiation = Radiation(arch) jra55_backend = JRA55NetCDFBackend(80) atmosphere = JRA55PrescribedAtmosphere(arch; backend=jra55_backend) +radiation = JRA55PrescribedRadiation(arch; backend=jra55_backend) land = JRA55PrescribedLand(arch; backend=jra55_backend) # ### Coupled simulation diff --git a/examples/single_column_os_papa_simulation.jl b/examples/single_column_os_papa_simulation.jl index d0a38baf6..1420687fd 100644 --- a/examples/single_column_os_papa_simulation.jl +++ b/examples/single_column_os_papa_simulation.jl @@ -68,6 +68,11 @@ atmosphere = JRA55PrescribedAtmosphere(longitude = λ★, end_date = DateTime(1990, 1, 31), # Last day of the simulation backend = InMemory()) +radiation = JRA55PrescribedRadiation(longitude = λ★, + latitude = φ★, + end_date = DateTime(1990, 1, 31), + backend = InMemory()) + # This builds a representation of the atmosphere on the small grid atmosphere.grid @@ -101,7 +106,6 @@ lines!(axq, t_days, qa) current_figure() # We continue constructing a simulation. -radiation = Radiation() coupled_model = OceanOnlyModel(ocean; atmosphere, radiation) simulation = Simulation(coupled_model, Δt=ocean.Δt, stop_time=30days) @@ -205,8 +209,8 @@ ua = atmosphere.velocities.u va = atmosphere.velocities.v Ta = atmosphere.tracers.T qa = atmosphere.tracers.q -ℐꜜˡʷ = atmosphere.downwelling_radiation.longwave -ℐꜜˢʷ = atmosphere.downwelling_radiation.shortwave +ℐꜜˡʷ = radiation.downwelling_longwave +ℐꜜˢʷ = radiation.downwelling_shortwave Pr = atmosphere.freshwater_flux.rain Ps = atmosphere.freshwater_flux.snow diff --git a/examples/veros_ocean_forced_simulation.jl b/examples/veros_ocean_forced_simulation.jl index bb95573f5..523a6c0d4 100644 --- a/examples/veros_ocean_forced_simulation.jl +++ b/examples/veros_ocean_forced_simulation.jl @@ -69,11 +69,10 @@ ocean.set_forcing = set_forcing_tke_only # radiation, as well as freshwater fluxes. atmos = JRA55PrescribedAtmosphere(; backend = JRA55NetCDFBackend(10)) +radiation = JRA55PrescribedRadiation(; backend = JRA55NetCDFBackend(10)) -# The coupled ocean--atmosphere model. -# We use the default radiation model and we do not couple an ice model for simplicity. +# The coupled ocean--atmosphere model. We do not couple an ice model for simplicity. -radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, nothing; atmosphere=atmos, radiation) simulation = Simulation(coupled_model; Δt = 1800, stop_time = 60days) diff --git a/experiments/arctic_simulation.jl b/experiments/arctic_simulation.jl index afabdf826..9afe252c6 100644 --- a/experiments/arctic_simulation.jl +++ b/experiments/arctic_simulation.jl @@ -90,7 +90,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), ##### atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(40)) -radiation = Radiation() +radiation = JRA55PrescribedRadiation(arch; backend=JRA55NetCDFBackend(40)) ##### ##### Arctic coupled model diff --git a/experiments/coupled_simulation/earth_system_coupled_simulation.jl b/experiments/coupled_simulation/earth_system_coupled_simulation.jl index 334ebce91..3c65fc3b2 100644 --- a/experiments/coupled_simulation/earth_system_coupled_simulation.jl +++ b/experiments/coupled_simulation/earth_system_coupled_simulation.jl @@ -79,8 +79,11 @@ salinity = ECCOMetadata(:salinity; dir="./") ice_thickness = ECCOMetadata(:sea_ice_thickness; dir="./") ice_concentration = ECCOMetadata(:sea_ice_concentration; dir="./") -atmosphere = JRA55PrescribedAtmosphere(arch, backend=JRA55NetCDFBackend(20)) -radiation = Radiation(ocean_albedo = LatitudeDependentAlbedo(), sea_ice_albedo=0.6) +jra55_backend = JRA55NetCDFBackend(20) +atmosphere = JRA55PrescribedAtmosphere(arch; backend=jra55_backend) +radiation = JRA55PrescribedRadiation(arch; backend=jra55_backend, + ocean_surface = SurfaceRadiationProperties(LatitudeDependentAlbedo(), 0.97), + sea_ice_surface = SurfaceRadiationProperties(0.6, 1.0)) set!(ocean.model, T=temperature, S=salinity) set!(sea_ice.model.ice_thickness, ice_thickness, inpainting=NearestNeighborInpainting(1)) diff --git a/experiments/flux_climatology/flux_climatology.jl b/experiments/flux_climatology/flux_climatology.jl index 20ad23d60..dfda99ab8 100644 --- a/experiments/flux_climatology/flux_climatology.jl +++ b/experiments/flux_climatology/flux_climatology.jl @@ -197,7 +197,7 @@ atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(1000)) ##### A prescribed earth... ##### -earth_model = OceanOnlyModel(ocean; atmosphere, radiation = Radiation(ocean_emissivity=0, ocean_albedo=1)) +earth_model = OceanOnlyModel(ocean; atmosphere) # radiation off (radiation=nothing default) earth = Simulation(earth_model, Δt=3hours, stop_time=365days) wall_time = Ref(time_ns()) diff --git a/experiments/one_degree_simulation/one_degree_simulation.jl b/experiments/one_degree_simulation/one_degree_simulation.jl index e48bc4d56..215beafd6 100644 --- a/experiments/one_degree_simulation/one_degree_simulation.jl +++ b/experiments/one_degree_simulation/one_degree_simulation.jl @@ -45,8 +45,9 @@ ocean = ocean_simulation(grid; momentum_advection, tracer_advection, free_surfac set!(ocean.model, T=ECCOMetadata(:temperature; dates=first(dates)), S=ECCOMetadata(:salinity; dates=first(dates))) -radiation = Radiation(arch) -atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(41)) +jra55_backend = JRA55NetCDFBackend(41) +atmosphere = JRA55PrescribedAtmosphere(arch; backend=jra55_backend) +radiation = JRA55PrescribedRadiation(arch; backend=jra55_backend) coupled_model = OceanOnlyModel(ocean; atmosphere, radiation) simulation = Simulation(coupled_model; Δt=10minutes, stop_iteration=100) diff --git a/src/SeaIces/freezing_limited_ocean_temperature.jl b/src/SeaIces/freezing_limited_ocean_temperature.jl index d721b0b95..2860962f0 100644 --- a/src/SeaIces/freezing_limited_ocean_temperature.jl +++ b/src/SeaIces/freezing_limited_ocean_temperature.jl @@ -24,7 +24,7 @@ The melting temperature is a function of salinity and is controlled by the `liqu FreezingLimitedOceanTemperature(FT::DataType=Oceananigans.defaults.FloatType; liquidus=LinearLiquidus(FT)) = FreezingLimitedOceanTemperature(liquidus) -const FreezingLimitedEarthSystemModel = EarthSystemModel{<:FreezingLimitedOceanTemperature, A, L, O, <:NoSeaIceInterface} where {A, L, O} +const FreezingLimitedEarthSystemModel = EarthSystemModel{R, A, L, <:FreezingLimitedOceanTemperature, O, <:NoSeaIceInterface} where {R, A, L, O} # Extend interface methods to work with a `FreezingLimitedOceanTemperature` sea_ice_concentration(::FreezingLimitedOceanTemperature) = ZeroField() @@ -50,8 +50,8 @@ InterfaceComputations.sea_ice_ocean_interface(grid, ::FreezingLimitedOceanTemper InterfaceComputations.net_fluxes(::FreezingLimitedOceanTemperature) = nothing -const OnlyOceanwithFreezingLimited = EarthSystemModel{<:FreezingLimitedOceanTemperature, <:Nothing, <:Any, <:Any} -const OnlyAtmospherewithFreezingLimited = EarthSystemModel{<:FreezingLimitedOceanTemperature, <:Any, <:Any, <:Nothing} +const OnlyOceanwithFreezingLimited = EarthSystemModel{<:Any, <:Nothing, <:Any, <:FreezingLimitedOceanTemperature, <:Any} +const OnlyAtmospherewithFreezingLimited = EarthSystemModel{<:Any, <:Any, <:Any, <:FreezingLimitedOceanTemperature, <:Nothing} const SingleComponentPlusFreezingLimited = Union{OnlyAtmospherewithFreezingLimited, OnlyOceanwithFreezingLimited} # Also for the ocean nothing really happens here From 53aa209ebe970968d6c47f644a8e2d0fc1b0a333 Mon Sep 17 00:00:00 2001 From: "Gregory L. Wagner" Date: Thu, 30 Apr 2026 08:22:58 -0600 Subject: [PATCH 04/13] Apply suggestion from @glwagner --- src/Radiations/air_sea_interface_radiation_state.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Radiations/air_sea_interface_radiation_state.jl b/src/Radiations/air_sea_interface_radiation_state.jl index 4cd43c115..c97f36039 100644 --- a/src/Radiations/air_sea_interface_radiation_state.jl +++ b/src/Radiations/air_sea_interface_radiation_state.jl @@ -5,8 +5,7 @@ (σ = r.stefan_boltzmann_constant, surface_properties = r.surface_properties) -@inline function air_sea_interface_radiation_state(rk, exchanger_state, - i, j, k, grid, time) +@inline function air_sea_interface_radiation_state(rk, exchanger_state, i, j, k, grid, time) σ = rk.σ @inbounds ℐꜜˢʷ = exchanger_state.ℐꜜˢʷ[i, j, 1] @inbounds ℐꜜˡʷ = exchanger_state.ℐꜜˡʷ[i, j, 1] From bd251416a89f0e0c921d47e6b14227c5d203cc57 Mon Sep 17 00:00:00 2001 From: "Gregory L. Wagner" Date: Thu, 30 Apr 2026 08:23:23 -0600 Subject: [PATCH 05/13] Apply suggestion from @glwagner --- src/Radiations/air_sea_interface_radiation_state.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Radiations/air_sea_interface_radiation_state.jl b/src/Radiations/air_sea_interface_radiation_state.jl index c97f36039..c7748fa8d 100644 --- a/src/Radiations/air_sea_interface_radiation_state.jl +++ b/src/Radiations/air_sea_interface_radiation_state.jl @@ -15,8 +15,7 @@ return (; σ, α, ϵ, ℐꜜˢʷ, ℐꜜˡʷ) end -@inline function air_sea_ice_interface_radiation_state(rk, exchanger_state, - i, j, k, grid, time) +@inline function air_sea_ice_interface_radiation_state(rk, exchanger_state, i, j, k, grid, time) σ = rk.σ @inbounds ℐꜜˢʷ = exchanger_state.ℐꜜˢʷ[i, j, 1] @inbounds ℐꜜˡʷ = exchanger_state.ℐꜜˡʷ[i, j, 1] From 83a2151653255d4299487b71e12e19a79776d4f7 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 30 Apr 2026 08:39:05 -0600 Subject: [PATCH 06/13] Address PR review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SurfaceRadiationProperties gains a kwarg constructor with a default emissivity (0.97), letting users write `SurfaceRadiationProperties(albedo = 0.1)` to override only the albedo. - New top-level `default_stefan_boltzmann_constant = 5.670374419e-8` constant in Radiations; all PrescribedRadiation / data-wrangling constructors now default to it. - Reorder positional arguments to match struct (top→bottom) convention: - `EarthSystemModel(radiation, atmosphere, land, sea_ice, ocean; ...)` - `OceanSeaIceModel(sea_ice, ocean; ...)` All call sites in src, tests, examples, experiments, and docs flipped. - Fix indent in ECCOPrescribedRadiation docstring. - Apply review-suggested formatting to air_sea_(ice_)interface_radiation_state. - Update docstring in earth_system_model.jl to reflect the new positional-arg convention. - one_degree_simulation.jl now demonstrates a custom ocean albedo via `SurfaceRadiationProperties(albedo = LatitudeDependentAlbedo())`. - Fix Speedy comment in global_climate_simulation.jl: NumericalEarth still computes turbulent fluxes; only the radiation path is unwired against Speedy upwelling-LW. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/src/developers/slab_ocean.jl | 2 +- docs/src/earth_system_model.md | 12 +++-- examples/global_climate_simulation.jl | 9 ++-- .../idealized_single_column_simulation.jl | 3 +- examples/meridional_heat_transport_ecco.jl | 2 +- examples/one_degree_simulation.jl | 8 +++- examples/veros_ocean_forced_simulation.jl | 2 +- experiments/arctic_simulation.jl | 2 +- .../earth_system_coupled_simulation.jl | 2 +- src/DataWrangling/ECCO/ECCO_radiation.jl | 24 +++++----- src/DataWrangling/JRA55/JRA55.jl | 2 +- .../JRA55/JRA55_prescribed_radiation.jl | 20 ++++---- .../OSPapa/OSPapa_prescribed_radiation.jl | 18 ++++---- src/Diagnostics/meridional_heat_transport.jl | 2 +- src/EarthSystemModels/earth_system_model.jl | 46 +++++++++---------- src/Radiations/Radiations.jl | 6 ++- src/Radiations/prescribed_radiation.jl | 4 +- .../surface_radiation_properties.jl | 2 +- test/test_checkpointer.jl | 2 +- test/test_diagnostics_2.jl | 2 +- test/test_ocean_sea_ice_model.jl | 2 +- test/test_radiations.jl | 2 +- test/test_sea_ice_ocean_heat_fluxes.jl | 12 ++--- test/test_speedy_coupling.jl | 2 +- test/test_surface_fluxes.jl | 6 +-- 25 files changed, 104 insertions(+), 90 deletions(-) diff --git a/docs/src/developers/slab_ocean.jl b/docs/src/developers/slab_ocean.jl index 82c7dadf0..0860dc86d 100644 --- a/docs/src/developers/slab_ocean.jl +++ b/docs/src/developers/slab_ocean.jl @@ -140,7 +140,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness, dataset=ECCO4Monthly()), ℵ=Metadatum(:sea_ice_concentration, dataset=ECCO4Monthly())) interfaces = ComponentInterfaces(atmosphere, slab_ocean, sea_ice; exchange_grid=grid) -coupled_model = NumericalEarth.EarthSystemModel(atmosphere, slab_ocean, sea_ice; interfaces) +coupled_model = NumericalEarth.EarthSystemModel(nothing, atmosphere, nothing, sea_ice, slab_ocean; interfaces) simulation = Simulation(coupled_model, Δt=60minutes, stop_time=120days) run!(simulation) diff --git a/docs/src/earth_system_model.md b/docs/src/earth_system_model.md index 8086b01b2..d7f7a278c 100644 --- a/docs/src/earth_system_model.md +++ b/docs/src/earth_system_model.md @@ -52,6 +52,7 @@ model # output EarthSystemModel{CPU}(time = 1 hour, iteration = 3) +├── radiation: Nothing ├── atmosphere: Nothing ├── land: Nothing ├── sea_ice: FreezingLimitedOceanTemperature{ClimaSeaIce.SeaIceThermodynamics.LinearLiquidus{Float64}} @@ -88,7 +89,7 @@ a sea ice component as positional arguments: ```jldoctest esm ocean = ocean_simulation(grid, timestepper = :QuasiAdamsBashforth2) sea_ice = FreezingLimitedOceanTemperature() -model = OceanSeaIceModel(ocean, sea_ice) +model = OceanSeaIceModel(sea_ice, ocean) # output EarthSystemModel{CPU}(time = 0 seconds, iteration = 0) @@ -110,9 +111,12 @@ Oceananigans `Simulation`, would also work. EarthSystemModel ``` -The full constructor takes positional arguments `(atmosphere, ocean, sea_ice)` and -gives access to every knob: radiation parameters, reference densities, heat capacities, -and -- most importantly -- the `interfaces` keyword, which controls how fluxes are computed. +The full constructor takes positional arguments +`(radiation, atmosphere, land, sea_ice, ocean)` -- the components in struct +order, top to bottom -- and gives access to every knob: reference densities, +heat capacities, and -- most importantly -- the `interfaces` keyword, which +controls how fluxes are computed. Pass `nothing` for components that are +absent. ## Customizing flux formulations diff --git a/examples/global_climate_simulation.jl b/examples/global_climate_simulation.jl index bfebd8000..de51a3894 100644 --- a/examples/global_climate_simulation.jl +++ b/examples/global_climate_simulation.jl @@ -98,11 +98,12 @@ nothing #hide nothing #hide # We build the complete coupled `earth_model` and the coupled simulation. -# SpeedyWeather drives the air-sea fluxes here, so we leave the top-level -# `radiation` component as `nothing` (radiatively decoupled) to avoid -# double-counting. +# NumericalEarth still computes turbulent (sensible heat, water vapor) fluxes +# here using its own bulk-formula machinery and writes them back to Speedy. +# Top-level radiation, however, is not yet wired up against SpeedyWeather's +# upwelling-LW path, so we leave `radiation = nothing` for now. -earth_model = EarthSystemModel(atmosphere, ocean, sea_ice) +earth_model = EarthSystemModel(nothing, atmosphere, nothing, sea_ice, ocean) # ## Building and running the simulation # diff --git a/examples/idealized_single_column_simulation.jl b/examples/idealized_single_column_simulation.jl index 988258bcb..ec76bece1 100644 --- a/examples/idealized_single_column_simulation.jl +++ b/examples/idealized_single_column_simulation.jl @@ -24,8 +24,9 @@ atmosphere = PrescribedAtmosphere(atmosphere_grid, atmosphere_times) # Build the radiation component (lives on the same grid + times as the atmosphere # in this single-column setup) and prescribe a constant shortwave forcing. +# Override the default ocean albedo (0.05) but keep the default emissivity (0.97). radiation = PrescribedRadiation(atmosphere_grid, atmosphere_times; - ocean_surface = SurfaceRadiationProperties(0.1, 0.97)) + ocean_surface = SurfaceRadiationProperties(albedo=0.1)) parent(atmosphere.tracers.T) .= Tᵃᵗ # K parent(atmosphere.velocities.u) .= u₁₀ # m/s diff --git a/examples/meridional_heat_transport_ecco.jl b/examples/meridional_heat_transport_ecco.jl index 30fba8392..fd6ad9766 100755 --- a/examples/meridional_heat_transport_ecco.jl +++ b/examples/meridional_heat_transport_ecco.jl @@ -45,7 +45,7 @@ set!(sea_ice.model, h=ecco_sea_ice_thickness, ℵ=ecco_sea_ice_concentration) jra55_backend = JRA55NetCDFBackend(80) atmosphere = JRA55PrescribedAtmosphere(arch; backend=jra55_backend) radiation = JRA55PrescribedRadiation(arch; backend=jra55_backend) -esm = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +esm = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation) simulation = Simulation(esm; Δt=20minutes, stop_time=5*365days) diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index b67ad3f40..53e09aaf9 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -97,7 +97,11 @@ set!(sea_ice.model, h=ecco_sea_ice_thickness, ℵ=ecco_sea_ice_concentration) # We force the simulation with a JRA55-do atmospheric reanalysis. jra55_backend = JRA55NetCDFBackend(80) atmosphere = JRA55PrescribedAtmosphere(arch; backend=jra55_backend) -radiation = JRA55PrescribedRadiation(arch; backend=jra55_backend) +# Use a latitude-dependent ocean albedo (Large & Yeager 2009); keep the +# default ocean emissivity (0.97) and sea-ice surface (albedo 0.7, +# emissivity 1.0). +radiation = JRA55PrescribedRadiation(arch; backend=jra55_backend, + ocean_surface = SurfaceRadiationProperties(albedo = LatitudeDependentAlbedo())) land = JRA55PrescribedLand(arch; backend=jra55_backend) # ### Coupled simulation @@ -107,7 +111,7 @@ land = JRA55PrescribedLand(arch; backend=jra55_backend) # With Runge-Kutta 3rd order time-stepping we can safely use a timestep of 20 minutes. -coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, land, radiation) +coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, land, radiation) simulation = Simulation(coupled_model; Δt=20minutes, stop_time=365days) # ### A progress messenger diff --git a/examples/veros_ocean_forced_simulation.jl b/examples/veros_ocean_forced_simulation.jl index 523a6c0d4..598582683 100644 --- a/examples/veros_ocean_forced_simulation.jl +++ b/examples/veros_ocean_forced_simulation.jl @@ -73,7 +73,7 @@ radiation = JRA55PrescribedRadiation(; backend = JRA55NetCDFBackend(10)) # The coupled ocean--atmosphere model. We do not couple an ice model for simplicity. -coupled_model = OceanSeaIceModel(ocean, nothing; atmosphere=atmos, radiation) +coupled_model = OceanSeaIceModel(nothing, ocean; atmosphere=atmos, radiation) simulation = Simulation(coupled_model; Δt = 1800, stop_time = 60days) # We set up a progress callback that will print the current time, iteration, and maximum velocities diff --git a/experiments/arctic_simulation.jl b/experiments/arctic_simulation.jl index 9afe252c6..eee1fdb48 100644 --- a/experiments/arctic_simulation.jl +++ b/experiments/arctic_simulation.jl @@ -96,7 +96,7 @@ radiation = JRA55PrescribedRadiation(arch; backend=JRA55NetCDFBackend(40)) ##### Arctic coupled model ##### -arctic = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +arctic = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation) arctic = Simulation(arctic, Δt=5minutes, stop_time=365days) # Sea-ice variables diff --git a/experiments/coupled_simulation/earth_system_coupled_simulation.jl b/experiments/coupled_simulation/earth_system_coupled_simulation.jl index 3c65fc3b2..73a81d5d5 100644 --- a/experiments/coupled_simulation/earth_system_coupled_simulation.jl +++ b/experiments/coupled_simulation/earth_system_coupled_simulation.jl @@ -89,7 +89,7 @@ set!(ocean.model, T=temperature, S=salinity) set!(sea_ice.model.ice_thickness, ice_thickness, inpainting=NearestNeighborInpainting(1)) set!(sea_ice.model.ice_concentration, ice_concentration, inpainting=NearestNeighborInpainting(1)) -earth_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +earth_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation) earth = Simulation(earth_model; Δt=30minutes, stop_iteration=10, stop_time=30days) u, v, _ = ocean.model.velocities diff --git a/src/DataWrangling/ECCO/ECCO_radiation.jl b/src/DataWrangling/ECCO/ECCO_radiation.jl index 23cc78155..01a1eebcf 100644 --- a/src/DataWrangling/ECCO/ECCO_radiation.jl +++ b/src/DataWrangling/ECCO/ECCO_radiation.jl @@ -1,17 +1,17 @@ -using NumericalEarth.Radiations: PrescribedRadiation, SurfaceRadiationProperties +using NumericalEarth.Radiations: PrescribedRadiation, SurfaceRadiationProperties, default_stefan_boltzmann_constant """ ECCOPrescribedRadiation([architecture = CPU(), FT = Float32]; - dataset = ECCO4Monthly(), - start_date = first_date(dataset, :downwelling_shortwave), - end_date = last_date(dataset, :downwelling_shortwave), - dir = default_download_directory(dataset), - time_indices_in_memory = 10, - time_indexing = Cyclical(), - ocean_surface = SurfaceRadiationProperties(0.05, 0.97), - sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), - stefan_boltzmann_constant = 5.67e-8, - other_kw...) + dataset = ECCO4Monthly(), + start_date = first_date(dataset, :downwelling_shortwave), + end_date = last_date(dataset, :downwelling_shortwave), + dir = default_download_directory(dataset), + time_indices_in_memory = 10, + time_indexing = Cyclical(), + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), + stefan_boltzmann_constant = default_stefan_boltzmann_constant, + other_kw...) Return a [`PrescribedRadiation`](@ref) backed by ECCO downwelling shortwave and longwave fields. @@ -25,7 +25,7 @@ function ECCOPrescribedRadiation(architecture = CPU(), FT = Float32; time_indices_in_memory = 10, ocean_surface = SurfaceRadiationProperties(0.05, 0.97), sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), - stefan_boltzmann_constant = 5.67e-8, + stefan_boltzmann_constant = default_stefan_boltzmann_constant, other_kw...) ℐꜜˢʷ_meta = Metadata(:downwelling_shortwave; dataset, start_date, end_date, dir) diff --git a/src/DataWrangling/JRA55/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl index 77eaabb07..57cdcd6b4 100644 --- a/src/DataWrangling/JRA55/JRA55.jl +++ b/src/DataWrangling/JRA55/JRA55.jl @@ -20,7 +20,7 @@ using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBac using NumericalEarth using NumericalEarth.Atmospheres: PrescribedAtmosphere -using NumericalEarth.Radiations: PrescribedRadiation, SurfaceRadiationProperties +using NumericalEarth.Radiations: PrescribedRadiation, SurfaceRadiationProperties, default_stefan_boltzmann_constant using GPUArraysCore: @allowscalar diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_radiation.jl b/src/DataWrangling/JRA55/JRA55_prescribed_radiation.jl index 70a30f064..da28be94a 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_radiation.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_radiation.jl @@ -3,15 +3,15 @@ JRA55PrescribedRadiation(arch::Distributed, FT = Float32; kw...) = """ JRA55PrescribedRadiation([architecture = CPU(), FT = Float32]; - dataset = RepeatYearJRA55(), - start_date = first_date(dataset, :downwelling_shortwave_radiation), - end_date = last_date(dataset, :downwelling_shortwave_radiation), - backend = JRA55NetCDFBackend(10), - time_indexing = Cyclical(), - ocean_surface = SurfaceRadiationProperties(0.05, 0.97), - sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), - stefan_boltzmann_constant = 5.67e-8, - other_kw...) + dataset = RepeatYearJRA55(), + start_date = first_date(dataset, :downwelling_shortwave_radiation), + end_date = last_date(dataset, :downwelling_shortwave_radiation), + backend = JRA55NetCDFBackend(10), + time_indexing = Cyclical(), + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), + stefan_boltzmann_constant = default_stefan_boltzmann_constant, + other_kw...) Return a [`PrescribedRadiation`](@ref) backed by JRA55 downwelling shortwave and longwave `JRA55FieldTimeSeries`. Surface radiative properties (albedo, @@ -26,7 +26,7 @@ function JRA55PrescribedRadiation(architecture = CPU(), FT = Float32; time_indexing = Cyclical(), ocean_surface = SurfaceRadiationProperties(0.05, 0.97), sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), - stefan_boltzmann_constant = 5.67e-8, + stefan_boltzmann_constant = default_stefan_boltzmann_constant, other_kw...) kw = (; time_indexing, backend, start_date, end_date, dataset) diff --git a/src/DataWrangling/OSPapa/OSPapa_prescribed_radiation.jl b/src/DataWrangling/OSPapa/OSPapa_prescribed_radiation.jl index 7b980e57e..04ea5b798 100644 --- a/src/DataWrangling/OSPapa/OSPapa_prescribed_radiation.jl +++ b/src/DataWrangling/OSPapa/OSPapa_prescribed_radiation.jl @@ -1,14 +1,14 @@ -using NumericalEarth.Radiations: PrescribedRadiation, SurfaceRadiationProperties +using NumericalEarth.Radiations: PrescribedRadiation, SurfaceRadiationProperties, default_stefan_boltzmann_constant """ OSPapaPrescribedRadiation(architecture = CPU(), FT = Float32; - start_date = first_date(OSPapaHourly(), :shortwave_radiation), - end_date = last_date(OSPapaHourly(), :shortwave_radiation), - dir = download_OSPapa_cache, - max_gap_hours = 72, - ocean_surface = SurfaceRadiationProperties(0.05, 0.97), - sea_ice_surface = nothing, - stefan_boltzmann_constant = 5.67e-8) + start_date = first_date(OSPapaHourly(), :shortwave_radiation), + end_date = last_date(OSPapaHourly(), :shortwave_radiation), + dir = download_OSPapa_cache, + max_gap_hours = 72, + ocean_surface = SurfaceRadiationProperties(0.05, 0.97), + sea_ice_surface = nothing, + stefan_boltzmann_constant = default_stefan_boltzmann_constant) Construct a `PrescribedRadiation` from Ocean Station Papa buoy SW/LW observations on a single-column grid. @@ -20,7 +20,7 @@ function OSPapaPrescribedRadiation(architecture = CPU(), FT = Float32; max_gap_hours = 72, ocean_surface = SurfaceRadiationProperties(0.05, 0.97), sea_ice_surface = nothing, - stefan_boltzmann_constant = 5.67e-8) + stefan_boltzmann_constant = default_stefan_boltzmann_constant) mdkw = (; dataset = OSPapaHourly(), start_date, end_date, dir) surface_grid = RectilinearGrid(architecture, FT; size=(), topology=(Flat, Flat, Flat)) diff --git a/src/Diagnostics/meridional_heat_transport.jl b/src/Diagnostics/meridional_heat_transport.jl index 6bc6338db..9ef034fd2 100644 --- a/src/Diagnostics/meridional_heat_transport.jl +++ b/src/Diagnostics/meridional_heat_transport.jl @@ -61,7 +61,7 @@ sea_ice = sea_ice_simulation(grid, ocean) atmosphere = PrescribedAtmosphere(grid, [0.0]) -esm = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation = Radiation()) +esm = OceanSeaIceModel(sea_ice, ocean; atmosphere) mht = meridional_heat_transport(esm) diff --git a/src/EarthSystemModels/earth_system_model.jl b/src/EarthSystemModels/earth_system_model.jl index 834aeb206..d76d610d2 100644 --- a/src/EarthSystemModels/earth_system_model.jl +++ b/src/EarthSystemModels/earth_system_model.jl @@ -89,9 +89,7 @@ allocate_interface_fluxes!(::Any, exchange_grid, surfaces) = nothing allocate_interface_fluxes!(::Nothing, exchange_grid, surfaces) = nothing """ - EarthSystemModel(atmosphere, ocean, sea_ice; - radiation = nothing, - land = nothing, + EarthSystemModel(radiation, atmosphere, land, sea_ice, ocean; clock = Clock{Float64}(time=0), ocean_reference_density = reference_density(ocean), ocean_heat_capacity = heat_capacity(ocean), @@ -99,29 +97,32 @@ allocate_interface_fluxes!(::Nothing, exchange_grid, surfaces) = nothing sea_ice_heat_capacity = heat_capacity(sea_ice), interfaces = nothing) -Construct a coupled earth system model with an atmosphere, ocean, and sea ice component. -For simpler configurations, see [`OceanOnlyModel`](@ref) and [`OceanSeaIceModel`](@ref). +Construct a coupled earth system model. Components are passed in struct order +(top to bottom): radiation, atmosphere, land, sea_ice, ocean. Pass `nothing` +for components that are absent. For simpler configurations, see +[`OceanOnlyModel`](@ref), [`OceanSeaIceModel`](@ref), and +[`AtmosphereOceanModel`](@ref). Arguments ========== -- `atmosphere`: A representation of a possibly time-dependent atmospheric state. +- `radiation`: Radiation component, or `nothing` for a radiatively decoupled surface. + Pass a `PrescribedRadiation` (e.g. `JRA55PrescribedRadiation(...)`) to + enable radiative forcing. +- `atmosphere`: A representation of a possibly time-dependent atmospheric state, or `nothing`. For a prognostic atmosphere, use `atmosphere_simulation`. For prescribed atmospheric forcing, use `JRA55PrescribedAtmosphere` or `PrescribedAtmosphere`. -- `ocean`: A representation of a possibly time-dependent ocean state. Currently, only `Oceananigans.Simulation`s - of `Oceananigans.HydrostaticFreeSurfaceModel` are tested. -- `sea_ice`: A representation of a possibly time-dependent sea ice state. +- `land`: Land component, or `nothing`. +- `sea_ice`: A representation of a possibly time-dependent sea ice state, or `nothing`. For example, the minimalist `FreezingLimitedOceanTemperature` represents oceanic latent heating during freezing only, but does not evolve sea ice variables. For prognostic sea ice use an `Oceananigans.Simulation` of `ClimaSeaIce.SeaIceModel`. +- `ocean`: A representation of a possibly time-dependent ocean state. Currently, only `Oceananigans.Simulation`s + of `Oceananigans.HydrostaticFreeSurfaceModel` are tested. Keyword Arguments ================== -- `radiation`: Radiation component. Defaults to `nothing` (radiatively decoupled surface). - Pass a `PrescribedRadiation` (e.g. `JRA55PrescribedRadiation(...)`) to enable radiative - forcing. -- `land`: Land component. Defaults to `nothing`. - `clock`: Keeps track of time. - `ocean_reference_density`: Reference density for the ocean. Defaults to value from ocean model. - `ocean_heat_capacity`: Heat capacity for the ocean. Defaults to value from ocean model. @@ -130,9 +131,7 @@ Keyword Arguments - `interfaces`: Component interfaces for coupling. Defaults to `nothing` and will be constructed automatically. To customize the sea ice-ocean heat flux formulation, create interfaces manually using `ComponentInterfaces`. """ -function EarthSystemModel(atmosphere, ocean, sea_ice; - radiation = nothing, - land = nothing, +function EarthSystemModel(radiation, atmosphere, land, sea_ice, ocean; clock = Clock{Float64}(time=0), ocean_reference_density = reference_density(ocean), ocean_heat_capacity = heat_capacity(ocean), @@ -203,7 +202,7 @@ function present_surfaces(ocean, sea_ice) end """ - OceanOnlyModel(ocean; atmosphere=nothing, radiation=nothing, kw...) + OceanOnlyModel(ocean; atmosphere=nothing, radiation=nothing, land=nothing, kw...) Construct an ocean-only model without a sea ice component. This is a convenience constructor for [`EarthSystemModel`](@ref) that sets `sea_ice` @@ -214,17 +213,18 @@ The `atmosphere` keyword can be used to specify a prescribed atmospheric forcing to `EarthSystemModel`. """ OceanOnlyModel(ocean; atmosphere=nothing, land=nothing, radiation=nothing, kw...) = - EarthSystemModel(atmosphere, ocean, default_sea_ice(); radiation, land, kw...) + EarthSystemModel(radiation, atmosphere, land, default_sea_ice(), ocean; kw...) """ - OceanSeaIceModel(ocean, sea_ice; atmosphere=nothing, radiation=nothing, kw...) + OceanSeaIceModel(sea_ice, ocean; atmosphere=nothing, radiation=nothing, land=nothing, kw...) Construct a coupled ocean--sea ice model. This is a convenience constructor for [`EarthSystemModel`](@ref) with an explicit sea ice component -and an optional prescribed atmosphere. +and an optional prescribed atmosphere. Positional arguments follow the +struct convention (top→bottom): `sea_ice` then `ocean`. """ -OceanSeaIceModel(ocean, sea_ice; atmosphere=nothing, land=nothing, radiation=nothing, kw...) = - EarthSystemModel(atmosphere, ocean, sea_ice; radiation, land, kw...) +OceanSeaIceModel(sea_ice, ocean; atmosphere=nothing, land=nothing, radiation=nothing, kw...) = + EarthSystemModel(radiation, atmosphere, land, sea_ice, ocean; kw...) """ AtmosphereOceanModel(atmosphere, ocean; kw...) @@ -234,7 +234,7 @@ Convenience constructor for [`EarthSystemModel`](@ref) with an atmosphere and oc but no sea ice. All keyword arguments are forwarded to `EarthSystemModel`. """ AtmosphereOceanModel(atmosphere, ocean; land=nothing, radiation=nothing, kw...) = - EarthSystemModel(atmosphere, ocean, nothing; radiation, land, kw...) + EarthSystemModel(radiation, atmosphere, land, nothing, ocean; kw...) time(coupled_model::EarthSystemModel) = coupled_model.clock.time diff --git a/src/Radiations/Radiations.jl b/src/Radiations/Radiations.jl index bee972c39..fd31f94c4 100644 --- a/src/Radiations/Radiations.jl +++ b/src/Radiations/Radiations.jl @@ -4,7 +4,11 @@ export PrescribedRadiation, SurfaceRadiationProperties, InterfaceRadiationFlux, LatitudeDependentAlbedo, - TabulatedAlbedo + TabulatedAlbedo, + default_stefan_boltzmann_constant + +# CODATA 2018 value of the Stefan–Boltzmann constant, in W m⁻² K⁻⁴. +const default_stefan_boltzmann_constant = 5.670374419e-8 using Oceananigans using Oceananigans.Architectures: architecture diff --git a/src/Radiations/prescribed_radiation.jl b/src/Radiations/prescribed_radiation.jl index 23978633b..0c1a3332a 100644 --- a/src/Radiations/prescribed_radiation.jl +++ b/src/Radiations/prescribed_radiation.jl @@ -54,7 +54,7 @@ end sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), snow_surface = nothing, land_surface = nothing, - stefan_boltzmann_constant = 5.67e-8) + stefan_boltzmann_constant = default_stefan_boltzmann_constant) Construct a `PrescribedRadiation` component from `FieldTimeSeries` of downwelling shortwave and longwave radiation. Grid + times are inferred from @@ -69,7 +69,7 @@ function PrescribedRadiation(downwelling_shortwave::FieldTimeSeries, sea_ice_surface = SurfaceRadiationProperties(0.7, 1.0), snow_surface = nothing, land_surface = nothing, - stefan_boltzmann_constant = 5.67e-8) + stefan_boltzmann_constant = default_stefan_boltzmann_constant) grid = downwelling_shortwave.grid times = downwelling_shortwave.times diff --git a/src/Radiations/surface_radiation_properties.jl b/src/Radiations/surface_radiation_properties.jl index 7fddf6869..0b069189d 100644 --- a/src/Radiations/surface_radiation_properties.jl +++ b/src/Radiations/surface_radiation_properties.jl @@ -14,7 +14,7 @@ and longwave emissivity (`emissivity`). any other object for which `stateindex` is defined. `emissivity` may be a `Number` or any other `stateindex`-able object. """ -SurfaceRadiationProperties(; albedo, emissivity) = SurfaceRadiationProperties(albedo, emissivity) +SurfaceRadiationProperties(; albedo, emissivity = 0.97) = SurfaceRadiationProperties(albedo, emissivity) Adapt.adapt_structure(to, s::SurfaceRadiationProperties) = SurfaceRadiationProperties(Adapt.adapt(to, s.albedo), diff --git a/test/test_checkpointer.jl b/test/test_checkpointer.jl index ce5eb2148..ab13917b4 100644 --- a/test/test_checkpointer.jl +++ b/test/test_checkpointer.jl @@ -32,7 +32,7 @@ using Oceananigans.OutputWriters: Checkpointer land = JRA55PrescribedLand(arch; backend) radiation = JRA55PrescribedRadiation(arch; backend) - return OceanSeaIceModel(ocean, sea_ice; atmosphere, land, radiation) + return OceanSeaIceModel(sea_ice, ocean; atmosphere, land, radiation) end # Reference run: 3 iterations, then continue to 6 diff --git a/test/test_diagnostics_2.jl b/test/test_diagnostics_2.jl index 19a7d3efd..28fec3701 100644 --- a/test/test_diagnostics_2.jl +++ b/test/test_diagnostics_2.jl @@ -23,7 +23,7 @@ for arch in test_architectures sea_ice = sea_ice_simulation(grid, ocean) atmosphere = PrescribedAtmosphere(grid, [0.0]) - esm = OceanSeaIceModel(ocean, sea_ice; atmosphere) + esm = OceanSeaIceModel(sea_ice, ocean; atmosphere) T_flux = ocean.model.tracers.T.boundary_conditions.top.condition S_flux = ocean.model.tracers.S.boundary_conditions.top.condition diff --git a/test/test_ocean_sea_ice_model.jl b/test/test_ocean_sea_ice_model.jl index 64ae969db..5552701f8 100644 --- a/test/test_ocean_sea_ice_model.jl +++ b/test/test_ocean_sea_ice_model.jl @@ -64,7 +64,7 @@ using ClimaSeaIce.Rheologies # Fluxes are computed when the model is constructed, so we just test that this works. # And that we can time step with sea ice @test begin - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation) time_step!(coupled_model, 1) true end diff --git a/test/test_radiations.jl b/test/test_radiations.jl index 714dbc352..ac651db89 100644 --- a/test/test_radiations.jl +++ b/test/test_radiations.jl @@ -21,7 +21,7 @@ using NumericalEarth.Radiations: PrescribedRadiation, @test rad.surface_properties.ocean.emissivity == 0.97 @test rad.surface_properties.sea_ice.albedo == 0.7 @test rad.surface_properties.sea_ice.emissivity == 1.0 - @test rad.stefan_boltzmann_constant ≈ 5.67e-8 + @test rad.stefan_boltzmann_constant ≈ 5.67e-8 atol=1e-10 @test isnothing(rad.interface_fluxes) # Surfaces can be omitted diff --git a/test/test_sea_ice_ocean_heat_fluxes.jl b/test/test_sea_ice_ocean_heat_fluxes.jl index 46aafd54c..b20601ab8 100644 --- a/test/test_sea_ice_ocean_heat_fluxes.jl +++ b/test/test_sea_ice_ocean_heat_fluxes.jl @@ -208,7 +208,7 @@ end interfaces = ComponentInterfaces(atmosphere, ocean, sea_ice; radiation, sea_ice_ocean_heat_flux) - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation, interfaces) + coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation, interfaces) # Test melting conditions: warm ocean above freezing # Freezing point at S=35 is about -1.9°C @@ -266,7 +266,7 @@ end interfaces = ComponentInterfaces(atmosphere, ocean, sea_ice; radiation, sea_ice_ocean_heat_flux) - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation, interfaces) + coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation, interfaces) # Set up melting conditions set!(ocean.model, T=2.0, S=35.0) # Warm ocean @@ -410,7 +410,7 @@ end interfaces = ComponentInterfaces(atmosphere, ocean, sea_ice; radiation, sea_ice_ocean_heat_flux) - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation, interfaces) + coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation, interfaces) # Set up conditions where frazil might form: # Cold ocean near freezing with ice present @@ -458,7 +458,7 @@ end # Test with ThreeEquationHeatFlux (default) @test begin - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation) flux_form = coupled_model.interfaces.sea_ice_ocean_interface.flux_formulation flux_form isa ThreeEquationHeatFlux end @@ -469,7 +469,7 @@ end interfaces = ComponentInterfaces(atmosphere, ocean, sea_ice; radiation, sea_ice_ocean_heat_flux = flux) - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation, interfaces) + coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation, interfaces) flux_form = coupled_model.interfaces.sea_ice_ocean_interface.flux_formulation flux_form isa IceBathHeatFlux end @@ -482,7 +482,7 @@ end interfaces = ComponentInterfaces(atmosphere, ocean, sea_ice; radiation, sea_ice_ocean_heat_flux) - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation, interfaces) + coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation, interfaces) @test begin time_step!(coupled_model, 60) true diff --git a/test/test_speedy_coupling.jl b/test/test_speedy_coupling.jl index a49840be8..9c78dad22 100644 --- a/test/test_speedy_coupling.jl +++ b/test/test_speedy_coupling.jl @@ -15,7 +15,7 @@ Oceananigans.set!(ocean.model, T=EN4Metadatum(:temperature), S=EN4Metadatum(:sal atmos = NumericalEarth.atmosphere_simulation(spectral_grid) -earth_model = EarthSystemModel(atmos, ocean, default_sea_ice()) +earth_model = EarthSystemModel(nothing, atmos, nothing, default_sea_ice(), ocean) Qca = atmos.variables.parameterizations.ocean.sensible_heat_flux.data Mva = atmos.variables.parameterizations.ocean.surface_humidity_flux.data diff --git a/test/test_surface_fluxes.jl b/test/test_surface_fluxes.jl index f1061e018..8f2cf51b6 100644 --- a/test/test_surface_fluxes.jl +++ b/test/test_surface_fluxes.jl @@ -243,7 +243,7 @@ end # Always cooling! fill!(atmosphere.tracers.T, 273.15 - 20) - coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere) + coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere) # Test that the temperature has snapped up to freezing @test minimum(ocean.model.tracers.T) == 0 @@ -283,7 +283,7 @@ end fill!(ocean.model.tracers.T, -2.0) # Test that we populate the sea-ice ocean stress - earth = OceanSeaIceModel(ocean, sea_ice; atmosphere) + earth = OceanSeaIceModel(sea_ice, ocean; atmosphere) τˣ = earth.interfaces.sea_ice_ocean_interface.fluxes.x_momentum τʸ = earth.interfaces.sea_ice_ocean_interface.fluxes.y_momentum @@ -327,7 +327,7 @@ end # radiation = Radiation(ocean_albedo=0.1, ocean_emissivity=1.0) # sea_ice = nothing -# coupled_model = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +# coupled_model = OceanSeaIceModel(sea_ice, ocean; atmosphere, radiation) # times = 0:1hours:1days # Ntimes = length(times) From 51bdbd075326c10482265b903feff5d907207a72 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 30 Apr 2026 08:44:19 -0600 Subject: [PATCH 07/13] Add kwarg-only EarthSystemModel constructor The new `EarthSystemModel(; radiation, atmosphere, land, sea_ice, ocean, kw...)` form is equivalent to the positional one but skips the awkward `nothing` padding for absent components: EarthSystemModel(; atmosphere, ocean) # ocean + atmosphere EarthSystemModel(; atmosphere, sea_ice, ocean, radiation) # full coupled All previously-padded call sites in test_speedy_coupling.jl, examples/global_climate_simulation.jl, and docs/src/developers/slab_ocean.jl switch to the kwarg form for readability. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/src/developers/slab_ocean.jl | 2 +- examples/global_climate_simulation.jl | 2 +- src/EarthSystemModels/earth_system_model.jl | 26 +++++++++++++++++++++ test/test_speedy_coupling.jl | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/src/developers/slab_ocean.jl b/docs/src/developers/slab_ocean.jl index 0860dc86d..5654367c2 100644 --- a/docs/src/developers/slab_ocean.jl +++ b/docs/src/developers/slab_ocean.jl @@ -140,7 +140,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness, dataset=ECCO4Monthly()), ℵ=Metadatum(:sea_ice_concentration, dataset=ECCO4Monthly())) interfaces = ComponentInterfaces(atmosphere, slab_ocean, sea_ice; exchange_grid=grid) -coupled_model = NumericalEarth.EarthSystemModel(nothing, atmosphere, nothing, sea_ice, slab_ocean; interfaces) +coupled_model = NumericalEarth.EarthSystemModel(; atmosphere, sea_ice, ocean=slab_ocean, interfaces) simulation = Simulation(coupled_model, Δt=60minutes, stop_time=120days) run!(simulation) diff --git a/examples/global_climate_simulation.jl b/examples/global_climate_simulation.jl index de51a3894..1eac5f6e3 100644 --- a/examples/global_climate_simulation.jl +++ b/examples/global_climate_simulation.jl @@ -103,7 +103,7 @@ nothing #hide # Top-level radiation, however, is not yet wired up against SpeedyWeather's # upwelling-LW path, so we leave `radiation = nothing` for now. -earth_model = EarthSystemModel(nothing, atmosphere, nothing, sea_ice, ocean) +earth_model = EarthSystemModel(; atmosphere, sea_ice, ocean) # ## Building and running the simulation # diff --git a/src/EarthSystemModels/earth_system_model.jl b/src/EarthSystemModels/earth_system_model.jl index d76d610d2..5e334c789 100644 --- a/src/EarthSystemModels/earth_system_model.jl +++ b/src/EarthSystemModels/earth_system_model.jl @@ -192,6 +192,32 @@ function EarthSystemModel(radiation, atmosphere, land, sea_ice, ocean; return earth_system_model end +""" + EarthSystemModel(; radiation = nothing, + atmosphere = nothing, + land = nothing, + sea_ice = nothing, + ocean = nothing, + kw...) + +Keyword-only constructor for `EarthSystemModel`. Equivalent to the positional +form, but lets you pass only the components you actually have: + +```julia +EarthSystemModel(; atmosphere, ocean) # ocean + atmosphere +EarthSystemModel(; atmosphere, sea_ice, ocean, radiation) # full coupled +``` + +All keyword arguments accepted by the positional constructor are forwarded. +""" +EarthSystemModel(; radiation = nothing, + atmosphere = nothing, + land = nothing, + sea_ice = nothing, + ocean = nothing, + kw...) = + EarthSystemModel(radiation, atmosphere, land, sea_ice, ocean; kw...) + # Determine which surfaces are present in the model — used to allocate # per-surface diagnostic radiation flux buffers. function present_surfaces(ocean, sea_ice) diff --git a/test/test_speedy_coupling.jl b/test/test_speedy_coupling.jl index 9c78dad22..413f030d5 100644 --- a/test/test_speedy_coupling.jl +++ b/test/test_speedy_coupling.jl @@ -15,7 +15,7 @@ Oceananigans.set!(ocean.model, T=EN4Metadatum(:temperature), S=EN4Metadatum(:sal atmos = NumericalEarth.atmosphere_simulation(spectral_grid) -earth_model = EarthSystemModel(nothing, atmos, nothing, default_sea_ice(), ocean) +earth_model = EarthSystemModel(; atmosphere=atmos, sea_ice=default_sea_ice(), ocean) Qca = atmos.variables.parameterizations.ocean.sensible_heat_flux.data Mva = atmos.variables.parameterizations.ocean.surface_humidity_flux.data From b0b8b47bbcf533f3faebb916bd284200e19cd9f3 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 30 Apr 2026 11:18:26 -0600 Subject: [PATCH 08/13] Fix missed OceanSeaIceModel arg order in land test test_ocean_sea_ice_model.jl line 82 still had the old OceanSeaIceModel(ocean_with_land, sea_ice_with_land; ...) order. The earlier sed only matched literal 'ocean,' so it skipped this variant. Co-Authored-By: Claude Opus 4.7 (1M context) --- test/test_ocean_sea_ice_model.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_ocean_sea_ice_model.jl b/test/test_ocean_sea_ice_model.jl index 5552701f8..abfc3200e 100644 --- a/test/test_ocean_sea_ice_model.jl +++ b/test/test_ocean_sea_ice_model.jl @@ -79,7 +79,7 @@ using ClimaSeaIce.Rheologies sea_ice_with_land = sea_ice_simulation(grid, ocean_with_land; advection=WENO(order=7)) above_freezing_ocean_temperature!(ocean_with_land, grid, sea_ice_with_land) - coupled_model = OceanSeaIceModel(ocean_with_land, sea_ice_with_land; atmosphere, land, radiation) + coupled_model = OceanSeaIceModel(sea_ice_with_land, ocean_with_land; atmosphere, land, radiation) @test !isnothing(coupled_model.interfaces.exchanger.land) time_step!(coupled_model, 1) true From aeb643ac672326ca21a046ed951ea3651902c64c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 30 Apr 2026 12:14:06 -0600 Subject: [PATCH 09/13] Remove accidentally-committed test/Manifest.toml The test/Manifest.toml was committed by mistake in b9260d8e. Each Julia version generates its own resolved manifest from test/Project.toml, so committing one causes 'manifest differs' warnings (and ultimately resolution failures) on CI runs that use a different Julia version than the one the manifest was generated against. Add test/Manifest.toml to .gitignore alongside the existing root and docs entries. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 1 + test/Manifest.toml | 2409 -------------------------------------------- 2 files changed, 1 insertion(+), 2409 deletions(-) delete mode 100644 test/Manifest.toml diff --git a/.gitignore b/.gitignore index 4acc5052a..c553b3bb0 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ CondaPkg.toml # claude .claude +test/Manifest.toml diff --git a/test/Manifest.toml b/test/Manifest.toml deleted file mode 100644 index aa421621b..000000000 --- a/test/Manifest.toml +++ /dev/null @@ -1,2409 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.12.6" -manifest_format = "2.0" -project_hash = "b66e32e367c83f4abfda540176d6a679e11da82b" - -[[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.AbstractNumbers]] -deps = ["SpecialFunctions"] -git-tree-sha1 = "c0aa4b519104fecca9bc146c9843393f7cbd3c99" -uuid = "85c772de-338a-5e7f-b815-41e76c26ac1f" -version = "0.2.5" - -[[deps.AbstractTrees]] -git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" -uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" -version = "0.4.5" - -[[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "2eeb2c9bef11013efc6f8f97f32ee59b146b09fb" -uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.44" - - [deps.Accessors.extensions] - AxisKeysExt = "AxisKeys" - IntervalSetsExt = "IntervalSets" - LinearAlgebraExt = "LinearAlgebra" - StaticArraysExt = "StaticArrays" - StructArraysExt = "StructArrays" - TestExt = "Test" - UnitfulExt = "Unitful" - - [deps.Accessors.weakdeps] - AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - -[[deps.Adapt]] -deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "0761717147821d696c9470a7a86364b2fbd22fd8" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.5.2" -weakdeps = ["SparseArrays", "StaticArrays"] - - [deps.Adapt.extensions] - AdaptSparseArraysExt = "SparseArrays" - AdaptStaticArraysExt = "StaticArrays" - -[[deps.AliasTables]] -deps = ["PtrArrays", "Random"] -git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" -uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" -version = "1.1.3" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.2" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "54f895554d05c83e3dd59f6a396671dae8999573" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.24.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceAMDGPUExt = "AMDGPU" - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"] - ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceMetalExt = "Metal" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceSparseArraysExt = "SparseArrays" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - 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" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - Metal = "dde4c033-4e86-420c-a63e-0dd931031962" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" -version = "1.11.0" - -[[deps.AssociatedLegendrePolynomials]] -git-tree-sha1 = "c5b6a5ac656586d038dd04441b6e165a21c80f09" -uuid = "2119f1ac-fb78-50f5-8cc0-dda848ebdb19" -version = "1.0.2" - -[[deps.Atomix]] -deps = ["UnsafeAtomics"] -git-tree-sha1 = "b8651b2eb5796a386b0398a20b519a6a6150f75c" -uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" -version = "1.1.3" - - [deps.Atomix.extensions] - AtomixCUDAExt = "CUDA" - AtomixMetalExt = "Metal" - AtomixOpenCLExt = "OpenCL" - AtomixoneAPIExt = "oneAPI" - - [deps.Atomix.weakdeps] - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - Metal = "dde4c033-4e86-420c-a63e-0dd931031962" - OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" - oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" - -[[deps.AxisAlgorithms]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] -git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" -uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" -version = "1.1.0" - -[[deps.BFloat16s]] -deps = ["LinearAlgebra", "Printf", "Random"] -git-tree-sha1 = "e386db8b4753b42caac75ac81d0a4fe161a68a97" -uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" -version = "0.6.1" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" -version = "1.11.0" - -[[deps.BitFlags]] -git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.9" - -[[deps.BitInformation]] -deps = ["Distributions", "Random", "StatsBase"] -git-tree-sha1 = "2cf994e66a0886a91ba108cb3cfc044363f0bb01" -uuid = "de688a37-743e-4ac2-a6f0-bd62414d1aa7" -version = "0.6.3" - -[[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 = "535c80f1c0847a4c967ea945fca21becc9de1522" -uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" -version = "1.21.7+0" - -[[deps.Breeze]] -deps = ["Adapt", "Dates", "DocStringExtensions", "GPUArraysCore", "InteractiveUtils", "JLD2", "KernelAbstractions", "Oceananigans", "Printf", "Statistics"] -git-tree-sha1 = "4c487a3a17edd7ab11075f28fcd40332129343cd" -repo-rev = "main" -repo-url = "https://github.com/NumericalEarth/Breeze.jl/" -uuid = "660aa2fb-d4c8-4359-a52c-9c057bc511da" -version = "0.4.8" - - [deps.Breeze.extensions] - BreezeCloudMicrophysicsExt = ["CloudMicrophysics", "SpecialFunctions"] - BreezeRRTMGPExt = ["ClimaComms", "RRTMGP"] - BreezeReactantExt = "Reactant" - - [deps.Breeze.weakdeps] - ClimaComms = "3a4d1b5c-c61d-41fd-a00a-5873ba7a1b0d" - CloudMicrophysics = "6a9e3e04-43cd-43ba-94b9-e8782df3c71b" - RRTMGP = "a01a1ee8-cea4-48fc-987c-fc7878d79da1" - Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.BufferedStreams]] -git-tree-sha1 = "6863c5b7fc997eadcabdbaf6c5f201dc30032643" -uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" -version = "1.2.2" - -[[deps.Bzip2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" -uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.9+0" - -[[deps.CDSAPI]] -deps = ["Dates", "HTTP", "JSON", "ScopedValues"] -git-tree-sha1 = "5cc0e84538b4619208d63002e273056633f33553" -uuid = "8a7b9de3-9c00-473e-88b4-7eccd7ef2fea" -version = "2.2.2" - -[[deps.CEnum]] -git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" -uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.5.0" - -[[deps.CFTime]] -deps = ["Dates", "Printf"] -git-tree-sha1 = "b2c9f2d3b8014323c0a8f2b401b68fa6bb08ed06" -uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.2.8" - -[[deps.CPUSummary]] -deps = ["CpuId", "IfElse", "PrecompileTools", "Preferences", "Static"] -git-tree-sha1 = "f3a21d7fc84ba618a779d1ed2fcca2e682865bab" -uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.7" - -[[deps.CUDA]] -deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Compiler_jll", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] -git-tree-sha1 = "c876673fd63ca14d8e02dff5aa720fbea93e6584" -uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.11.2" - - [deps.CUDA.extensions] - ChainRulesCoreExt = "ChainRulesCore" - EnzymeCoreExt = "EnzymeCore" - SparseMatricesCSRExt = "SparseMatricesCSR" - SpecialFunctionsExt = "SpecialFunctions" - - [deps.CUDA.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - SparseMatricesCSR = "a0a7dd2c-ebf4-11e9-1f05-cf50bc540ca1" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.CUDA_Compiler_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "CUDA_Runtime_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "b977706846cb0a75d3842a1fed810ab2e6ab2f94" -uuid = "d1e2174e-dfdc-576e-b43e-73b79eb1aca8" -version = "0.4.3+0" - -[[deps.CUDA_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "TOML"] -git-tree-sha1 = "3b759ec65ac87ad192c2925114fa5c126657a5bd" -uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "13.2.1+0" - -[[deps.CUDA_Runtime_Discovery]] -deps = ["Libdl"] -git-tree-sha1 = "4fd010410c0c91c8b9bd6194a9ebdebecd9a8107" -uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "2.0.0" - -[[deps.CUDA_Runtime_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "c0314d9fb0ebd00e404feba4c3fbc04c9975abc1" -uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.21.0+1" - -[[deps.CatViews]] -deps = ["Random", "Test"] -git-tree-sha1 = "23d1f1e10d4e24374112fcf800ac981d14a54b24" -uuid = "81a5f4ea-a946-549a-aa7e-2a7f63a27d31" -version = "1.0.0" - -[[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "12177ad6b3cad7fd50c8b3825ce24a99ad61c18f" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.26.1" -weakdeps = ["SparseArrays"] - - [deps.ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[deps.ChunkCodecCore]] -git-tree-sha1 = "1a3ad7e16a321667698a19e77362b35a1e94c544" -uuid = "0b6fb165-00bc-4d37-ab8b-79f91016dbe1" -version = "1.0.1" - -[[deps.ChunkCodecLibZlib]] -deps = ["ChunkCodecCore", "Zlib_jll"] -git-tree-sha1 = "cee8104904c53d39eb94fd06cbe60cb5acde7177" -uuid = "4c0bbee4-addc-4d73-81a0-b6caacae83c8" -version = "1.0.0" - -[[deps.ChunkCodecLibZstd]] -deps = ["ChunkCodecCore", "Zstd_jll"] -git-tree-sha1 = "34d9873079e4cb3d0c62926a225136824677073f" -uuid = "55437552-ac27-4d47-9aa3-63184e8fd398" -version = "1.0.0" - -[[deps.ClimaSeaIce]] -deps = ["Adapt", "JLD2", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "813f90bc5583311d17767468df8e98209a96aa53" -uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.4.10" - -[[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 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.8" - -[[deps.ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.12.1" -weakdeps = ["StyledStrings"] - - [deps.ColorTypes.extensions] - StyledStringsExt = "StyledStrings" - -[[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.11.0" -weakdeps = ["SpecialFunctions"] - - [deps.ColorVectorSpace.extensions] - SpecialFunctionsExt = "SpecialFunctions" - -[[deps.Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.13.1" - -[[deps.CommonDataModel]] -deps = ["CFTime", "DataStructures", "Dates", "DiskArrays", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "bf07704e843daabd2cb2bb1404571656f80bce16" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.4.3" - -[[deps.CommonSolve]] -git-tree-sha1 = "78ea4ddbcf9c241827e7035c3a03e2e456711470" -uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.6" - -[[deps.CommonSubexpressions]] -deps = ["MacroTools"] -git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.1" - -[[deps.CommonWorldInvalidations]] -git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" -uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" -version = "1.0.0" - -[[deps.Compat]] -deps = ["TOML", "UUIDs"] -git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.18.1" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.3.0+1" - -[[deps.ComponentArrays]] -deps = ["Adapt", "ArrayInterface", "ChainRulesCore", "ConstructionBase", "Functors", "LinearAlgebra", "StaticArrayInterface", "StaticArraysCore"] -git-tree-sha1 = "342e21057cfa3152eb456ebcda25ed5ce3f0e275" -uuid = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66" -version = "0.15.37" - - [deps.ComponentArrays.extensions] - ComponentArraysGPUArraysExt = "GPUArrays" - ComponentArraysKernelAbstractionsExt = "KernelAbstractions" - ComponentArraysMooncakeExt = "Mooncake" - ComponentArraysOptimisersExt = "Optimisers" - ComponentArraysReactantExt = "Reactant" - ComponentArraysRecursiveArrayToolsExt = "RecursiveArrayTools" - ComponentArraysReverseDiffExt = "ReverseDiff" - ComponentArraysSciMLBaseExt = "SciMLBase" - ComponentArraysTrackerExt = "Tracker" - ComponentArraysZygoteExt = "Zygote" - - [deps.ComponentArrays.weakdeps] - GPUArrays = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" - KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" - Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" - Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2" - Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" - RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" - -[[deps.CompositeTypes]] -git-tree-sha1 = "bce26c3dab336582805503bed209faab1c279768" -uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657" -version = "0.1.4" - -[[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 = "21d088c496ea22914fe80906eb5bce65755e5ec8" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.5.1" - -[[deps.CondaPkg]] -deps = ["JSON", "Markdown", "MicroMamba", "Pidfile", "Pkg", "Preferences", "Scratch", "TOML", "pixi_jll"] -git-tree-sha1 = "0300af904a8c8d41ff715a60a6959136d22b8572" -uuid = "992eb4ea-22a4-4c89-a5bb-47a3300528ab" -version = "0.2.34" - -[[deps.ConstructionBase]] -git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.6.0" -weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseLinearAlgebraExt = "LinearAlgebra" - ConstructionBaseStaticArraysExt = "StaticArrays" - -[[deps.CopernicusMarine]] -deps = ["CondaPkg", "PythonCall"] -git-tree-sha1 = "9ec0ad703214ef341cf59496a48060f323eccaf9" -uuid = "cd43e856-93a3-40c8-bc9e-6146cdce14fa" -version = "0.1.1" - -[[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 = ["Distances", "LinearAlgebra", "Printf", "Random", "Statistics", "TaylorSeries"] -git-tree-sha1 = "6ffea589cf350b1582722e57a8de787907d59454" -uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.3.4" - -[[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", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "5fab31e2e01e70ad66e3e24c968c264d1cf166d6" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.8.2" - -[[deps.DataStructures]] -deps = ["OrderedCollections"] -git-tree-sha1 = "e86f4a2805f7f19bec5129bc9150c38208e5dc23" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.19.4" - -[[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" -version = "1.11.0" - -[[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 = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] -git-tree-sha1 = "e5d9ce1b751ddf9bcd9d36b51249dce8ea73cd55" -uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.4.19" - -[[deps.Distances]] -deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.12" -weakdeps = ["ChainRulesCore", "SparseArrays"] - - [deps.Distances.extensions] - DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesSparseArraysExt = "SparseArrays" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" -version = "1.11.0" - -[[deps.Distributions]] -deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "e421c1938fafab0165b04dc1a9dbe2a26272952c" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.125" - - [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]] -git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.5" - -[[deps.DomainSets]] -deps = ["CompositeTypes", "FunctionMaps", "IntervalSets", "LinearAlgebra", "StaticArrays"] -git-tree-sha1 = "4599e0cd684f3ff6cbbab73c77553a3d01a8d74d" -uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" -version = "0.7.18" - - [deps.DomainSets.extensions] - DomainSetsMakieExt = "Makie" - DomainSetsRandomExt = "Random" - - [deps.DomainSets.weakdeps] - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.7.0" - -[[deps.EnumX]] -git-tree-sha1 = "c49898e8438c828577f04b92fc9368c388ac783c" -uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" -version = "1.0.7" - -[[deps.Enzyme]] -deps = ["CEnum", "EnzymeCore", "Enzyme_jll", "GPUCompiler", "InteractiveUtils", "LLVM", "Libdl", "LinearAlgebra", "ObjectFile", "PrecompileTools", "Preferences", "Printf", "Random", "SparseArrays"] -git-tree-sha1 = "d6dd65421104fa9f7d5cc37283a998937f359a39" -uuid = "7da242da-08ed-463a-9acd-ee780be4f1d9" -version = "0.13.138" - - [deps.Enzyme.extensions] - EnzymeBFloat16sExt = "BFloat16s" - EnzymeChainRulesCoreExt = "ChainRulesCore" - EnzymeGPUArraysCoreExt = "GPUArraysCore" - EnzymeLogExpFunctionsExt = "LogExpFunctions" - EnzymeSpecialFunctionsExt = "SpecialFunctions" - EnzymeStaticArraysExt = "StaticArrays" - - [deps.Enzyme.weakdeps] - ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" - BFloat16s = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.EnzymeCore]] -git-tree-sha1 = "24bbb6fc8fb87eb71c1f8d00184a60fc22c63903" -uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" -version = "0.8.19" -weakdeps = ["Adapt", "ChainRulesCore"] - - [deps.EnzymeCore.extensions] - AdaptExt = "Adapt" - EnzymeCoreChainRulesCoreExt = "ChainRulesCore" - -[[deps.Enzyme_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "4c22000e08aaa862526d9a41cfb7003e4002e653" -uuid = "7cc45869-7501-5eee-bdea-0790c847d4ef" -version = "0.0.256+0" - -[[deps.ExceptionUnwrapping]] -deps = ["Test"] -git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" -uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" -version = "0.1.11" - -[[deps.ExprTools]] -git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" -uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.10" - -[[deps.ExpressionExplorer]] -git-tree-sha1 = "5f1c005ed214356bbe41d442cc1ccd416e510b7e" -uuid = "21656369-7473-754a-2065-74616d696c43" -version = "1.1.4" - -[[deps.Extents]] -git-tree-sha1 = "b309b36a9e02fe7be71270dd8c0fd873625332b4" -uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.6" - -[[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "97f08406df914023af55ade2f843c39e99c5d969" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.10.0" - -[[deps.FFTW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6866aec60ef98e3164cd8d6855225684207e9dff" -uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.12+0" - -[[deps.FastGaussQuadrature]] -deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] -git-tree-sha1 = "0044e9f5e49a57e88205e8f30ab73928b05fe5b6" -uuid = "442a2c76-b920-505d-bb47-c5924d526838" -version = "1.1.0" - -[[deps.FieldMetadata]] -git-tree-sha1 = "c279c6eab9767a3f62685e5276c850512e0a1afd" -uuid = "bf96fef3-21d2-5d20-8afa-0e7d4c32a885" -version = "0.3.1" - -[[deps.FileIO]] -deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "6522cfb3b8fe97bec632252263057996cbd3de20" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.18.0" -weakdeps = ["HTTP"] - - [deps.FileIO.extensions] - HTTPExt = "HTTP" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" -version = "1.11.0" - -[[deps.FillArrays]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "2f979084d1e13948a3352cf64a25df6bd3b4dca3" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.16.0" -weakdeps = ["PDMats", "SparseArrays", "StaticArrays", "Statistics"] - - [deps.FillArrays.extensions] - FillArraysPDMatsExt = "PDMats" - FillArraysSparseArraysExt = "SparseArrays" - FillArraysStaticArraysExt = "StaticArrays" - FillArraysStatisticsExt = "Statistics" - -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" - -[[deps.Flatten]] -deps = ["ConstructionBase", "FieldMetadata"] -git-tree-sha1 = "d3541c658c7e452fefba6c933c43842282cdfd3e" -uuid = "4c728ea3-d9ee-5c9a-9642-b6f7d7dc04fa" -version = "0.4.3" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "cddeab6487248a39dae1a960fff0ac17b2a28888" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.3.3" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.FunctionMaps]] -deps = ["CompositeTypes", "LinearAlgebra", "StaticArrays"] -git-tree-sha1 = "31bd99a57edf98990d1c21486032963955450e8d" -uuid = "a85aefff-f8ca-4649-a888-c8e5398bc76c" -version = "0.1.2" - -[[deps.Functors]] -deps = ["Compat", "ConstructionBase", "LinearAlgebra", "Random"] -git-tree-sha1 = "60a0339f28a233601cb74468032b5c302d5067de" -uuid = "d9f16b24-f501-4c13-a1f2-28368ffc5196" -version = "0.5.2" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" -version = "1.11.0" - -[[deps.GPUArrays]] -deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "SparseArrays", "Statistics"] -git-tree-sha1 = "34fd745547978beb471f029f447290ef4dbc7bbd" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "11.5.3" -weakdeps = ["JLD2"] - - [deps.GPUArrays.extensions] - JLD2Ext = "JLD2" - -[[deps.GPUArraysCore]] -deps = ["Adapt"] -git-tree-sha1 = "83cf05ab16a73219e5f6bd1bdfa9848fa24ac627" -uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.2.0" - -[[deps.GPUCompiler]] -deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "PrecompileTools", "Preferences", "Scratch", "Serialization", "TOML", "Tracy", "UUIDs"] -git-tree-sha1 = "fedfe5e7db7035271c3f58359007f971da1dde87" -uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "1.9.1" - -[[deps.GPUToolbox]] -deps = ["LLVM"] -git-tree-sha1 = "a589b6c1a0eff953571f5d8b0474f5020831114d" -uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" -version = "1.1.1" - -[[deps.GenericFFT]] -deps = ["AbstractFFTs", "FFTW", "LinearAlgebra", "Reexport"] -git-tree-sha1 = "5029b303ba330e2c94ea3237b0e20df44aaab75e" -uuid = "a8297547-1b15-4a5a-a998-a2ac5f1cef28" -version = "0.1.7" - -[[deps.GeoFormatTypes]] -git-tree-sha1 = "7528a7956248c723d01a0a9b0447bf254bf4da52" -uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f" -version = "0.4.5" - -[[deps.GeoInterface]] -deps = ["DataAPI", "Extents", "GeoFormatTypes"] -git-tree-sha1 = "2b0312a0c06b4408773c6dc1829b472ea706f058" -uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.6.1" - - [deps.GeoInterface.extensions] - GeoInterfaceMakieExt = ["Makie", "GeometryBasics"] - GeoInterfaceRecipesBaseExt = "RecipesBase" - - [deps.GeoInterface.weakdeps] - GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" - -[[deps.Glob]] -git-tree-sha1 = "83cb0092e2792b9e3a865b6655e88f5b862607e2" -uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" -version = "1.4.0" - -[[deps.HDF5_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "MPIABI_jll", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "aws_c_s3_jll", "dlfcn_win32_jll", "libaec_jll", "mpif_jll"] -git-tree-sha1 = "45337643a2d97262d5fe72ce1f13e8a662d13d62" -uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" -version = "2.1.2+0" - -[[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "51059d23c8bb67911a2e6fd5130229113735fc7e" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.11.0" - -[[deps.HashArrayMappedTries]] -git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" -uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" -version = "0.2.0" - -[[deps.HostCPUFeatures]] -deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Preferences", "Static"] -git-tree-sha1 = "af9ab7d1f70739a47f03be78771ebda38c3c71bf" -uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.18" - -[[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "XML2_jll", "Xorg_libpciaccess_jll"] -git-tree-sha1 = "baaaebd42ed9ee1bd9173cfd56910e55a8622ee1" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.13.0+1" - -[[deps.HypergeometricFunctions]] -deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" -uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.28" - -[[deps.IOCapture]] -deps = ["Logging", "Random"] -git-tree-sha1 = "0ee181ec08df7d7c911901ea38baf16f755114dc" -uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "1.0.0" - -[[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 = "8c193230235bbcee22c8066b0374f63b5683c2d3" -uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" -version = "0.10.5" - -[[deps.ImageMorphology]] -deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] -git-tree-sha1 = "895205d762ae24a01689f8cc7ad584b55f1fd005" -uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" -version = "0.4.7" - -[[deps.InlineStrings]] -git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.5" - - [deps.InlineStrings.extensions] - ArrowTypesExt = "ArrowTypes" - ParsersExt = "Parsers" - - [deps.InlineStrings.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" - -[[deps.Inpaintings]] -deps = ["LinearAlgebra", "Match", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "aa4e89ed3dcb4cc854ac386cbdcfa3c3b3de4f87" -uuid = "a3d749fb-087c-5225-80b3-65fbd02ae0fd" -version = "0.3.1" - -[[deps.IntegerMathUtils]] -git-tree-sha1 = "4c1acff2dc6b6967e7e750633c50bc3b8d83e617" -uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" -version = "0.1.3" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "ec1debd61c300961f98064cfb21287613ad7f303" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2025.2.0+0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" -version = "1.11.0" - -[[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" -weakdeps = ["Unitful"] - - [deps.Interpolations.extensions] - InterpolationsUnitfulExt = "Unitful" - -[[deps.IntervalSets]] -git-tree-sha1 = "79d6bd28c8d9bccc2229784f1bd637689b256377" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.14" - - [deps.IntervalSets.extensions] - IntervalSetsRandomExt = "Random" - IntervalSetsRecipesBaseExt = "RecipesBase" - IntervalSetsStatisticsExt = "Statistics" - - [deps.IntervalSets.weakdeps] - Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[deps.InverseFunctions]] -git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb" -uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.17" -weakdeps = ["Dates", "Test"] - - [deps.InverseFunctions.extensions] - InverseFunctionsDatesExt = "Dates" - InverseFunctionsTestExt = "Test" - -[[deps.InvertedIndices]] -git-tree-sha1 = "6da3c4316095de0f5ee2ebd875df8721e7e0bdbe" -uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" -version = "1.3.1" - -[[deps.IrrationalConstants]] -git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.6" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[deps.JLD2]] -deps = ["ChunkCodecLibZlib", "ChunkCodecLibZstd", "FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues"] -git-tree-sha1 = "941f87a0ae1b14d1ac2fa57245425b23a9d7a516" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.6.4" -weakdeps = ["UnPack"] - - [deps.JLD2.extensions] - UnPackExt = "UnPack" - -[[deps.JLLWrappers]] -deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.7.1" - -[[deps.JSON]] -deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"] -git-tree-sha1 = "67c6f1f085cb2671c93fe34244c9cccde30f7a26" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "1.5.0" - - [deps.JSON.extensions] - JSONArrowExt = ["ArrowTypes"] - - [deps.JSON.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.JuliaSyntaxHighlighting]] -deps = ["StyledStrings"] -uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" -version = "1.12.0" - -[[deps.KernelAbstractions]] -deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] -git-tree-sha1 = "f2e76d3ced51a2a9e185abc0b97494c7273f649f" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.41" -weakdeps = ["EnzymeCore", "LinearAlgebra", "SparseArrays"] - - [deps.KernelAbstractions.extensions] - EnzymeExt = "EnzymeCore" - LinearAlgebraExt = "LinearAlgebra" - SparseArraysExt = "SparseArrays" - -[[deps.Krylov]] -deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "c4d19f51afc7ba2afbe32031b8f2d21b11c9e26e" -uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.10.6" - -[[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "PrecompileTools", "Preferences", "Printf", "Unicode"] -git-tree-sha1 = "c0cec0c63687dda0115a51fe04d8f75902e181b3" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "9.6.0" -weakdeps = ["BFloat16s"] - - [deps.LLVM.extensions] - BFloat16sExt = "BFloat16s" - -[[deps.LLVMExtra_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "721fcd02aa06f8b2ed58d8db9914beab7a274b69" -uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.41+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 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" -uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "18.1.8+0" - -[[deps.LRUCache]] -git-tree-sha1 = "5519b95a490ff5fe629c4a7aa3b3dfc9160498b3" -uuid = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" -version = "1.6.2" -weakdeps = ["Serialization"] - - [deps.LRUCache.extensions] - SerializationExt = ["Serialization"] - -[[deps.LaTeXStrings]] -git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" -uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.4.0" - -[[deps.LayoutPointers]] -deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "a9eaadb366f5493a5654e843864c13d8b107548c" -uuid = "10f19ff3-798f-405d-979b-55457f8fc047" -version = "0.1.17" - -[[deps.LazyArtifacts]] -deps = ["Artifacts", "Pkg"] -uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" -version = "1.11.0" - -[[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", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.15.0+0" - -[[deps.LibGit2]] -deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" -version = "1.11.0" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.9.0+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "OpenSSL_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.3+1" - -[[deps.LibTracyClient_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d4e20500d210247322901841d4eafc7a0c52642d" -uuid = "ad6e5548-8b26-5c9f-8ef3-ef0ad883f3a5" -version = "0.13.1+0" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" -version = "1.11.0" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.18.0+0" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -version = "1.12.0" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.29" - - [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" -version = "1.11.0" - -[[deps.LoggingExtras]] -deps = ["Dates", "Logging"] -git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" -uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.2.0" - -[[deps.LoopVectorization]] -deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "a9fc7883eb9b5f04f46efb9a540833d1fad974b3" -uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.173" - - [deps.LoopVectorization.extensions] - ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] - ForwardDiffNNlibExt = ["ForwardDiff", "NNlib"] - SpecialFunctionsExt = "SpecialFunctions" - - [deps.LoopVectorization.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.LowerTriangularArrays]] -deps = ["Adapt", "DocStringExtensions", "GPUArrays", "KernelAbstractions", "LinearAlgebra", "SpeedyWeatherInternals"] -git-tree-sha1 = "bd7e64ab00ef86d7c501dbf728601af434967c65" -uuid = "ed20b33f-a660-45d0-a353-9c8c20bb5814" -version = "0.1.2" - - [deps.LowerTriangularArrays.extensions] - LowerTriangularArraysFiniteDifferencesExt = "FiniteDifferences" - - [deps.LowerTriangularArrays.weakdeps] - FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" - -[[deps.Lz4_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "191686b1ac1ea9c89fc52e996ad15d1d241d1e33" -uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" -version = "1.10.1+0" - -[[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] -git-tree-sha1 = "282cadc186e7b2ae0eeadbd7a4dffed4196ae2aa" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2025.2.0+0" - -[[deps.MPI]] -deps = ["Distributed", "DocStringExtensions", "Libdl", "MPIABI_jll", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Serialization", "Sockets"] -git-tree-sha1 = "ff6309186ff377782d01f6577d19ae1b5f5185c5" -uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" -version = "0.20.26" - - [deps.MPI.extensions] - AMDGPUExt = "AMDGPU" - CUDAExt = "CUDA" - - [deps.MPI.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - -[[deps.MPIABI_jll]] -deps = ["Artifacts", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "9be143b6045719e8fb019d2b3bc2aebad1184fef" -uuid = "b5ada748-db0f-5fc0-8972-9331c762740c" -version = "0.1.5+0" - -[[deps.MPICH_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "07dbec8aab01696edc0151a401a6cdfe95b9b885" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "5.0.1+0" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "8e98d5d80b87403c311fd51e8455d4546ba7a5f8" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.12" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "675df097f8eeb28998b2cfe3b25655af73d5f7df" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.5.6+0" - -[[deps.MacroTools]] -git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.16" - -[[deps.Malt]] -deps = ["Distributed", "Logging", "RelocatableFolders", "Serialization", "Sockets"] -git-tree-sha1 = "c2335b4e291f2422e2be8abf8936ccad58a98992" -uuid = "36869731-bdee-424d-aa32-cab38c994e3b" -version = "1.4.1" - -[[deps.ManualMemory]] -git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" -uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" -version = "0.1.8" - -[[deps.MappedArrays]] -git-tree-sha1 = "0ee4497a4e80dbd29c058fcee6493f5219556f40" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.3" - -[[deps.Markdown]] -deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" -version = "1.11.0" - -[[deps.Match]] -deps = ["MacroTools", "OrderedCollections"] -git-tree-sha1 = "58c5c5db26f2f0512facb359991410b7b5982c38" -uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf" -version = "2.4.1" - -[[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "8785729fa736197687541f7053f6d8ab7fc44f92" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.10" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "ff69a2b1330bcb730b9ac1ab7dd680176f5896b8" -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.1010+0" - -[[deps.MeshArrays]] -deps = ["CatViews", "Dates", "Distributed", "GeoInterface", "Glob", "LazyArtifacts", "NearestNeighbors", "Pkg", "Printf", "SharedArrays", "SparseArrays", "Statistics", "Unitful"] -git-tree-sha1 = "aa4d4dac4dd237c53fc9c8dcd1771acb216b357a" -uuid = "cb8c808f-1acf-59a3-9d2b-6e38d009f683" -version = "0.5.5" - - [deps.MeshArrays.extensions] - MeshArraysDataDepsExt = ["DataDeps"] - MeshArraysGeoJSONExt = ["GeoJSON"] - MeshArraysGeometryOpsExt = ["GeometryOps"] - MeshArraysJLD2Ext = ["JLD2"] - MeshArraysMakieExt = ["Makie"] - MeshArraysProjExt = ["Proj"] - MeshArraysShapefileExt = ["Shapefile"] - - [deps.MeshArrays.weakdeps] - DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" - GeoJSON = "61d90e0f-e114-555e-ac52-39dfb47a3ef9" - GeometryOps = "3251bfac-6a57-4b6d-aa61-ac1fef2975ab" - JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - Proj = "c94c279d-25a6-4763-9509-64d165bea63e" - Shapefile = "8e980c4a-a4fe-5da2-b3a7-4b4b0353a2f4" - -[[deps.MicroMamba]] -deps = ["Pkg", "Scratch", "micromamba_jll"] -git-tree-sha1 = "535656ce55266bfed0575cd051acc4f36dc869a0" -uuid = "0b3b1443-0f03-428d-bdfb-f27f9c1191ea" -version = "0.1.15" - -[[deps.MicrosoftMPI_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "bc95bf4149bf535c09602e3acdf950d9b4376227" -uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf" -version = "10.1.4+3" - -[[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" -version = "1.11.0" - -[[deps.ModelParameters]] -deps = ["AbstractNumbers", "ConstructionBase", "Flatten", "PrettyTables", "Setfield", "Tables"] -git-tree-sha1 = "6ba99217d1f748115c2edab0bdd56b9fe4e5b795" -uuid = "4744a3fa-6c31-4707-899e-a3298e4618ad" -version = "0.4.6" - - [deps.ModelParameters.extensions] - ModelParametersMakieExt = "Makie" - ModelParametersUnitfulExt = "Unitful" - - [deps.ModelParameters.weakdeps] - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - -[[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 = "2025.11.4" - -[[deps.MuladdMacro]] -git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" -uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -version = "0.2.4" - -[[deps.NCDatasets]] -deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "5eb7747d10437f5acb2675c1f865ffa0353f3f9c" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.15" -weakdeps = ["MPI"] - - [deps.NCDatasets.extensions] - NCDatasetsMPIExt = "MPI" - -[[deps.NVTX]] -deps = ["JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] -git-tree-sha1 = "a9083c3e469e63cca454d1fc3b19472d9d92c14a" -uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" -version = "1.0.3" -weakdeps = ["Colors"] - - [deps.NVTX.extensions] - NVTXColorsExt = "Colors" - -[[deps.NVTX_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "af2232f69447494514c25742ba1503ec7e9877fe" -uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" -version = "3.2.2+0" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.1.3" - -[[deps.NearestNeighbors]] -deps = ["AbstractTrees", "Distances", "StaticArrays"] -git-tree-sha1 = "e2c3bba08dd6dedfe17a17889131b885b8c082f0" -uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" -version = "0.4.27" - -[[deps.NetCDF_jll]] -deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPIABI_jll", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML", "XML2_jll", "Zlib_jll", "Zstd_jll", "libaec_jll", "libzip_jll"] -git-tree-sha1 = "8a36db9b934b0e72583e624abc8f3b3d60554f2c" -uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" -version = "401.1000.0+0" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.3.0" - -[[deps.NumericalEarth]] -deps = ["Adapt", "CFTime", "ClimaSeaIce", "CubedSphere", "DataDeps", "Dates", "Distances", "DocStringExtensions", "Downloads", "GPUArraysCore", "Glob", "ImageMorphology", "JLD2", "KernelAbstractions", "MeshArrays", "NCDatasets", "Oceananigans", "OffsetArrays", "PrecompileTools", "Printf", "Scratch", "SeawaterPolynomials", "StaticArrays", "Statistics", "Thermodynamics", "ZipFile"] -path = ".." -uuid = "904d977b-046a-4731-8b86-9235c0d1ef02" -version = "0.3.0" -weakdeps = ["Breeze", "CDSAPI", "CondaPkg", "CopernicusMarine", "PythonCall", "Reactant", "SpeedyWeather", "WorldOceanAtlasTools", "XESMF"] - - [deps.NumericalEarth.extensions] - NumericalEarthBreezeExt = "Breeze" - NumericalEarthCDSAPIExt = "CDSAPI" - NumericalEarthCopernicusMarineExt = "CopernicusMarine" - NumericalEarthReactantExt = "Reactant" - NumericalEarthSpeedyWeatherExt = ["SpeedyWeather", "XESMF"] - NumericalEarthVerosExt = ["PythonCall", "CondaPkg"] - NumericalEarthWOAExt = "WorldOceanAtlasTools" - -[[deps.ObjectFile]] -deps = ["Reexport", "StructIO"] -git-tree-sha1 = "22faba70c22d2f03e60fbc61da99c4ebfc3eb9ba" -uuid = "d8793406-e978-5875-9003-1fc021f44a92" -version = "0.5.0" - -[[deps.OceanGrids]] -deps = ["Inpaintings", "Interpolations", "LinearAlgebra", "NearestNeighbors", "SparseArrays", "Unitful"] -git-tree-sha1 = "7c17f4245c6fe4e69fdeedc49572c2547c9a073f" -uuid = "cfe838f4-859f-11e9-2ea1-df7d4e7c3537" -version = "0.4.6" - -[[deps.Oceananigans]] -deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "865afaee507b963d35c4df498af9f51c487a1198" -uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.107.3" - - [deps.Oceananigans.extensions] - OceananigansAMDGPUExt = ["AMDGPU", "AbstractFFTs"] - OceananigansCUDAExt = ["CUDA", "GPUArrays", "GPUArraysCore"] - OceananigansEnzymeExt = "Enzyme" - OceananigansMakieExt = "Makie" - OceananigansMetalExt = "Metal" - OceananigansNCDatasetsExt = "NCDatasets" - OceananigansOneAPIExt = "oneAPI" - OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase", "AbstractFFTs"] - OceananigansXESMFExt = ["XESMF"] - - [deps.Oceananigans.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - GPUArrays = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - Metal = "dde4c033-4e86-420c-a63e-0dd931031962" - NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" - Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" - XESMF = "2e0b0046-e7a1-486f-88de-807ee8ffabe5" - oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" - -[[deps.OffsetArrays]] -git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.17.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.29+0" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.7+0" - -[[deps.OpenMPI_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] -git-tree-sha1 = "6d6c0ca4824268c1a7dca1f4721c535ac63d9074" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.11+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "NetworkOptions", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "1d1aaa7d449b58415f97d2839c318b70ffb525a0" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.6.1" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.4+0" - -[[deps.OpenSpecFun_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" -uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" -version = "0.5.6+0" - -[[deps.OrderedCollections]] -git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.8.1" - -[[deps.PDMats]] -deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "e4cff168707d441cd6bf3ff7e4832bdf34278e4a" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.37" -weakdeps = ["StatsBase"] - - [deps.PDMats.extensions] - StatsBaseExt = "StatsBase" - -[[deps.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[deps.ParallelTestRunner]] -deps = ["Dates", "IOCapture", "Malt", "Printf", "Random", "Scratch", "Serialization", "Statistics", "Test"] -git-tree-sha1 = "1b6dd742aa3598dbca6bc2cc20a65c9819c1f42f" -uuid = "d3525ed8-44d0-4b2c-a655-542cee43accc" -version = "2.6.0" - -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.3" - -[[deps.Pidfile]] -deps = ["FileWatching", "Test"] -git-tree-sha1 = "2d8aaf8ee10df53d0dfb9b8ee44ae7c04ced2b03" -uuid = "fa939f87-e72e-5be4-a000-7fc836dbe307" -version = "1.3.0" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.12.1" -weakdeps = ["REPL"] - - [deps.Pkg.extensions] - REPLExt = "REPL" - -[[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 = "645bed98cd47f72f67316fd42fc47dee771aefcd" -uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" -version = "0.2.2" - -[[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 = "07a921781cab75691315adc645096ed5e370cb77" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.3.3" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "8b770b60760d4451834fe79dd483e318eee709c4" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.5.2" - -[[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "624de6279ab7d94fc9f672f0068107eb6619732c" -uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "3.3.2" - - [deps.PrettyTables.extensions] - PrettyTablesTypstryExt = "Typstry" - - [deps.PrettyTables.weakdeps] - Typstry = "f0ed7684-a786-439e-b1e3-3b82803b501e" - -[[deps.Primes]] -deps = ["IntegerMathUtils"] -git-tree-sha1 = "25cdd1d20cd005b52fc12cb6be3f75faaf59bb9b" -uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.5.7" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" -version = "1.11.0" - -[[deps.ProgressMeter]] -deps = ["Distributed", "Printf"] -git-tree-sha1 = "fbb92c6c56b34e1a2c4c36058f68f332bec840e7" -uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.11.0" - -[[deps.ProtoBuf]] -deps = ["BufferedStreams", "EnumX", "TOML"] -git-tree-sha1 = "da18083a52d9d57bbe6dadaacad39731e5f7be39" -uuid = "3349acd9-ac6a-5e09-bcdb-63829b23a429" -version = "1.3.0" - -[[deps.PtrArrays]] -git-tree-sha1 = "4fbbafbc6251b883f4d2705356f3641f3652a7fe" -uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" -version = "1.4.0" - -[[deps.PythonCall]] -deps = ["CondaPkg", "Dates", "Libdl", "MacroTools", "Markdown", "Pkg", "Serialization", "Tables", "UnsafePointers"] -git-tree-sha1 = "982f3f017f08d31202574ef6bdcf8b3466430bea" -uuid = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" -version = "0.9.31" - - [deps.PythonCall.extensions] - CategoricalArraysExt = "CategoricalArrays" - PyCallExt = "PyCall" - - [deps.PythonCall.weakdeps] - CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597" - PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" - -[[deps.QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "5e8e8b0ab68215d7a2b14b9921a946fee794749e" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.11.3" -weakdeps = ["Enzyme"] - - [deps.QuadGK.extensions] - QuadGKEnzymeExt = "Enzyme" - -[[deps.Quaternions]] -deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "4d8c1b7c3329c1885b857abb50d08fa3f4d9e3c8" -uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.7" - -[[deps.REPL]] -deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" -version = "1.11.0" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -version = "1.11.0" - -[[deps.Random123]] -deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "dbe5fd0b334694e905cb9fda73cd8554333c46e2" -uuid = "74087812-796a-5b5d-8853-05524746bad3" -version = "1.7.1" - -[[deps.RandomNumbers]] -deps = ["Random"] -git-tree-sha1 = "c6ec94d2aaba1ab2ff983052cf6a606ca5985902" -uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" -version = "1.6.0" - -[[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.Reactant]] -deps = ["Adapt", "BFloat16s", "CEnum", "Crayons", "Downloads", "EnumX", "Enzyme", "EnzymeCore", "FileWatching", "Functors", "GPUArraysCore", "GPUCompiler", "HTTP", "JSON", "LLVM", "LLVMOpenMP_jll", "Libdl", "LinearAlgebra", "OrderedCollections", "PrecompileTools", "Preferences", "PrettyTables", "ProtoBuf", "Random", "ReactantCore", "Reactant_jll", "ScopedValues", "Scratch", "Serialization", "Setfield", "Sockets", "StableRNGs", "StructUtils", "StyledStrings", "UUIDs", "p7zip_jll"] -git-tree-sha1 = "e02293894a505abfc68ef5e0743d6035d411c64f" -uuid = "3c362404-f566-11ee-1572-e11a4b42c853" -version = "0.2.254" - - [deps.Reactant.extensions] - ReactantAbstractFFTsExt = "AbstractFFTs" - ReactantArrayInterfaceExt = "ArrayInterface" - ReactantCUDAExt = ["CUDA", "Enzyme", "GPUCompiler", "KernelAbstractions", "LLVM", "Printf"] - ReactantDLFP8TypesExt = "DLFP8Types" - ReactantDatesExt = "Dates" - ReactantFFTWExt = ["FFTW", "AbstractFFTs", "LinearAlgebra"] - ReactantFillArraysExt = "FillArrays" - ReactantFloat8sExt = "Float8s" - ReactantKernelAbstractionsExt = "KernelAbstractions" - ReactantLogExpFunctionsExt = ["IrrationalConstants", "LogExpFunctions"] - ReactantMCMCDiagnosticToolsExt = ["MCMCDiagnosticTools", "Statistics"] - ReactantMPIExt = "MPI" - ReactantNNlibExt = ["NNlib", "Statistics"] - ReactantNPZExt = "NPZ" - ReactantOffsetArraysExt = "OffsetArrays" - ReactantOneHotArraysExt = "OneHotArrays" - ReactantPythonCallExt = "PythonCall" - ReactantRandom123Ext = "Random123" - ReactantSparseArraysExt = "SparseArrays" - ReactantSpecialFunctionsExt = "SpecialFunctions" - ReactantStaticArraysExt = "StaticArrays" - ReactantStatisticsExt = "Statistics" - ReactantStructArraysExt = "StructArrays" - ReactantYaoBlocksExt = "YaoBlocks" - ReactantZygoteExt = "Zygote" - - [deps.Reactant.weakdeps] - AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c" - ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - DLFP8Types = "f4c16678-4a16-415b-82ef-ed337c5d6c7c" - Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" - FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" - FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" - Float8s = "81dfefd7-55b0-40c6-a251-db853704e186" - IrrationalConstants = "92d709cd-6900-40b7-9082-c6be49f344b6" - KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" - LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" - MCMCDiagnosticTools = "be115224-59cd-429b-ad48-344e309966f0" - MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" - NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" - NPZ = "15e1cf62-19b3-5cfa-8e77-841668bca605" - OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" - OneHotArrays = "0b1bfda6-eb8a-41d2-88d8-f5af5cad476f" - Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" - PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" - Random123 = "74087812-796a-5b5d-8853-05524746bad3" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" - YaoBlocks = "418bc28f-b43b-5e0b-a6e7-61bbc1a2c1df" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" - -[[deps.ReactantCore]] -deps = ["ExpressionExplorer", "MacroTools"] -git-tree-sha1 = "5b9e0fe7fb2cf3794fd96ac32bf2732aa4bb9776" -uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" -version = "0.1.19" - -[[deps.Reactant_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "2749c35cb1bcc588ad71a50acf19108b9c6e47ed" -uuid = "0192cb87-2b54-54ad-80e0-3be72ad8a3c0" -version = "0.0.371+0" - -[[deps.RealDot]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" -uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" -version = "0.1.0" - -[[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 = "62389eeff14780bfe55195b7204c0d8738436d64" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.1" - -[[deps.RingGrids]] -deps = ["Adapt", "Artifacts", "DocStringExtensions", "FastGaussQuadrature", "GPUArrays", "KernelAbstractions", "LinearAlgebra", "Pkg", "Printf", "SpeedyWeatherInternals", "Statistics"] -git-tree-sha1 = "fc7e92d38be29d68df9af3d97d2f1d3a7e8fcab4" -uuid = "d1845624-ad4f-453b-8ff4-a8db365bf3a7" -version = "0.1.3" - - [deps.RingGrids.extensions] - RingGridsFiniteDifferencesExt = "FiniteDifferences" - RingGridsGeoMakieExt = "GeoMakie" - RingGridsMakieExt = "Makie" - RingGridsNCDatasetsExt = "NCDatasets" - - [deps.RingGrids.weakdeps] - FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" - GeoMakie = "db073c08-6b98-4ee5-b6a4-5efafb3259c6" - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" - -[[deps.Rmath]] -deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "5b3d50eb374cea306873b371d3f8d3915a018f0b" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.9.0" - -[[deps.Rmath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.5.1+0" - -[[deps.RootSolvers]] -deps = ["ForwardDiff", "Printf"] -git-tree-sha1 = "3b6c0089c3dc3d5780786d5007e976fe9d1b7887" -uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" -version = "1.0.2" - -[[deps.Roots]] -deps = ["Accessors", "CommonSolve", "Printf"] -git-tree-sha1 = "3eff988b9bd09543783e2e051b0a1eef11f65c2d" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.3.0" - - [deps.Roots.extensions] - RootsChainRulesCoreExt = "ChainRulesCore" - RootsForwardDiffExt = "ForwardDiff" - RootsIntervalRootFindingExt = "IntervalRootFinding" - RootsSymPyExt = "SymPy" - RootsSymPyPythonCallExt = "SymPyPythonCall" - RootsUnitfulExt = "Unitful" - - [deps.Roots.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" - SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" - SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - -[[deps.Rotations]] -deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.1" - - [deps.Rotations.extensions] - RotationsRecipesBaseExt = "RecipesBase" - - [deps.Rotations.weakdeps] - RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" - -[[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 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" -uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" -version = "0.6.43" - -[[deps.SciMLPublic]] -git-tree-sha1 = "0ba076dbdce87ba230fff48ca9bca62e1f345c9b" -uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" -version = "1.0.1" - -[[deps.ScopedValues]] -deps = ["HashArrayMappedTries", "Logging"] -git-tree-sha1 = "ac4b837d89a58c848e85e698e2a2514e9d59d8f6" -uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" -version = "1.6.0" - -[[deps.Scratch]] -deps = ["Dates"] -git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" -uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.3.0" - -[[deps.SeawaterPolynomials]] -git-tree-sha1 = "e2671e9abe2a2faa51dcecd9d911522931c16012" -uuid = "d496a93d-167e-4197-9f49-d3af4ff8fe40" -version = "0.3.10" - -[[deps.SentinelArrays]] -deps = ["Dates", "Random"] -git-tree-sha1 = "ebe7e59b37c400f694f52b58c93d26201387da70" -uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.9" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -version = "1.11.0" - -[[deps.Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "c5391c6ace3bc430ca630251d02ea9687169ca68" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.2" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" -version = "1.11.0" - -[[deps.SimpleBufferStream]] -git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.2.0" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" -version = "1.11.0" - -[[deps.SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.2" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.12.0" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "2700b235561b0335d5bef7097a111dc513b8655e" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.7.2" -weakdeps = ["ChainRulesCore"] - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - -[[deps.SpeedyTransforms]] -deps = ["AbstractFFTs", "Adapt", "AssociatedLegendrePolynomials", "Atomix", "DocStringExtensions", "FFTW", "FastGaussQuadrature", "GPUArrays", "GenericFFT", "KernelAbstractions", "LinearAlgebra", "LowerTriangularArrays", "Primes", "Printf", "RingGrids", "SpeedyWeatherInternals", "Statistics"] -git-tree-sha1 = "0960dcee70cd2eb5d6858cc63cd91e1419f8fe72" -uuid = "ed023a3f-7a3c-42dd-bab6-68c21c8c3105" -version = "0.1.1" -weakdeps = ["CUDA", "Enzyme"] - - [deps.SpeedyTransforms.extensions] - SpeedyTransformsCUDAExt = "CUDA" - SpeedyTransformsEnzymeExt = "Enzyme" - -[[deps.SpeedyWeather]] -deps = ["AbstractFFTs", "Adapt", "AssociatedLegendrePolynomials", "Atomix", "BitInformation", "CodecZlib", "ComponentArrays", "Dates", "DocStringExtensions", "DomainSets", "FFTW", "FastGaussQuadrature", "GPUArrays", "GenericFFT", "JLD2", "KernelAbstractions", "LinearAlgebra", "LowerTriangularArrays", "NCDatasets", "Primes", "Printf", "ProgressMeter", "Random", "RingGrids", "SpeedyTransforms", "SpeedyWeatherInternals", "Statistics", "TOML"] -git-tree-sha1 = "f59944897672d7fdc8bef0d47f7ec2d1d28793bf" -uuid = "9e226e20-d153-4fed-8a5b-493def4f21a9" -version = "0.17.4" - - [deps.SpeedyWeather.extensions] - SpeedyWeatherEnzymeExt = "Enzyme" - SpeedyWeatherFiniteDifferencesExt = "FiniteDifferences" - SpeedyWeatherGeoMakieExt = "GeoMakie" - SpeedyWeatherUnicodePlotsExt = "UnicodePlots" - - [deps.SpeedyWeather.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" - GeoMakie = "db073c08-6b98-4ee5-b6a4-5efafb3259c6" - UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" - -[[deps.SpeedyWeatherInternals]] -deps = ["ComponentArrays", "ConstructionBase", "Dates", "DocStringExtensions", "DomainSets", "KernelAbstractions", "MacroTools", "ModelParameters"] -git-tree-sha1 = "19ae520aff10b5b94ff06d11cb861c92e9466add" -uuid = "34489162-d270-4603-8b96-37b04f830d73" -version = "0.1.3" - - [deps.SpeedyWeatherInternals.extensions] - SpeedyWeatherInternalsAMDGPUExt = "AMDGPU" - SpeedyWeatherInternalsCUDAExt = "CUDA" - SpeedyWeatherInternalsJLArraysExt = "JLArrays" - SpeedyWeatherInternalsMetalExt = "Metal" - - [deps.SpeedyWeatherInternals.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" - Metal = "dde4c033-4e86-420c-a63e-0dd931031962" - -[[deps.StableRNGs]] -deps = ["Random"] -git-tree-sha1 = "4f96c596b8c8258cc7d3b19797854d368f243ddc" -uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" -version = "1.0.4" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "be1cf4eb0ac528d96f5115b4ed80c26a8d8ae621" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.2" - -[[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] -git-tree-sha1 = "49440414711eddc7227724ae6e570c7d5559a086" -uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.3.1" - -[[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "SciMLPublic", "Static"] -git-tree-sha1 = "aa1ea41b3d45ac449d10477f65e2b40e3197a0d2" -uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.9.0" -weakdeps = ["OffsetArrays", "StaticArrays"] - - [deps.StaticArrayInterface.extensions] - StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" - StaticArrayInterfaceStaticArraysExt = "StaticArrays" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "246a8bb2e6667f832eea063c3a56aef96429a3db" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.18" -weakdeps = ["ChainRulesCore", "Statistics"] - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "6ab403037779dae8c514bad259f32a447262455a" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.4" - -[[deps.Statistics]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.11.1" -weakdeps = ["SparseArrays"] - - [deps.Statistics.extensions] - SparseArraysExt = ["SparseArrays"] - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "178ed29fd5b2a2cfc3bd31c13375ae925623ff36" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.8.0" - -[[deps.StatsBase]] -deps = ["AliasTables", "DataAPI", "DataStructures", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "aceda6f4e598d331548e04cc6b2124a6148138e3" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.10" - -[[deps.StatsFuns]] -deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "91f091a8716a6bb38417a6e6f274602a19aaa685" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.5.2" -weakdeps = ["ChainRulesCore", "InverseFunctions"] - - [deps.StatsFuns.extensions] - StatsFunsChainRulesCoreExt = "ChainRulesCore" - StatsFunsInverseFunctionsExt = "InverseFunctions" - -[[deps.StringManipulation]] -deps = ["PrecompileTools"] -git-tree-sha1 = "d05693d339e37d6ab134c5ab53c29fce5ee5d7d5" -uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.4.4" - -[[deps.StructArrays]] -deps = ["ConstructionBase", "DataAPI", "Tables"] -git-tree-sha1 = "ad8002667372439f2e3611cfd14097e03fa4bccd" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.7.3" -weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"] - - [deps.StructArrays.extensions] - StructArraysAdaptExt = "Adapt" - StructArraysGPUArraysCoreExt = ["GPUArraysCore", "KernelAbstractions"] - StructArraysLinearAlgebraExt = "LinearAlgebra" - StructArraysSparseArraysExt = "SparseArrays" - StructArraysStaticArraysExt = "StaticArrays" - -[[deps.StructIO]] -git-tree-sha1 = "c581be48ae1cbf83e899b14c07a807e1787512cc" -uuid = "53d494c1-5632-5724-8f4c-31dff12d585f" -version = "0.3.1" - -[[deps.StructUtils]] -deps = ["Dates", "UUIDs"] -git-tree-sha1 = "86f5831495301b2a1387476cb30f86af7ab99194" -uuid = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42" -version = "2.8.0" - - [deps.StructUtils.extensions] - StructUtilsMeasurementsExt = ["Measurements"] - StructUtilsStaticArraysCoreExt = ["StaticArraysCore"] - StructUtilsTablesExt = ["Tables"] - - [deps.StructUtils.weakdeps] - Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" - -[[deps.StyledStrings]] -uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" -version = "1.11.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.8.3+2" - -[[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 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.12.1" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[deps.TaylorSeries]] -deps = ["LinearAlgebra", "Markdown", "SparseArrays"] -git-tree-sha1 = "4a5ddc4036946d3a7900b5776b0872e36d848a29" -uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.20.10" - - [deps.TaylorSeries.extensions] - TaylorSeriesIAExt = "IntervalArithmetic" - TaylorSeriesJLD2Ext = "JLD2" - TaylorSeriesRATExt = "RecursiveArrayTools" - TaylorSeriesSAExt = "StaticArrays" - - [deps.TaylorSeries.weakdeps] - IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" - JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" - RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[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" -version = "1.11.0" - -[[deps.Thermodynamics]] -deps = ["ForwardDiff", "Random", "RootSolvers"] -git-tree-sha1 = "9f39fc85c78edf969ead08f88a1a0068562aa543" -uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.15.9" - - [deps.Thermodynamics.extensions] - CreateParametersExt = "ClimaParams" - - [deps.Thermodynamics.weakdeps] - ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" - -[[deps.ThreadingUtilities]] -deps = ["ManualMemory"] -git-tree-sha1 = "d969183d3d244b6c33796b5ed01ab97328f2db85" -uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" -version = "0.5.5" - -[[deps.TiledIteration]] -deps = ["OffsetArrays", "StaticArrayInterface"] -git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" -uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" -version = "0.5.0" - -[[deps.Tracy]] -deps = ["ExprTools", "LibTracyClient_jll", "Libdl"] -git-tree-sha1 = "73e3ff50fd3990874c59fef0f35d10644a1487bc" -uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" -version = "0.1.6" - - [deps.Tracy.extensions] - TracyProfilerExt = "TracyProfiler_jll" - - [deps.Tracy.weakdeps] - TracyProfiler_jll = "0c351ed6-8a68-550e-8b79-de6f926da83c" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.11.3" - -[[deps.URIs]] -git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" -uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.6.1" - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" -version = "1.11.0" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" -version = "1.11.0" - -[[deps.Unitful]] -deps = ["Dates", "LinearAlgebra", "Random"] -git-tree-sha1 = "57e1b2c9de4bd6f40ecb9de4ac1797b81970d008" -uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" -version = "1.28.0" - - [deps.Unitful.extensions] - ConstructionBaseUnitfulExt = "ConstructionBase" - ForwardDiffExt = "ForwardDiff" - InverseFunctionsUnitfulExt = "InverseFunctions" - LatexifyExt = ["Latexify", "LaTeXStrings"] - NaNMathExt = "NaNMath" - PrintfExt = "Printf" - - [deps.Unitful.weakdeps] - ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" - Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" - NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" - Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[deps.UnsafeAtomics]] -git-tree-sha1 = "0f30765c32d66d58e41f4cb5624d4fc8a82ec13b" -uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" -version = "0.3.1" -weakdeps = ["LLVM"] - - [deps.UnsafeAtomics.extensions] - UnsafeAtomicsLLVM = ["LLVM"] - -[[deps.UnsafePointers]] -git-tree-sha1 = "c81331b3b2e60a982be57c046ec91f599ede674a" -uuid = "e17b2a0c-0bdf-430a-bd0c-3a23cae4ff39" -version = "1.0.0" - -[[deps.VectorizationBase]] -deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "d1d9a935a26c475ebffd54e9c7ad11627c43ea85" -uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.72" - -[[deps.WoodburyMatrices]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "248a7031b3da79a127f14e5dc5f417e26f9f6db7" -uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "1.1.0" - -[[deps.WorldOceanAtlasTools]] -deps = ["DataDeps", "DataFrames", "Downloads", "Match", "NCDatasets", "NearestNeighbors", "OceanGrids", "Statistics", "StatsBase", "Unitful"] -git-tree-sha1 = "134d30d8a0f03a1deb57767a478e230edbfa627f" -uuid = "04f20302-f1b9-11e8-29d9-7d841cb0a64a" -version = "0.6.4" - -[[deps.XESMF]] -deps = ["CondaPkg", "LinearAlgebra", "PythonCall", "SparseArrays"] -git-tree-sha1 = "f572a29a8ddd0ec974f909493ec6b9ca7f7e1c1d" -uuid = "2e0b0046-e7a1-486f-88de-807ee8ffabe5" -version = "0.1.6" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "80d3930c6347cfce7ccf96bd3bafdf079d9c0390" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.9+0" - -[[deps.XZ_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "b29c22e245d092b8b4e8d3c09ad7baa586d9f573" -uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.8.3+0" - -[[deps.Xorg_libpciaccess_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "4909eb8f1cbf6bd4b1c30dd18b2ead9019ef2fad" -uuid = "a65dc6b1-eb27-53a1-bb3e-dea574b5389e" -version = "0.18.1+0" - -[[deps.ZipFile]] -deps = ["Libdl", "Printf", "Zlib_jll"] -git-tree-sha1 = "f492b7fe1698e623024e873244f10d89c95c340a" -uuid = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea" -version = "0.10.1" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.3.1+2" - -[[deps.Zstd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.7+1" - -[[deps.aws_c_auth_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_cal_jll", "aws_c_http_jll", "aws_c_sdkutils_jll"] -git-tree-sha1 = "8cab83c96af80a1be968251ce1a0548a7545484d" -uuid = "2b3700d1-4306-52e2-a478-c162f0c514be" -version = "0.9.6+0" - -[[deps.aws_c_cal_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_common_jll"] -git-tree-sha1 = "22c0f42f4a1f0dc5dcfa8fd267c4ac407c455e7a" -uuid = "70f11efc-bab2-57f1-b0f3-22aad4e67c4b" -version = "0.9.13+0" - -[[deps.aws_c_common_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "a759cb9bf456ad792cc7898a81ae333cce9ef02a" -uuid = "73048d1d-b8c4-5092-a58d-866c5e8d1e50" -version = "0.12.6+0" - -[[deps.aws_c_compression_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_common_jll"] -git-tree-sha1 = "7910c72f45f44afd297c39fe43b99c56d5ed22ec" -uuid = "73a04cd5-f3d7-5bac-9290-e8adb709f224" -version = "0.3.2+0" - -[[deps.aws_c_http_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_compression_jll", "aws_c_io_jll"] -git-tree-sha1 = "e358d5a001ef7afbd4f8c5225322512819cda2f2" -uuid = "3254fc65-9028-534d-aa9d-d76d128babc6" -version = "0.10.13+0" - -[[deps.aws_c_io_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_cal_jll", "aws_c_common_jll", "s2n_tls_jll"] -git-tree-sha1 = "7e481d474b2087ee8bbf55b81bf9119f21e396d9" -uuid = "13c41daa-f319-5298-b5eb-5754e0170d52" -version = "0.26.3+0" - -[[deps.aws_c_s3_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_auth_jll", "aws_c_common_jll", "aws_c_http_jll", "aws_checksums_jll", "s2n_tls_jll"] -git-tree-sha1 = "3e9917ab25114feba657e71be41cad068b9f6595" -uuid = "bd1f34fb-993f-5903-a121-aaf302eed6d4" -version = "0.11.5+0" - -[[deps.aws_c_sdkutils_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_common_jll"] -git-tree-sha1 = "c43dfba2c1ab9ea9f02f2c80e86fa16f6460244e" -uuid = "1282aa60-004d-510b-9f52-12498d409daa" -version = "0.2.4+1" - -[[deps.aws_checksums_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "aws_c_common_jll"] -git-tree-sha1 = "2570c8e23f4771a087b12a47edcaaa670ac05a01" -uuid = "b2a88e68-78e7-5e94-8c20-c02986ec140e" -version = "0.2.10+0" - -[[deps.demumble_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6498e3581023f8e530f34760d18f75a69e3a4ea8" -uuid = "1e29f10c-031c-5a83-9565-69cddfc27673" -version = "1.3.0+0" - -[[deps.dlfcn_win32_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e141d67ffe550eadfb5af1bdbdaf138031e4805f" -uuid = "c4b69c83-5512-53e3-94e6-de98773c479f" -version = "1.4.2+0" - -[[deps.libaec_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1411bc34c180946d3cef591de1384012afa6edee" -uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.1.6+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.15.0+0" - -[[deps.libzip_jll]] -deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "OpenSSL_jll", "XZ_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "86addc139bca85fdf9e7741e10977c45785727b7" -uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" -version = "1.11.3+0" - -[[deps.micromamba_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "717df6f6892af4ee13279a73aa58474e58a88667" -uuid = "f8abcde7-e9b7-5caa-b8af-a437887ae8e4" -version = "2.3.1+0" - -[[deps.mpif_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIABI_jll", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML"] -git-tree-sha1 = "a8083ee0737c243c8f40a4ba86a0956997facb73" -uuid = "9aeb927a-4695-514f-a259-621a69f20ec0" -version = "0.1.7+0" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.64.0+1" - -[[deps.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "1350188a69a6e46f799d3945beef36435ed7262f" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2022.0.0+1" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.7.0+0" - -[[deps.pixi_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "f349584316617063160a947a82638f7611a8ef0f" -uuid = "4d7b5844-a134-5dcd-ac86-c8f19cd51bed" -version = "0.41.3+0" - -[[deps.s2n_tls_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6b99e06a3863de281da6ff0e193a5b3706349054" -uuid = "cddc5d3d-934d-5d3a-9747-62fc12ea3f48" -version = "1.7.2+0" From a862678d98bc4ec17476c3f4304992ba941b5e24 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 30 Apr 2026 14:31:41 -0600 Subject: [PATCH 10/13] Touch JRA55PrescribedRadiation in test init for cache-fallback hygiene MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GPU CI hit a NetCDF: HDF error opening JRA55/RYF.rlds.1990_1991.nc — a corrupted cached download. The existing init guard only constructs a JRA55PrescribedAtmosphere, which never touches the radiation files (rlds/rsds). Now that those files are loaded at test time via JRA55PrescribedRadiation, a bad cached file isn't caught until much later. Construct a JRA55PrescribedRadiation in the same try/catch so the NumericalEarthArtifacts fallback path triggers for radiation downloads too, mirroring the atmosphere variables. Co-Authored-By: Claude Opus 4.7 (1M context) --- test/runtests.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index ef9d1bc50..7a88b6ccb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -79,6 +79,9 @@ function __init__() try atmosphere = JRA55PrescribedAtmosphere(backend=JRA55NetCDFBackend(2)) + # Touch the radiation variables (rlds/rsds) too, so a corrupted cached + # download is caught by the same fallback path. + radiation = JRA55PrescribedRadiation(backend=JRA55NetCDFBackend(2)) catch e @warn "Original JRA55 download failed, trying NumericalEarthArtifacts fallback..." exception=(e, catch_backtrace()) emit_ci_warning("Broken JRA55 download", "Original source failed during init") @@ -87,6 +90,7 @@ function __init__() download_from_artifacts(metadata_path(datum)) end atmosphere = JRA55PrescribedAtmosphere(backend=JRA55NetCDFBackend(2)) + radiation = JRA55PrescribedRadiation(backend=JRA55NetCDFBackend(2)) end ##### From 3a7114ab78a73a72a7a26b8d22c12bbc2112fa98 Mon Sep 17 00:00:00 2001 From: "Gregory L. Wagner" Date: Fri, 1 May 2026 14:01:00 -0600 Subject: [PATCH 11/13] Update src/EarthSystemModels/InterfaceComputations/component_interfaces.jl Co-authored-by: Eliot Quon --- .../InterfaceComputations/component_interfaces.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl b/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl index f04b33de7..f97404b09 100644 --- a/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl +++ b/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl @@ -336,6 +336,7 @@ Keyword Arguments - `ThreeEquationHeatFlux()`: coupled heat/salt/freezing point system (default) - `radiation`: radiation component. Default: `Radiation()`. ++ `radiation`: radiation component. Default: `nothing`. - `freshwater_density`: reference density of freshwater. Default: `default_freshwater_density`. - `atmosphere_ocean_fluxes`: flux formulation for atmosphere-ocean interface. Default: `SimilarityTheoryFluxes()`. - `atmosphere_sea_ice_fluxes`: flux formulation for atmosphere-sea ice interface. Default: `SimilarityTheoryFluxes()`. From 40d964cf4689f33589031a05fbeccddd2dd6fe3c Mon Sep 17 00:00:00 2001 From: "Gregory L. Wagner" Date: Fri, 1 May 2026 14:01:33 -0600 Subject: [PATCH 12/13] Update src/EarthSystemModels/earth_system_model.jl Co-authored-by: Eliot Quon --- src/EarthSystemModels/earth_system_model.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/EarthSystemModels/earth_system_model.jl b/src/EarthSystemModels/earth_system_model.jl index 5e334c789..1e7f59c45 100644 --- a/src/EarthSystemModels/earth_system_model.jl +++ b/src/EarthSystemModels/earth_system_model.jl @@ -138,6 +138,22 @@ function EarthSystemModel(radiation, atmosphere, land, sea_ice, ocean; sea_ice_reference_density = reference_density(sea_ice), sea_ice_heat_capacity = heat_capacity(sea_ice), interfaces = nothing) + if isnothing(radiation) && atmosphere isa PrescribedAtmosphere + @warn """ + `EarthSystemModel` was constructed with a `PrescribedAtmosphere` but \ + `radiation = nothing`. This means no upwelling longwave (ϵσT⁴), no \ + absorbed downwelling longwave, and no shortwave absorption — \ + results will be physically inconsistent. + + If you previously relied on `Radiation()` defaults: pass \ + `radiation = JRA55PrescribedRadiation(arch; backend, ...)` (or \ + `ECCOPrescribedRadiation` / `OSPapaPrescribedRadiation`) to restore \ + radiative forcing. Pass `radiation = PrescribedRadiation(grid)` for \ + emission-only mode. To suppress this warning, build the model \ + without a `PrescribedAtmosphere` (radiatively decoupled is the \ + intended `nothing` semantics). + """ maxlog=1 + end if ocean isa Simulation if !isnothing(ocean.callbacks) From effb52e700b10afe0f512cd57ca1c5c2ff126079 Mon Sep 17 00:00:00 2001 From: "Gregory L. Wagner" Date: Fri, 1 May 2026 14:01:44 -0600 Subject: [PATCH 13/13] Update src/Radiations/apply_air_sea_ice_radiative_fluxes.jl Co-authored-by: Eliot Quon --- src/Radiations/apply_air_sea_ice_radiative_fluxes.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Radiations/apply_air_sea_ice_radiative_fluxes.jl b/src/Radiations/apply_air_sea_ice_radiative_fluxes.jl index f9ce64236..eb2d9249d 100644 --- a/src/Radiations/apply_air_sea_ice_radiative_fluxes.jl +++ b/src/Radiations/apply_air_sea_ice_radiative_fluxes.jl @@ -22,6 +22,7 @@ function _apply_air_sea_ice_radiative_fluxes_dispatch!(coupled_model::EarthSyste sea_ice::Simulation{<:SeaIceModel}) radiation = coupled_model.radiation interface_fluxes = radiation.interface_fluxes + isnothing(interface_fluxes) && return nothing haskey(interface_fluxes, :sea_ice) || return nothing grid = sea_ice.model.grid