From ae5f0be40c70563c2a82eddb29d6c9702028013c Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 17:28:39 -0400 Subject: [PATCH 001/203] start modifying the data structure --- src/DataWrangling/DataWrangling.jl | 5 +- src/DataWrangling/JRA55.jl | 102 +------ src/DataWrangling/ecco_metadata.jl | 72 ++--- src/DataWrangling/ecco_restoring.jl | 32 +-- src/DataWrangling/jra55_field_time_series.jl | 266 +++++++++++++++++++ src/DataWrangling/jra55_metadata.jl | 156 +++++++++++ src/DataWrangling/metadata.jl | 58 ++++ 7 files changed, 509 insertions(+), 182 deletions(-) create mode 100644 src/DataWrangling/jra55_field_time_series.jl create mode 100644 src/DataWrangling/jra55_metadata.jl create mode 100644 src/DataWrangling/metadata.jl diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index af9ce21cd..728585a39 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -69,11 +69,12 @@ function save_field_time_series!(fts; path, name, overwrite_existing=false) return nothing end +include("metadata.jl") include("inpaint_mask.jl") -include("JRA55.jl") include("ECCO.jl") +include("JRA55.jl") -using .JRA55 using .ECCO +using .JRA55 end # module diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index a7427ec7e..83d132641 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -26,111 +26,13 @@ import Oceananigans.Fields: set! import Oceananigans.OutputReaders: new_backend, update_field_time_series! using Downloads: download +include("jra55_metadata.jl") + download_jra55_cache::String = "" function __init__() global download_jra55_cache = @get_scratch!("JRA55") end -# A list of all variables provided in the JRA55 dataset: -JRA55_variable_names = (:river_freshwater_flux, - :rain_freshwater_flux, - :snow_freshwater_flux, - :iceberg_freshwater_flux, - :specific_humidity, - :sea_level_pressure, - :relative_humidity, - :downwelling_longwave_radiation, - :downwelling_shortwave_radiation, - :temperature, - :eastward_velocity, - :northward_velocity) - -filenames = Dict( - :river_freshwater_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers - :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall - :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs - :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity - :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure - :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity - :downwelling_longwave_radiation => "RYF.rlds.1990_1991.nc", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "RYF.rsds.1990_1991.nc", # Downwelling shortwave radiation - :temperature => "RYF.tas.1990_1991.nc", # Near-surface air temperature - :eastward_velocity => "RYF.uas.1990_1991.nc", # Eastward near-surface wind - :northward_velocity => "RYF.vas.1990_1991.nc", # Northward near-surface wind -) - -jra55_short_names = Dict( - :river_freshwater_flux => "friver", # Freshwater fluxes from rivers - :rain_freshwater_flux => "prra", # Freshwater flux from rainfall - :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "licalvf", # Freshwater flux from calving icebergs - :specific_humidity => "huss", # Surface specific humidity - :sea_level_pressure => "psl", # Sea level pressure - :relative_humidity => "rhuss", # Surface relative humidity - :downwelling_longwave_radiation => "rlds", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "rsds", # Downwelling shortwave radiation - :temperature => "tas", # Near-surface air temperature - :eastward_velocity => "uas", # Eastward near-surface wind - :northward_velocity => "vas", # Northward near-surface wind -) - -field_time_series_short_names = Dict( - :river_freshwater_flux => "Fri", # Freshwater fluxes from rivers - :rain_freshwater_flux => "Fra", # Freshwater flux from rainfall - :snow_freshwater_flux => "Fsn", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "Fic", # Freshwater flux from calving icebergs - :specific_humidity => "qa", # Surface specific humidity - :sea_level_pressure => "pa", # Sea level pressure - :relative_humidity => "rh", # Surface relative humidity - :downwelling_longwave_radiation => "Ql", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "Qs", # Downwelling shortwave radiation - :temperature => "Ta", # Near-surface air temperature - :eastward_velocity => "ua", # Eastward near-surface wind - :northward_velocity => "va", # Northward near-surface wind -) - -urls = Dict( - :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * - "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - - :river_freshwater_flux => "https://www.dropbox.com/scl/fi/21ggl4p74k4zvbf04nb67/" * - "RYF.friver.1990_1991.nc?rlkey=ny2qcjkk1cfijmwyqxsfm68fz&dl=0", - - :rain_freshwater_flux => "https://www.dropbox.com/scl/fi/5icl1gbd7f5hvyn656kjq/" * - "RYF.prra.1990_1991.nc?rlkey=iifyjm4ppwyd8ztcek4dtx0k8&dl=0", - - :snow_freshwater_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * - "RYF.prsn.1990_1991.nc?rlkey=auyqpwn060cvy4w01a2yskfah&dl=0", - - :iceberg_freshwater_flux => "https://www.dropbox.com/scl/fi/44nc5y27ohvif7lkvpyv0/" * - "RYF.licalvf.1990_1991.nc?rlkey=w7rqu48y2baw1efmgrnmym0jk&dl=0", - - :specific_humidity => "https://www.dropbox.com/scl/fi/66z6ymfr4ghkynizydc29/" * - "RYF.huss.1990_1991.nc?rlkey=107yq04aew8lrmfyorj68v4td&dl=0", - - :sea_level_pressure => "https://www.dropbox.com/scl/fi/0fk332027oru1iiseykgp/" * - "RYF.psl.1990_1991.nc?rlkey=4xpr9uah741483aukok6d7ctt&dl=0", - - :relative_humidity => "https://www.dropbox.com/scl/fi/1agwsp0lzvntuyf8bm9la/" * - "RYF.rhuss.1990_1991.nc?rlkey=8cd0vs7iy1rw58b9pc9t68gtz&dl=0", - - :downwelling_longwave_radiation => "https://www.dropbox.com/scl/fi/y6r62szkirrivua5nqq61/" * - "RYF.rlds.1990_1991.nc?rlkey=wt9yq3cyrvs2rbowoirf4nkum&dl=0", - - :downwelling_shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * - "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - - :temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * - "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", - - :eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * - "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", - - :northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * - "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", -) - compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl index 3855bcacb..c2e61f5c7 100644 --- a/src/DataWrangling/ecco_metadata.jl +++ b/src/DataWrangling/ecco_metadata.jl @@ -4,55 +4,21 @@ import Dates: year, month, day import Oceananigans.Fields: set! import Base +using ClimaOcean.DataWrangling: Metadata + struct ECCO2Monthly end struct ECCO2Daily end struct ECCO4Monthly end -# Metadata holding the ECCO dataset information: -# - `name`: The name of the dataset. -# - `dates`: The dates of the dataset, in a `AbstractCFDateTime` format. -# - `version`: The version of the dataset, could be ECCO2Monthly, ECCO2Daily, or ECCO4Monthly. -struct ECCOMetadata{D, V} - name :: Symbol - dates :: D - version :: V -end - -Base.show(io::IO, metadata::ECCOMetadata) = - print(io, "ECCOMetadata:", '\n', - "├── field: $(metadata.name)", '\n', - "├── dates: $(metadata.dates)", '\n', - "└── data version: $(metadata.version)") - -# The default is the ECCO2Daily dataset at 1993-01-01. -function ECCOMetadata(name::Symbol; - date = DateTimeProlepticGregorian(1993, 1, 1), - version = ECCO2Daily()) - - return ECCOMetadata(name, date, version) -end +const ECCOMetadata{T} = Union{Metadata{T, <:ECCO4Monthly}, Metadata{T, <:ECCO2Daily}, Metadata{T, <:ECCO2Monthly}} where T -# Treat ECCOMetadata as an array to allow iteration over the dates. -Base.getindex(metadata::ECCOMetadata, i::Int) = @inbounds ECCOMetadata(metadata.name, metadata.dates[i], metadata.version) -Base.length(metadata::ECCOMetadata) = length(metadata.dates) -Base.eltype(metadata::ECCOMetadata) = Base.eltype(metadata.dates) -Base.first(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[1], metadata.version) -Base.last(metadata::ECCOMetadata) = @inbounds ECCOMetadata(metadata.name, metadata.dates[end], metadata.version) -Base.iterate(metadata::ECCOMetadata, i=1) = (@inline; (i % UInt) - 1 < length(metadata) ? (@inbounds ECCOMetadata(metadata.name, metadata.dates[i], metadata.version), i + 1) : nothing) +Base.size(data::Metadata{<:Any, <:ECCO2Daily}) = (1440, 720, 50, length(data.dates)) +Base.size(data::Metadata{<:Any, <:ECCO2Monthly}) = (1440, 720, 50, length(data.dates)) +Base.size(data::Metadata{<:Any, <:ECCO4Monthly}) = (720, 360, 50, length(data.dates)) -Base.axes(metadata::ECCOMetadata{<:AbstractCFDateTime}) = 1 -Base.first(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata -Base.last(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata -Base.iterate(metadata::ECCOMetadata{<:AbstractCFDateTime}) = (metadata, nothing) -Base.iterate(::ECCOMetadata{<:AbstractCFDateTime}, ::Any) = nothing - -Base.size(data::ECCOMetadata{<:Any, <:ECCO2Daily}) = (1440, 720, 50, length(data.dates)) -Base.size(data::ECCOMetadata{<:Any, <:ECCO2Monthly}) = (1440, 720, 50, length(data.dates)) -Base.size(data::ECCOMetadata{<:Any, <:ECCO4Monthly}) = (720, 360, 50, length(data.dates)) - -Base.size(::ECCOMetadata{<:AbstractCFDateTime, <:ECCO2Daily}) = (1440, 720, 50, 1) -Base.size(::ECCOMetadata{<:AbstractCFDateTime, <:ECCO2Monthly}) = (1440, 720, 50, 1) -Base.size(::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) = (720, 360, 50, 1) +Base.size(::Metadata{<:AbstractCFDateTime, <:ECCO2Daily}) = (1440, 720, 50, 1) +Base.size(::Metadata{<:AbstractCFDateTime, <:ECCO2Monthly}) = (1440, 720, 50, 1) +Base.size(::Metadata{<:AbstractCFDateTime, <:ECCO4Monthly}) = (720, 360, 50, 1) # The whole range of dates in the different dataset versions all_ecco_dates(::ECCO4Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) @@ -60,8 +26,8 @@ all_ecco_dates(::ECCO2Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month( all_ecco_dates(::ECCO2Daily) = DateTimeProlepticGregorian(1992, 1, 4) : Day(1) : DateTimeProlepticGregorian(2023, 12, 31) # File name generation specific to each Dataset version -function metadata_filename(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) - shortname = short_name(metadata) +function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:ECCO4Monthly}) + shortname = short_name(metadata) yearstr = string(Dates.year(metadata.dates)) monthstr = string(Dates.month(metadata.dates), pad=2) return shortname * "_" * yearstr * "_" * monthstr * ".nc" @@ -82,9 +48,9 @@ function metadata_filename(metadata::ECCOMetadata{<:AbstractCFDateTime}) end # Convenience functions -short_name(data::ECCOMetadata{<:Any, <:ECCO2Daily}) = ecco2_short_names[data.name] -short_name(data::ECCOMetadata{<:Any, <:ECCO2Monthly}) = ecco2_short_names[data.name] -short_name(data::ECCOMetadata{<:Any, <:ECCO4Monthly}) = ecco4_short_names[data.name] +short_name(data::Metadata{<:Any, <:ECCO2Daily}) = ecco2_short_names[data.name] +short_name(data::Metadata{<:Any, <:ECCO2Monthly}) = ecco2_short_names[data.name] +short_name(data::Metadata{<:Any, <:ECCO4Monthly}) = ecco4_short_names[data.name] field_location(data::ECCOMetadata) = ecco_location[data.name] @@ -122,12 +88,12 @@ ecco_location = Dict( ) # URLs for the ECCO datasets specific to each version -urls(::ECCOMetadata{<:Any, <:ECCO2Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" -urls(::ECCOMetadata{<:Any, <:ECCO2Daily}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/daily/" -urls(::ECCOMetadata{<:Any, <:ECCO4Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" +urls(::Metadata{<:Any, <:ECCO2Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" +urls(::Metadata{<:Any, <:ECCO2Daily}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/daily/" +urls(::Metadata{<:Any, <:ECCO4Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" """ - download_dataset!(metadata::ECCOMetadata) + download_dataset!(metadata::Metadata) Download the dataset specified by the given metadata. If the metadata contains a single date, the dataset is downloaded directly. If the metadata contains multiple dates, the dataset is @@ -139,7 +105,7 @@ or by launching julia with ECCO_USERNAME=myuser ECCO_PASSWORD=mypasswrd julia # Arguments -- `metadata::ECCOMetadata`: The metadata specifying the dataset to be downloaded. +- `metadata::Metadata`: The metadata specifying the dataset to be downloaded. """ function download_dataset!(metadata::ECCOMetadata; url = urls(metadata)) diff --git a/src/DataWrangling/ecco_restoring.jl b/src/DataWrangling/ecco_restoring.jl index 3f063fefd..f6d1f608a 100644 --- a/src/DataWrangling/ecco_restoring.jl +++ b/src/DataWrangling/ecco_restoring.jl @@ -12,6 +12,7 @@ using JLD2 using Dates using ClimaOcean: stateindex +using ClimaOcean.DataWrangling: native_times import Oceananigans.Fields: set! import Oceananigans.OutputReaders: new_backend, update_field_time_series! @@ -66,31 +67,6 @@ function set!(fts::ECCONetCDFFTS, path::ECCOMetadata=fts.path, name::String=fts. return nothing end -""" - ecco_times(metadata; start_time = metadata.dates[1]) - -Extracts the time values from the given metadata and calculates the time difference -from the start time. - -# Arguments -- `metadata`: The metadata containing the date information. -- `start_time`: The start time for calculating the time difference. Defaults to the first date in the metadata. - -# Returns -An array of time differences in seconds. -""" -function ecco_times(metadata; start_time = first(metadata).dates) - times = zeros(length(metadata)) - for (t, data) in enumerate(metadata) - date = data.dates - time = date - start_time - time = Second(time).value - times[t] = time - end - - return times -end - """ ECCO_field_time_series(metadata::ECCOMetadata; architecture = CPU(), @@ -100,10 +76,12 @@ end Create a field time series object for ECCO data. -# Arguments: +Arguments: +============== - metadata: An ECCOMetadata object containing information about the ECCO dataset. -# Keyword Arguments: +Keyword Arguments: +===================== - architecture: The architecture to use for computations (default: CPU()). - time_indices_in_memory: The number of time indices to keep in memory (default: 2). - time_indexing: The time indexing scheme to use (default: Cyclical()). diff --git a/src/DataWrangling/jra55_field_time_series.jl b/src/DataWrangling/jra55_field_time_series.jl new file mode 100644 index 000000000..1d6eb6ee8 --- /dev/null +++ b/src/DataWrangling/jra55_field_time_series.jl @@ -0,0 +1,266 @@ +using Oceananigans.Units +using Oceananigans.Grids: node, on_architecture +using Oceananigans.Fields: interpolate!, interpolate, location, instantiated_location +using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices +using Oceananigans.Utils: Time + +using CUDA: @allowscalar +using Base + +using NCDatasets +using JLD2 +using Dates + +using ClimaOcean: stateindex +using ClimaOcean.DataWrangling: native_times + +import Oceananigans.Fields: set! +import Oceananigans.OutputReaders: new_backend, update_field_time_series! + +@inline instantiate(T::DataType) = T() +@inline instantiate(T) = T + +struct JRA55NetCDFBackend{N} <: AbstractInMemoryBackend{Int} + start :: Int + length :: Int + + JRA55NetCDFBackend{N}(start::Int, length::Int) where N = new{N}(start, length) +end + +""" + JRA55NetCDFBackend(length) + +Represents an JRA55 FieldTimeSeries backed by JRA55 native .nc files. +Each time instance is stored in an individual file. +""" +JRA55NetCDFBackend(length; on_native_grid = false) = JRA55NetCDFBackend{on_native_grid}(1, length) + +Base.length(backend::JRA55NetCDFBackend) = backend.length +Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") + +const JRA55NetCDFFTS{N} = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <: JRA55NetCDFBackend{N}} where N + +new_backend(::JRA55NetCDFBackend{N}, start, length) where N = JRA55ONetCDFBackend{N}(start, length) +on_native_grid(::JRA55NetCDFBackend{N}) where N = N + +function set!(fts::JRA55NetCDFFTS, path::JRA55Metadata=fts.path, name::String=fts.name) + + backend = fts.backend + start = backend.start + + # Set the JRA55 dataset based on the backend!s + + for t in start:start+length(backend)-1 + + # find the file associated with the time index + metadata = @inbounds path[t] + + arch = architecture(fts) + + # f = inpainted_ecco_field(metadata; architecture = arch) + if on_native_grid(backend) + set!(fts[t], f) + else + interpolate!(fts[t], f) + end + end + + fill_halo_regions!(fts) + + return nothing +end + +""" + JRA55_field_time_series(metadata::ECCOMetadata; + architecture = CPU(), + time_indices_in_memory = 2, + time_indexing = Cyclical(), + grid = nothing) + +Create a field time series object for ECCO data. + +# Arguments: +- metadata: An ECCOMetadata object containing information about the ECCO dataset. + +# Keyword Arguments: +- architecture: The architecture to use for computations (default: CPU()). +- time_indices_in_memory: The number of time indices to keep in memory (default: 2). +- time_indexing: The time indexing scheme to use (default: Cyclical()). +- grid: if not a `nothing`, the ECCO data is directly interpolated on the `grid`, +""" +function JRA55_field_time_series(metadata::JRA55Metadata; + architecture = CPU(), + backend = JRA55NetCDFBackend(20), + time_indexing = Cyclical(), + grid = nothing) + + # ECCO data is too chunky to allow other backends + backend = if backend isa JRA55NetCDFBackend + JRA55NetCDFBackend(backend.length; + on_native_grid = isnothing(grid)) + else + backend + end + + # Making sure all the required individual files are downloaded + download_dataset!(metadata) + + location = field_location(metadata) + shortname = short_name(metadata) + + JRA55_native_grid = jra55_native_grid() + boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, location) + times = native_times(metadata) + + fts_grid = isnothing(grid) ? ECCO_native_grid : grid + + fts = FieldTimeSeries{location...}(fts_grid, times; + backend, + time_indexing, + boundary_conditions, + path = metadata, + name = shortname) + + # Let's set the data + set!(fts) + + return fts +end + +ECCO_field_time_series(variable_name::Symbol, version=ECCO4Monthly(); kw...) = + ECCO_field_time_series(ECCOMetadata(variable_name, all_ecco_dates(version), version); kw...) + +# Variable names for restoreable data +struct Temperature end +struct Salinity end +struct UVelocity end +struct VVelocity end + +oceananigans_fieldname = Dict( + :temperature => Temperature(), + :salinity => Salinity(), + :u_velocity => UVelocity(), + :v_velocity => VVelocity()) + +@inline Base.getindex(fields, i, j, k, ::Temperature) = @inbounds fields.T[i, j, k] +@inline Base.getindex(fields, i, j, k, ::Salinity) = @inbounds fields.S[i, j, k] +@inline Base.getindex(fields, i, j, k, ::UVelocity) = @inbounds fields.u[i, j, k] +@inline Base.getindex(fields, i, j, k, ::VVelocity) = @inbounds fields.v[i, j, k] + +""" + struct ECCORestoring{FTS, G, M, V, N} <: Function + +A struct representing ECCO restoring. + +# Fields +- `ecco_fts`: The ECCO FTS on the native ECCO grid. +- `ecco_grid`: The native ECCO grid to interpolate from. +- `mask`: A mask (could be a number, an array, a function or a field). +- `variable_name`: The variable name of the variable that needs restoring. +- `λ⁻¹`: The reciprocal of the restoring timescale. +""" +struct ECCORestoring{FTS, G, M, V, N} <: Function + ecco_fts :: FTS + ecco_grid :: G + mask :: M + variable_name :: V + λ⁻¹ :: N +end + +Adapt.adapt_structure(to, p::ECCORestoring) = + ECCORestoring(Adapt.adapt(to, p.ecco_fts), + Adapt.adapt(to, p.ecco_grid), + Adapt.adapt(to, p.mask), + Adapt.adapt(to, p.variable_name), + Adapt.adapt(to, p.λ⁻¹)) + +@inline function (p::ECCORestoring)(i, j, k, grid, clock, fields) + + # Figure out all the inputs: time, location, and node + time = Time(clock.time) + loc = location(p.ecco_fts) + + # Retrieve the variable to force + @inbounds var = fields[i, j, k, p.variable_name] + + ecco_backend = p.ecco_fts.backend + native_grid = on_native_grid(ecco_backend) + + ecco_var = get_ecco_variable(Val(native_grid), p.ecco_fts, i, j, k, p.ecco_grid, grid, time) + + # Extracting the mask value at the current node + mask = stateindex(p.mask, i, j, k, grid, clock.time, loc) + + return p.λ⁻¹ * mask * (ecco_var - var) +end + +# Differentiating between restoring done with an ECCO FTS +# that lives on the native ecco grid, that requires interpolation in space +# _inside_ the restoring function and restoring based on an ECCO +# FTS defined on the model grid that requires only time interpolation +@inline function get_ecco_variable(::Val{true}, ecco_fts, i, j, k, ecco_grid, grid, time) + # Extracting the ECCO field time series data and parameters + ecco_times = ecco_fts.times + ecco_data = ecco_fts.data + ecco_time_indexing = ecco_fts.time_indexing + ecco_backend = ecco_fts.backend + ecco_location = instantiated_location(ecco_fts) + + X = node(i, j, k, grid, ecco_location...) + + # Interpolating the ECCO field time series data onto the current node and time + return interpolate(X, time, ecco_data, ecco_location, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) +end + +@inline get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) = @inbounds ecco_fts[i, j, k, time] + +""" + ECCO_restoring_forcing(metadata::ECCOMetadata; + architecture = CPU(), + backend = ECCONetCDFBackend(2), + time_indexing = Cyclical(), + mask = 1, + timescale = 5days) + +Create a restoring forcing term that restores to values stored in an ECCO field time series. + +# Arguments: +============= +- `metadata`: The metadata for the ECCO field time series. + +# Keyword Arguments: +==================== +- `architecture`: The architecture. Typically `CPU` or `GPU` +- `time_indices_in_memory`: The number of time indices to keep in memory. trade-off between performance + and memory footprint. +- `time_indexing`: The time indexing scheme for the field time series, see [`FieldTimeSeries`](@ref) +- `mask`: The mask value. Can be a function of `(x, y, z, time)`, an array or a number +- `timescale`: The restoring timescale. +""" +function ECCO_restoring_forcing(variable_name::Symbol, version=ECCO4Monthly(); kw...) + metadata = ECCOMetadata(variable_name, all_ecco_dates(version), version) + return ECCO_restoring_forcing(metadata; kw...) +end + +function ECCO_restoring_forcing(metadata::ECCOMetadata; + architecture = CPU(), + time_indices_in_memory = 2, # Not more than this if we want to use GPU! + time_indexing = Cyclical(), + mask = 1, + timescale = 20days, + grid = nothing) + + ecco_fts = ECCO_field_time_series(metadata; grid, architecture, time_indices_in_memory, time_indexing) + ecco_grid = ecco_fts.grid + + # Grab the correct Oceananigans field to restore + variable_name = metadata.name + field_name = oceananigans_fieldname[variable_name] + + ecco_restoring = ECCORestoring(ecco_fts, ecco_grid, mask, field_name, 1 / timescale) + + # Defining the forcing that depends on the restoring field. + restoring_forcing = Forcing(ecco_restoring; discrete_form = true) + + return restoring_forcing +end \ No newline at end of file diff --git a/src/DataWrangling/jra55_metadata.jl b/src/DataWrangling/jra55_metadata.jl new file mode 100644 index 000000000..e9b84fe9a --- /dev/null +++ b/src/DataWrangling/jra55_metadata.jl @@ -0,0 +1,156 @@ +using CFTime +using Dates +import Dates: year, month, day +import Oceananigans.Fields: set! +import Base + +using ClimaOcean.DataWrangling: Metadata + +struct JRA55MultipleYears end +struct JRA55RepeatYear end + +const JRA55Metadata{T} = Union{Metadata{T, <:JRA55MultipleYears}, Metadata{<:JRA55RepeatYear}} where T + +Base.size(data::JRA55Metadata) = (640, 320, length(data.dates)) +Base.size(::JRA55Metadata{<:AbstractCFDateTime}) = (640, 320, 1) + +# File name generation specific to each Dataset version +function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) + # fix the filename + + return filename +end + +# File name generation specific to each Dataset version +function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55RepeatYear}) + # fix the filename + + return filename +end + +# Convenience functions +short_name(data::JRA55Metadata) = jra55_short_names[data.name] +field_location(data::JRA55Metadata) = jra55_location[data.name] + +# A list of all variables provided in the JRA55 dataset: +JRA55_variable_names = (:river_freshwater_flux, + :rain_freshwater_flux, + :snow_freshwater_flux, + :iceberg_freshwater_flux, + :specific_humidity, + :sea_level_pressure, + :relative_humidity, + :downwelling_longwave_radiation, + :downwelling_shortwave_radiation, + :temperature, + :eastward_velocity, + :northward_velocity) + +filenames = Dict( + :river_freshwater_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers + :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall + :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs + :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity + :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure + :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity + :downwelling_longwave_radiation => "RYF.rlds.1990_1991.nc", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "RYF.rsds.1990_1991.nc", # Downwelling shortwave radiation + :temperature => "RYF.tas.1990_1991.nc", # Near-surface air temperature + :eastward_velocity => "RYF.uas.1990_1991.nc", # Eastward near-surface wind + :northward_velocity => "RYF.vas.1990_1991.nc", # Northward near-surface wind +) + +jra55_short_names = Dict( + :river_freshwater_flux => "friver", # Freshwater fluxes from rivers + :rain_freshwater_flux => "prra", # Freshwater flux from rainfall + :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "licalvf", # Freshwater flux from calving icebergs + :specific_humidity => "huss", # Surface specific humidity + :sea_level_pressure => "psl", # Sea level pressure + :relative_humidity => "rhuss", # Surface relative humidity + :downwelling_longwave_radiation => "rlds", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "rsds", # Downwelling shortwave radiation + :temperature => "tas", # Near-surface air temperature + :eastward_velocity => "uas", # Eastward near-surface wind + :northward_velocity => "vas", # Northward near-surface wind +) + +field_time_series_short_names = Dict( + :river_freshwater_flux => "Fri", # Freshwater fluxes from rivers + :rain_freshwater_flux => "Fra", # Freshwater flux from rainfall + :snow_freshwater_flux => "Fsn", # Freshwater flux from snowfall + :iceberg_freshwater_flux => "Fic", # Freshwater flux from calving icebergs + :specific_humidity => "qa", # Surface specific humidity + :sea_level_pressure => "pa", # Sea level pressure + :relative_humidity => "rh", # Surface relative humidity + :downwelling_longwave_radiation => "Ql", # Downwelling longwave radiation + :downwelling_shortwave_radiation => "Qs", # Downwelling shortwave radiation + :temperature => "Ta", # Near-surface air temperature + :eastward_velocity => "ua", # Eastward near-surface wind + :northward_velocity => "va", # Northward near-surface wind +) + +urls = Dict( + :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * + "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", + + :river_freshwater_flux => "https://www.dropbox.com/scl/fi/21ggl4p74k4zvbf04nb67/" * + "RYF.friver.1990_1991.nc?rlkey=ny2qcjkk1cfijmwyqxsfm68fz&dl=0", + + :rain_freshwater_flux => "https://www.dropbox.com/scl/fi/5icl1gbd7f5hvyn656kjq/" * + "RYF.prra.1990_1991.nc?rlkey=iifyjm4ppwyd8ztcek4dtx0k8&dl=0", + + :snow_freshwater_flux => "https://www.dropbox.com/scl/fi/1r4ajjzb3643z93ads4x4/" * + "RYF.prsn.1990_1991.nc?rlkey=auyqpwn060cvy4w01a2yskfah&dl=0", + + :iceberg_freshwater_flux => "https://www.dropbox.com/scl/fi/44nc5y27ohvif7lkvpyv0/" * + "RYF.licalvf.1990_1991.nc?rlkey=w7rqu48y2baw1efmgrnmym0jk&dl=0", + + :specific_humidity => "https://www.dropbox.com/scl/fi/66z6ymfr4ghkynizydc29/" * + "RYF.huss.1990_1991.nc?rlkey=107yq04aew8lrmfyorj68v4td&dl=0", + + :sea_level_pressure => "https://www.dropbox.com/scl/fi/0fk332027oru1iiseykgp/" * + "RYF.psl.1990_1991.nc?rlkey=4xpr9uah741483aukok6d7ctt&dl=0", + + :relative_humidity => "https://www.dropbox.com/scl/fi/1agwsp0lzvntuyf8bm9la/" * + "RYF.rhuss.1990_1991.nc?rlkey=8cd0vs7iy1rw58b9pc9t68gtz&dl=0", + + :downwelling_longwave_radiation => "https://www.dropbox.com/scl/fi/y6r62szkirrivua5nqq61/" * + "RYF.rlds.1990_1991.nc?rlkey=wt9yq3cyrvs2rbowoirf4nkum&dl=0", + + :downwelling_shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * + "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", + + :temperature => "https://www.dropbox.com/scl/fi/fpl0npwi476w635g6lke9/" * + "RYF.tas.1990_1991.nc?rlkey=0skb9pe6lgbfbiaoybe7m945s&dl=0", + + :eastward_velocity => "https://www.dropbox.com/scl/fi/86wetpqla2x97isp8092g/" * + "RYF.uas.1990_1991.nc?rlkey=rcaf18sh1yz0v9g4hjm1249j0&dl=0", + + :northward_velocity => "https://www.dropbox.com/scl/fi/d38sflo9ddljstd5jwgml/" * + "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", +) + +variable_is_three_dimensional(data::JRA55Metadata) = false + +# URLs for the JRA55 datasets specific to each version +function urls(metadata::JRA55Metadata) + return "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" +end + +function download_dataset!(metadata::JRA55Metadata; + url = urls(metadata)) + + for data in metadata + filename = metadata_filename(data) + shortname = short_name(data) + + if !isfile(filename) + fileurl = joinpath(url, shortname, year, filename) + download(url, filepath) + end + end + + return nothing +end \ No newline at end of file diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl new file mode 100644 index 000000000..523fdd2c0 --- /dev/null +++ b/src/DataWrangling/metadata.jl @@ -0,0 +1,58 @@ + +# Metadata holding the ECCO dataset information: +# - `name`: The name of the dataset. +# - `dates`: The dates of the dataset, in a `AbstractCFDateTime` format. +# - `version`: The version of the dataset, could be ECCO2Monthly, ECCO2Daily, or ECCO4Monthly. +struct Metadata{D, V} + name :: Symbol + dates :: D + version :: V +end + +Base.show(io::IO, metadata::Metadata) = + print(io, "Metadata:", '\n', + "├── field: $(metadata.name)", '\n', + "├── dates: $(metadata.dates)", '\n', + "└── data version: $(metadata.version)") + +# Treat Metadata as an array to allow iteration over the dates. +Base.getindex(metadata::Metadata, i::Int) = @inbounds Metadata(metadata.name, metadata.dates[i], metadata.version) +Base.length(metadata::Metadata) = length(metadata.dates) +Base.eltype(metadata::Metadata) = Base.eltype(metadata.dates) +Base.first(metadata::Metadata) = @inbounds Metadata(metadata.name, metadata.dates[1], metadata.version) +Base.last(metadata::Metadata) = @inbounds Metadata(metadata.name, metadata.dates[end], metadata.version) +Base.iterate(metadata::Metadata, i=1) = (@inline; (i % UInt) - 1 < length(metadata) ? (@inbounds Metadata(metadata.name, metadata.dates[i], metadata.version), i + 1) : nothing) + +Base.axes(metadata::Metadata{<:AbstractCFDateTime}) = 1 +Base.first(metadata::Metadata{<:AbstractCFDateTime}) = metadata +Base.last(metadata::Metadata{<:AbstractCFDateTime}) = metadata +Base.iterate(metadata::Metadata{<:AbstractCFDateTime}) = (metadata, nothing) +Base.iterate(::Metadata{<:AbstractCFDateTime}, ::Any) = nothing + +Base.size(data::Metadata{<:Any, <:JRA55ThreeHourly}) = (640, 320, 1, length(data.dates)) + + +""" + native_times(metadata; start_time = metadata.dates[1]) + +Extracts the time values from the given metadata and calculates the time difference +from the start time. + +# Arguments +- `metadata`: The metadata containing the date information. +- `start_time`: The start time for calculating the time difference. Defaults to the first date in the metadata. + +# Returns +An array of time differences in seconds. +""" +function native_times(metadata; start_time = first(metadata).dates) + times = zeros(length(metadata)) + for (t, data) in enumerate(metadata) + date = data.dates + time = date - start_time + time = Second(time).value + times[t] = time + end + + return times +end \ No newline at end of file From 42be4e9714aa0c3a065ae230cb8d9b8903d802ac Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Thu, 25 Jul 2024 17:46:44 -0400 Subject: [PATCH 002/203] going on... --- src/DataWrangling/JRA55.jl | 333 ------------ src/DataWrangling/jra55_field_time_series.jl | 533 ++++++++++++++----- 2 files changed, 391 insertions(+), 475 deletions(-) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55.jl index 83d132641..8005df95b 100644 --- a/src/DataWrangling/JRA55.jl +++ b/src/DataWrangling/JRA55.jl @@ -155,339 +155,6 @@ end new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length) -""" - JRA55_field_time_series(variable_name; - architecture = CPU(), - location = nothing, - url = nothing, - filename = nothing, - shortname = nothing, - backend = InMemory(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) - -Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, -which describes one of the variables in the "repeat year forcing" dataset derived -from the Japanese 55-year atmospheric reanalysis for driving ocean-sea-ice models (JRA55-do). -For more information about the derivation of the repeat year forcing dataset, see - -"Stewart et al., JRA55-do-based repeat year forcing datasets for driving ocean–sea-ice models", -Ocean Modelling, 2020, https://doi.org/10.1016/j.ocemod.2019.101557. - -The `variable_name`s (and their `shortname`s used in NetCDF files) -available from the JRA55-do are: - - - `:river_freshwater_flux` ("friver") - - `:rain_freshwater_flux` ("prra") - - `:snow_freshwater_flux` ("prsn") - - `:iceberg_freshwater_flux` ("licalvf") - - `:specific_humidity` ("huss") - - `:sea_level_pressure` ("psl") - - `:relative_humidity` ("rhuss") - - `:downwelling_longwave_radiation` ("rlds") - - `:downwelling_shortwave_radiation` ("rsds") - - `:temperature` ("ras") - - `:eastward_velocity` ("uas") - - `:northward_velocity` ("vas") - -Keyword arguments -================= - - - `architecture`: Architecture for the `FieldTimeSeries`. - Default: CPU() - - - `time_indices`: Indices of the timeseries to extract from file. - For example, `time_indices=1:3` returns a - `FieldTimeSeries` with the first three time snapshots - of `variable_name`. - - - `url`: The url accessed to download the data for `variable_name`. - Default: `ClimaOcean.JRA55.urls[variable_name]`. - - - `filename`: The name of the downloaded file. - Default: `ClimaOcean.JRA55.filenames[variable_name]`. - - - `shortname`: The "short name" of `variable_name` inside its NetCDF file. - Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. - - - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. - If it does not exist it will be generated. - - - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is - loaded (not recommended). -""" -function JRA55_field_time_series(variable_name; - architecture = CPU(), - grid = nothing, - location = nothing, - url = nothing, - dir = download_jra55_cache, - filename = nothing, - shortname = nothing, - latitude = nothing, - longitude = nothing, - backend = InMemory(), - time_indexing = Cyclical(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) - - # OnDisk backends do not support time interpolation! - # Disallow OnDisk for JRA55 dataset loading - if backend isa OnDisk - msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") - throw(ArgumentError(msg)) - end - - if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) - variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) - variables_msg = prod(variable_strs) - - msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', - "The variables provided by the JRA55-do dataset are:", '\n', - variables_msg) - - throw(ArgumentError(msg)) - end - - filepath = isnothing(filename) ? joinpath(dir, filenames[variable_name]) : joinpath(dir, filename) - - if !isnothing(filename) && !isfile(filepath) && isnothing(url) - throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ - If intended, please provide both the filename and url that should be used \n \ - to download the new file.")) - end - - isnothing(filename) && (filename = filenames[variable_name]) - isnothing(shortname) && (shortname = jra55_short_names[variable_name]) - isnothing(url) && (url = urls[variable_name]) - - # Record some important user decisions - totally_in_memory = backend isa TotallyInMemory - on_native_grid = isnothing(grid) - !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") - - jld2_filepath = joinpath(dir, string("JRA55_repeat_year_", variable_name, ".jld2")) - fts_name = field_time_series_short_names[variable_name] - - # Note, we don't re-use existing jld2 files. - isfile(filepath) || download(url, filepath) - isfile(jld2_filepath) && rm(jld2_filepath) - - # Determine default time indices - if totally_in_memory - # In this case, the whole time series is in memory. - # Either the time series is short, or we are doing a limited-area - # simulation, like in a single column. So, we conservatively - # set a default `time_indices = 1:2`. - isnothing(time_indices) && (time_indices = 1:2) - time_indices_in_memory = time_indices - native_fts_architecture = architecture - else - # In this case, part or all of the time series will be stored in a file. - # Note: if the user has provided a grid, we will have to preprocess the - # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers - # to the time_indices that we will preprocess; - # by default we choose all of them. The architecture is only the - # architecture used for preprocessing, which typically will be CPU() - # even if we would like the final FieldTimeSeries on the GPU. - isnothing(time_indices) && (time_indices = :) - - if backend isa JRA55NetCDFBackend - time_indices_in_memory = 1:length(backend) - native_fts_architecture = architecture - else # then `time_indices_in_memory` refers to preprocessing - maximum_index = min(preprocess_chunk_size, length(time_indices)) - time_indices_in_memory = 1:maximum_index - native_fts_architecture = preprocess_architecture - end - end - - # Set a default location. - if isnothing(location) - LX = LY = Center - else - LX, LY = location - end - - ds = Dataset(filepath) - - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - - # Interfaces for the "native" JRA55 grid - λn = ds["lon_bnds"][1, :] - φn = ds["lat_bnds"][1, :] - - # The .nc coordinates lon_bnds and lat_bnds do not include - # the last interface, so we push them here. - push!(φn, 90) - push!(λn, λn[1] + 360) - - # TODO: support loading just part of the JRA55 data. - # Probably with arguments that take latitude, longitude bounds. - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) - - native_times = ds["time"][time_indices] - data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - λr = λn[i₁:i₂+1] - φr = φn[j₁:j₂+1] - Nrx, Nry, Nt = size(data) - close(ds) - - N = (Nrx, Nry) - H = min.(N, (3, 3)) - - JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; - halo = H, - size = N, - longitude = λr, - latitude = φr, - topology = (TX, Bounded, Flat)) - - boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) - times = jra55_times(native_times) - - if backend isa JRA55NetCDFBackend - fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - backend, - time_indexing, - boundary_conditions, - path = filepath, - name = shortname) - - # Fill the data in a GPU-friendly manner - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) - - return fts - else - # Make times into an array for later preprocessing - if !totally_in_memory - times = collect(times) - end - - native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - time_indexing, - boundary_conditions) - - # Fill the data in a GPU-friendly manner - copyto!(interior(native_fts, :, :, 1, :), data) - fill_halo_regions!(native_fts) - - if on_native_grid && totally_in_memory - return native_fts - - elseif totally_in_memory # but not on the native grid! - boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) - fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) - interpolate!(fts, native_fts) - return fts - end - end - - @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - - preprocessing_grid = on_native_grid ? JRA55_native_grid : grid - - # Re-open the dataset! - ds = Dataset(filepath) - all_datetimes = ds["time"][time_indices] - all_Nt = length(all_datetimes) - - all_times = jra55_times(all_datetimes) - - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; - boundary_conditions, - backend = OnDisk(), - path = jld2_filepath, - name = fts_name) - - # Save data to disk, one field at a time - start_clock = time_ns() - n = 1 # on disk - m = 0 # in memory - - times_in_memory = all_times[time_indices_in_memory] - - fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; - boundary_conditions, - backend = InMemory(), - path = jld2_filepath, - name = fts_name) - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) - end - - while n <= all_Nt - print(" ... processing time index $n of $all_Nt \r") - - if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory - m += 1 - else # load new data - # Update time_indices - time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size - n₁ = first(time_indices_in_memory) - - # Clip time_indices if they extend past the end of the dataset - if last(time_indices_in_memory) > all_Nt - time_indices_in_memory = UnitRange(n₁, all_Nt) - end - - # Re-compute times - new_times = jra55_times(all_times[time_indices_in_memory], all_times[n₁]) - native_fts.times = new_times - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - fts.times = new_times - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) - end - - m = 1 # reset - end - - set!(on_disk_fts, fts[m], n, fts.times[m]) - - n += 1 - end - - elapsed = 1e-9 * (time_ns() - start_clock) - elapsed_str = prettytime(elapsed) - @info " ... done ($elapsed_str)" * repeat(" ", 20) - - close(ds) - - user_fts = FieldTimeSeries(jld2_filepath, fts_name; architecture, backend, time_indexing) - fill_halo_regions!(user_fts) - - return user_fts -end - const AA = Oceananigans.Architectures.AbstractArchitecture JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = diff --git a/src/DataWrangling/jra55_field_time_series.jl b/src/DataWrangling/jra55_field_time_series.jl index 1d6eb6ee8..281bb793f 100644 --- a/src/DataWrangling/jra55_field_time_series.jl +++ b/src/DataWrangling/jra55_field_time_series.jl @@ -44,29 +44,32 @@ new_backend(::JRA55NetCDFBackend{N}, start, length) where N = JRA55ONetCDFBacken on_native_grid(::JRA55NetCDFBackend{N}) where N = N function set!(fts::JRA55NetCDFFTS, path::JRA55Metadata=fts.path, name::String=fts.name) - - backend = fts.backend - start = backend.start - - # Set the JRA55 dataset based on the backend!s - - for t in start:start+length(backend)-1 - - # find the file associated with the time index - metadata = @inbounds path[t] - - arch = architecture(fts) - - # f = inpainted_ecco_field(metadata; architecture = arch) - if on_native_grid(backend) - set!(fts[t], f) - else - interpolate!(fts[t], f) - end - end - + + # Do different things based on the Backend... + ds = Dataset(path) + + # Note that each file should have the variables + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data + + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + LX, LY, LZ = location(fts) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) + + ti = time_indices(fts) + ti = collect(ti) + data = ds[name][i₁:i₂, j₁:j₂, ti] + close(ds) + + copyto!(interior(fts, :, :, 1, :), data) fill_halo_regions!(fts) - + return nothing end @@ -79,10 +82,12 @@ end Create a field time series object for ECCO data. -# Arguments: +Arguments: +=========== - metadata: An ECCOMetadata object containing information about the ECCO dataset. -# Keyword Arguments: +Keyword Arguments: +===================== - architecture: The architecture to use for computations (default: CPU()). - time_indices_in_memory: The number of time indices to keep in memory (default: 2). - time_indexing: The time indexing scheme to use (default: Cyclical()). @@ -92,9 +97,10 @@ function JRA55_field_time_series(metadata::JRA55Metadata; architecture = CPU(), backend = JRA55NetCDFBackend(20), time_indexing = Cyclical(), - grid = nothing) + grid = nothing, + latitude = nothing, + longitude = nothing) - # ECCO data is too chunky to allow other backends backend = if backend isa JRA55NetCDFBackend JRA55NetCDFBackend(backend.length; on_native_grid = isnothing(grid)) @@ -105,14 +111,57 @@ function JRA55_field_time_series(metadata::JRA55Metadata; # Making sure all the required individual files are downloaded download_dataset!(metadata) + # Note that each file should have the variables + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data + + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + + # Interfaces for the "native" JRA55 grid + λn = ds["lon_bnds"][1, :] + φn = ds["lat_bnds"][1, :] + + # The .nc coordinates lon_bnds and lat_bnds do not include + # the last interface, so we push them here. + push!(φn, 90) + push!(λn, λn[1] + 360) + + # TODO: support loading just part of the JRA55 data. + # Probably with arguments that take latitude, longitude bounds. + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + + native_times = ds["time"][time_indices] + data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + λr = λn[i₁:i₂+1] + φr = φn[j₁:j₂+1] + Nrx, Nry, Nt = size(data) + close(ds) + + N = (Nrx, Nry) + H = min.(N, (3, 3)) + + JRA55_native_grid = LatitudeLongitudeGrid(architecture, Float32; + halo = H, + size = N, + longitude = λr, + latitude = φr, + topology = (TX, Bounded, Flat)) + + boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) + location = field_location(metadata) shortname = short_name(metadata) - JRA55_native_grid = jra55_native_grid() boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, location) times = native_times(metadata) - fts_grid = isnothing(grid) ? ECCO_native_grid : grid + fts_grid = isnothing(grid) ? JRA55_native_grid : grid fts = FieldTimeSeries{location...}(fts_grid, times; backend, @@ -127,140 +176,340 @@ function JRA55_field_time_series(metadata::JRA55Metadata; return fts end -ECCO_field_time_series(variable_name::Symbol, version=ECCO4Monthly(); kw...) = - ECCO_field_time_series(ECCOMetadata(variable_name, all_ecco_dates(version), version); kw...) - -# Variable names for restoreable data -struct Temperature end -struct Salinity end -struct UVelocity end -struct VVelocity end +JRA55_field_time_series(variable_name::Symbol, version=JRA55RepeatYear(); kw...) = + JRA55_field_time_series(Metadata(variable_name, all_dates(version), version); kw...) -oceananigans_fieldname = Dict( - :temperature => Temperature(), - :salinity => Salinity(), - :u_velocity => UVelocity(), - :v_velocity => VVelocity()) -@inline Base.getindex(fields, i, j, k, ::Temperature) = @inbounds fields.T[i, j, k] -@inline Base.getindex(fields, i, j, k, ::Salinity) = @inbounds fields.S[i, j, k] -@inline Base.getindex(fields, i, j, k, ::UVelocity) = @inbounds fields.u[i, j, k] -@inline Base.getindex(fields, i, j, k, ::VVelocity) = @inbounds fields.v[i, j, k] """ - struct ECCORestoring{FTS, G, M, V, N} <: Function + JRA55_field_time_series(variable_name; + architecture = CPU(), + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + backend = InMemory(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + +Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, +which describes one of the variables in the "repeat year forcing" dataset derived +from the Japanese 55-year atmospheric reanalysis for driving ocean-sea-ice models (JRA55-do). +For more information about the derivation of the repeat year forcing dataset, see + +"Stewart et al., JRA55-do-based repeat year forcing datasets for driving ocean–sea-ice models", +Ocean Modelling, 2020, https://doi.org/10.1016/j.ocemod.2019.101557. + +The `variable_name`s (and their `shortname`s used in NetCDF files) +available from the JRA55-do are: + + - `:river_freshwater_flux` ("friver") + - `:rain_freshwater_flux` ("prra") + - `:snow_freshwater_flux` ("prsn") + - `:iceberg_freshwater_flux` ("licalvf") + - `:specific_humidity` ("huss") + - `:sea_level_pressure` ("psl") + - `:relative_humidity` ("rhuss") + - `:downwelling_longwave_radiation` ("rlds") + - `:downwelling_shortwave_radiation` ("rsds") + - `:temperature` ("ras") + - `:eastward_velocity` ("uas") + - `:northward_velocity` ("vas") + +Keyword arguments +================= + + - `architecture`: Architecture for the `FieldTimeSeries`. + Default: CPU() + + - `time_indices`: Indices of the timeseries to extract from file. + For example, `time_indices=1:3` returns a + `FieldTimeSeries` with the first three time snapshots + of `variable_name`. + + - `url`: The url accessed to download the data for `variable_name`. + Default: `ClimaOcean.JRA55.urls[variable_name]`. + + - `filename`: The name of the downloaded file. + Default: `ClimaOcean.JRA55.filenames[variable_name]`. + + - `shortname`: The "short name" of `variable_name` inside its NetCDF file. + Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. + + - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. + If it does not exist it will be generated. + + - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is + loaded (not recommended). +""" +function JRA55_field_time_series(variable_name; + architecture = CPU(), + grid = nothing, + location = nothing, + url = nothing, + dir = download_jra55_cache, + filename = nothing, + shortname = nothing, + latitude = nothing, + longitude = nothing, + backend = InMemory(), + time_indexing = Cyclical(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + + # OnDisk backends do not support time interpolation! + # Disallow OnDisk for JRA55 dataset loading + if backend isa OnDisk + msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") + throw(ArgumentError(msg)) + end -A struct representing ECCO restoring. + if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) + variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) + variables_msg = prod(variable_strs) -# Fields -- `ecco_fts`: The ECCO FTS on the native ECCO grid. -- `ecco_grid`: The native ECCO grid to interpolate from. -- `mask`: A mask (could be a number, an array, a function or a field). -- `variable_name`: The variable name of the variable that needs restoring. -- `λ⁻¹`: The reciprocal of the restoring timescale. -""" -struct ECCORestoring{FTS, G, M, V, N} <: Function - ecco_fts :: FTS - ecco_grid :: G - mask :: M - variable_name :: V - λ⁻¹ :: N -end + msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', + "The variables provided by the JRA55-do dataset are:", '\n', + variables_msg) -Adapt.adapt_structure(to, p::ECCORestoring) = - ECCORestoring(Adapt.adapt(to, p.ecco_fts), - Adapt.adapt(to, p.ecco_grid), - Adapt.adapt(to, p.mask), - Adapt.adapt(to, p.variable_name), - Adapt.adapt(to, p.λ⁻¹)) + throw(ArgumentError(msg)) + end -@inline function (p::ECCORestoring)(i, j, k, grid, clock, fields) + filepath = isnothing(filename) ? joinpath(dir, filenames[variable_name]) : joinpath(dir, filename) + + if !isnothing(filename) && !isfile(filepath) && isnothing(url) + throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ + If intended, please provide both the filename and url that should be used \n \ + to download the new file.")) + end + + isnothing(filename) && (filename = filenames[variable_name]) + isnothing(shortname) && (shortname = jra55_short_names[variable_name]) + isnothing(url) && (url = urls[variable_name]) + + # Record some important user decisions + totally_in_memory = backend isa TotallyInMemory + on_native_grid = isnothing(grid) + !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") + + jld2_filepath = joinpath(dir, string("JRA55_repeat_year_", variable_name, ".jld2")) + fts_name = field_time_series_short_names[variable_name] + + # Note, we don't re-use existing jld2 files. + isfile(filepath) || download(url, filepath) + isfile(jld2_filepath) && rm(jld2_filepath) + + # Determine default time indices + if totally_in_memory + # In this case, the whole time series is in memory. + # Either the time series is short, or we are doing a limited-area + # simulation, like in a single column. So, we conservatively + # set a default `time_indices = 1:2`. + isnothing(time_indices) && (time_indices = 1:2) + time_indices_in_memory = time_indices + native_fts_architecture = architecture + else + # In this case, part or all of the time series will be stored in a file. + # Note: if the user has provided a grid, we will have to preprocess the + # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers + # to the time_indices that we will preprocess; + # by default we choose all of them. The architecture is only the + # architecture used for preprocessing, which typically will be CPU() + # even if we would like the final FieldTimeSeries on the GPU. + isnothing(time_indices) && (time_indices = :) + + if backend isa JRA55NetCDFBackend + time_indices_in_memory = 1:length(backend) + native_fts_architecture = architecture + else # then `time_indices_in_memory` refers to preprocessing + maximum_index = min(preprocess_chunk_size, length(time_indices)) + time_indices_in_memory = 1:maximum_index + native_fts_architecture = preprocess_architecture + end + end + + # Set a default location. + if isnothing(location) + LX = LY = Center + else + LX, LY = location + end + + ds = Dataset(filepath) + + # Note that each file should have the variables + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data + + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + + # Interfaces for the "native" JRA55 grid + λn = ds["lon_bnds"][1, :] + φn = ds["lat_bnds"][1, :] + + # The .nc coordinates lon_bnds and lat_bnds do not include + # the last interface, so we push them here. + push!(φn, 90) + push!(λn, λn[1] + 360) + + # TODO: support loading just part of the JRA55 data. + # Probably with arguments that take latitude, longitude bounds. + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + + native_times = ds["time"][time_indices] + data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + λr = λn[i₁:i₂+1] + φr = φn[j₁:j₂+1] + Nrx, Nry, Nt = size(data) + close(ds) + + N = (Nrx, Nry) + H = min.(N, (3, 3)) + + JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; + halo = H, + size = N, + longitude = λr, + latitude = φr, + topology = (TX, Bounded, Flat)) + + boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) + times = jra55_times(native_times) - # Figure out all the inputs: time, location, and node - time = Time(clock.time) - loc = location(p.ecco_fts) + if backend isa JRA55NetCDFBackend + fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = filepath, + name = shortname) + + # Fill the data in a GPU-friendly manner + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) + + return fts + else + # Make times into an array for later preprocessing + if !totally_in_memory + times = collect(times) + end - # Retrieve the variable to force - @inbounds var = fields[i, j, k, p.variable_name] + native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + time_indexing, + boundary_conditions) - ecco_backend = p.ecco_fts.backend - native_grid = on_native_grid(ecco_backend) + # Fill the data in a GPU-friendly manner + copyto!(interior(native_fts, :, :, 1, :), data) + fill_halo_regions!(native_fts) - ecco_var = get_ecco_variable(Val(native_grid), p.ecco_fts, i, j, k, p.ecco_grid, grid, time) + if on_native_grid && totally_in_memory + return native_fts - # Extracting the mask value at the current node - mask = stateindex(p.mask, i, j, k, grid, clock.time, loc) + elseif totally_in_memory # but not on the native grid! + boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) + fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) + interpolate!(fts, native_fts) + return fts + end + end - return p.λ⁻¹ * mask * (ecco_var - var) -end + @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." -# Differentiating between restoring done with an ECCO FTS -# that lives on the native ecco grid, that requires interpolation in space -# _inside_ the restoring function and restoring based on an ECCO -# FTS defined on the model grid that requires only time interpolation -@inline function get_ecco_variable(::Val{true}, ecco_fts, i, j, k, ecco_grid, grid, time) - # Extracting the ECCO field time series data and parameters - ecco_times = ecco_fts.times - ecco_data = ecco_fts.data - ecco_time_indexing = ecco_fts.time_indexing - ecco_backend = ecco_fts.backend - ecco_location = instantiated_location(ecco_fts) + preprocessing_grid = on_native_grid ? JRA55_native_grid : grid - X = node(i, j, k, grid, ecco_location...) + # Re-open the dataset! + ds = Dataset(filepath) + all_datetimes = ds["time"][time_indices] + all_Nt = length(all_datetimes) - # Interpolating the ECCO field time series data onto the current node and time - return interpolate(X, time, ecco_data, ecco_location, ecco_grid, ecco_times, ecco_backend, ecco_time_indexing) -end + all_times = jra55_times(all_datetimes) -@inline get_ecco_variable(::Val{false}, ecco_fts, i, j, k, ecco_grid, grid, time) = @inbounds ecco_fts[i, j, k, time] + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; + boundary_conditions, + backend = OnDisk(), + path = jld2_filepath, + name = fts_name) -""" - ECCO_restoring_forcing(metadata::ECCOMetadata; - architecture = CPU(), - backend = ECCONetCDFBackend(2), - time_indexing = Cyclical(), - mask = 1, - timescale = 5days) - -Create a restoring forcing term that restores to values stored in an ECCO field time series. - -# Arguments: -============= -- `metadata`: The metadata for the ECCO field time series. - -# Keyword Arguments: -==================== -- `architecture`: The architecture. Typically `CPU` or `GPU` -- `time_indices_in_memory`: The number of time indices to keep in memory. trade-off between performance - and memory footprint. -- `time_indexing`: The time indexing scheme for the field time series, see [`FieldTimeSeries`](@ref) -- `mask`: The mask value. Can be a function of `(x, y, z, time)`, an array or a number -- `timescale`: The restoring timescale. -""" -function ECCO_restoring_forcing(variable_name::Symbol, version=ECCO4Monthly(); kw...) - metadata = ECCOMetadata(variable_name, all_ecco_dates(version), version) - return ECCO_restoring_forcing(metadata; kw...) -end + # Save data to disk, one field at a time + start_clock = time_ns() + n = 1 # on disk + m = 0 # in memory -function ECCO_restoring_forcing(metadata::ECCOMetadata; - architecture = CPU(), - time_indices_in_memory = 2, # Not more than this if we want to use GPU! - time_indexing = Cyclical(), - mask = 1, - timescale = 20days, - grid = nothing) + times_in_memory = all_times[time_indices_in_memory] - ecco_fts = ECCO_field_time_series(metadata; grid, architecture, time_indices_in_memory, time_indexing) - ecco_grid = ecco_fts.grid + fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; + boundary_conditions, + backend = InMemory(), + path = jld2_filepath, + name = fts_name) - # Grab the correct Oceananigans field to restore - variable_name = metadata.name - field_name = oceananigans_fieldname[variable_name] - - ecco_restoring = ECCORestoring(ecco_fts, ecco_grid, mask, field_name, 1 / timescale) - - # Defining the forcing that depends on the restoring field. - restoring_forcing = Forcing(ecco_restoring; discrete_form = true) + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + + if !on_native_grid + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + end + + while n <= all_Nt + print(" ... processing time index $n of $all_Nt \r") + + if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory + m += 1 + else # load new data + # Update time_indices + time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size + n₁ = first(time_indices_in_memory) + + # Clip time_indices if they extend past the end of the dataset + if last(time_indices_in_memory) > all_Nt + time_indices_in_memory = UnitRange(n₁, all_Nt) + end + + # Re-compute times + new_times = jra55_times(all_times[time_indices_in_memory], all_times[n₁]) + native_fts.times = new_times + + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + fts.times = new_times + + if !on_native_grid + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + end + + m = 1 # reset + end + + set!(on_disk_fts, fts[m], n, fts.times[m]) - return restoring_forcing -end \ No newline at end of file + n += 1 + end + + elapsed = 1e-9 * (time_ns() - start_clock) + elapsed_str = prettytime(elapsed) + @info " ... done ($elapsed_str)" * repeat(" ", 20) + + close(ds) + + user_fts = FieldTimeSeries(jld2_filepath, fts_name; architecture, backend, time_indexing) + fill_halo_regions!(user_fts) + + return user_fts +end From 1dab6e266147dabffb42456bc3d7a191f1c6c3ef Mon Sep 17 00:00:00 2001 From: Simone Silvestri <33547697+simone-silvestri@users.noreply.github.com> Date: Fri, 26 Jul 2024 14:45:38 -0400 Subject: [PATCH 003/203] comment --- src/DataWrangling/jra55_field_time_series.jl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/jra55_field_time_series.jl b/src/DataWrangling/jra55_field_time_series.jl index 281bb793f..b4aa02ac9 100644 --- a/src/DataWrangling/jra55_field_time_series.jl +++ b/src/DataWrangling/jra55_field_time_series.jl @@ -80,11 +80,11 @@ end time_indexing = Cyclical(), grid = nothing) -Create a field time series object for ECCO data. +Create a field time series object for JRA55 data. Arguments: =========== -- metadata: An ECCOMetadata object containing information about the ECCO dataset. +- metadata: An JRA55Metadata object containing information about the JRA55 dataset. Keyword Arguments: ===================== @@ -163,11 +163,17 @@ function JRA55_field_time_series(metadata::JRA55Metadata; fts_grid = isnothing(grid) ? JRA55_native_grid : grid + path = if backend isa JRA55NetCDFBackend + metadata + else + file_path + end + fts = FieldTimeSeries{location...}(fts_grid, times; backend, time_indexing, boundary_conditions, - path = metadata, + path, name = shortname) # Let's set the data From 9d11295d5d61301616cdad822448adfa61a0cfa8 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 1 Aug 2024 13:46:11 -0400 Subject: [PATCH 004/203] add some changes --- src/DataWrangling/jra55_field_time_series.jl | 308 +------------------ src/DataWrangling/jra55_metadata.jl | 9 +- 2 files changed, 22 insertions(+), 295 deletions(-) diff --git a/src/DataWrangling/jra55_field_time_series.jl b/src/DataWrangling/jra55_field_time_series.jl index b4aa02ac9..649001d40 100644 --- a/src/DataWrangling/jra55_field_time_series.jl +++ b/src/DataWrangling/jra55_field_time_series.jl @@ -46,7 +46,8 @@ on_native_grid(::JRA55NetCDFBackend{N}) where N = N function set!(fts::JRA55NetCDFFTS, path::JRA55Metadata=fts.path, name::String=fts.name) # Do different things based on the Backend... - ds = Dataset(path) + filename = metadata_filename(path) + ds = filename isa String ? Dataset(filename) : Dataset(filename[1]) # Note that each file should have the variables # - ds["time"]: time coordinate @@ -63,11 +64,14 @@ function set!(fts::JRA55NetCDFFTS, path::JRA55Metadata=fts.path, name::String=ft i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) ti = time_indices(fts) - ti = collect(ti) - data = ds[name][i₁:i₂, j₁:j₂, ti] - close(ds) - copyto!(interior(fts, :, :, 1, :), data) + if on_native_grid(fts.backend) + ti = collect(ti) + data = ds[name][i₁:i₂, j₁:j₂, ti] + copyto!(interior(fts, :, :, 1, :), data) + end + + close(ds) fill_halo_regions!(fts) return nothing @@ -95,22 +99,20 @@ Keyword Arguments: """ function JRA55_field_time_series(metadata::JRA55Metadata; architecture = CPU(), - backend = JRA55NetCDFBackend(20), + time_indices_in_memory = 2, time_indexing = Cyclical(), grid = nothing, latitude = nothing, longitude = nothing) - backend = if backend isa JRA55NetCDFBackend - JRA55NetCDFBackend(backend.length; - on_native_grid = isnothing(grid)) - else - backend - end + backend = JRA55NetCDFBackend(time_indices_in_memory; on_native_grid = isnothing(grid)) # Making sure all the required individual files are downloaded download_dataset!(metadata) + filename = metadata_filename(metadata) + ds = Dataset(filename) + # Note that each file should have the variables # - ds["time"]: time coordinate # - ds["lon"]: longitude at the location of the variable @@ -163,18 +165,14 @@ function JRA55_field_time_series(metadata::JRA55Metadata; fts_grid = isnothing(grid) ? JRA55_native_grid : grid - path = if backend isa JRA55NetCDFBackend - metadata - else - file_path - end - + path = metadata + fts = FieldTimeSeries{location...}(fts_grid, times; backend, time_indexing, boundary_conditions, path, - name = shortname) + name = metadata.name) # Let's set the data set!(fts) @@ -185,8 +183,6 @@ end JRA55_field_time_series(variable_name::Symbol, version=JRA55RepeatYear(); kw...) = JRA55_field_time_series(Metadata(variable_name, all_dates(version), version); kw...) - - """ JRA55_field_time_series(variable_name; architecture = CPU(), @@ -249,273 +245,3 @@ Keyword arguments - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is loaded (not recommended). """ -function JRA55_field_time_series(variable_name; - architecture = CPU(), - grid = nothing, - location = nothing, - url = nothing, - dir = download_jra55_cache, - filename = nothing, - shortname = nothing, - latitude = nothing, - longitude = nothing, - backend = InMemory(), - time_indexing = Cyclical(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) - - # OnDisk backends do not support time interpolation! - # Disallow OnDisk for JRA55 dataset loading - if backend isa OnDisk - msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") - throw(ArgumentError(msg)) - end - - if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) - variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) - variables_msg = prod(variable_strs) - - msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', - "The variables provided by the JRA55-do dataset are:", '\n', - variables_msg) - - throw(ArgumentError(msg)) - end - - filepath = isnothing(filename) ? joinpath(dir, filenames[variable_name]) : joinpath(dir, filename) - - if !isnothing(filename) && !isfile(filepath) && isnothing(url) - throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ - If intended, please provide both the filename and url that should be used \n \ - to download the new file.")) - end - - isnothing(filename) && (filename = filenames[variable_name]) - isnothing(shortname) && (shortname = jra55_short_names[variable_name]) - isnothing(url) && (url = urls[variable_name]) - - # Record some important user decisions - totally_in_memory = backend isa TotallyInMemory - on_native_grid = isnothing(grid) - !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") - - jld2_filepath = joinpath(dir, string("JRA55_repeat_year_", variable_name, ".jld2")) - fts_name = field_time_series_short_names[variable_name] - - # Note, we don't re-use existing jld2 files. - isfile(filepath) || download(url, filepath) - isfile(jld2_filepath) && rm(jld2_filepath) - - # Determine default time indices - if totally_in_memory - # In this case, the whole time series is in memory. - # Either the time series is short, or we are doing a limited-area - # simulation, like in a single column. So, we conservatively - # set a default `time_indices = 1:2`. - isnothing(time_indices) && (time_indices = 1:2) - time_indices_in_memory = time_indices - native_fts_architecture = architecture - else - # In this case, part or all of the time series will be stored in a file. - # Note: if the user has provided a grid, we will have to preprocess the - # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers - # to the time_indices that we will preprocess; - # by default we choose all of them. The architecture is only the - # architecture used for preprocessing, which typically will be CPU() - # even if we would like the final FieldTimeSeries on the GPU. - isnothing(time_indices) && (time_indices = :) - - if backend isa JRA55NetCDFBackend - time_indices_in_memory = 1:length(backend) - native_fts_architecture = architecture - else # then `time_indices_in_memory` refers to preprocessing - maximum_index = min(preprocess_chunk_size, length(time_indices)) - time_indices_in_memory = 1:maximum_index - native_fts_architecture = preprocess_architecture - end - end - - # Set a default location. - if isnothing(location) - LX = LY = Center - else - LX, LY = location - end - - ds = Dataset(filepath) - - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - - # Interfaces for the "native" JRA55 grid - λn = ds["lon_bnds"][1, :] - φn = ds["lat_bnds"][1, :] - - # The .nc coordinates lon_bnds and lat_bnds do not include - # the last interface, so we push them here. - push!(φn, 90) - push!(λn, λn[1] + 360) - - # TODO: support loading just part of the JRA55 data. - # Probably with arguments that take latitude, longitude bounds. - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) - - native_times = ds["time"][time_indices] - data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - λr = λn[i₁:i₂+1] - φr = φn[j₁:j₂+1] - Nrx, Nry, Nt = size(data) - close(ds) - - N = (Nrx, Nry) - H = min.(N, (3, 3)) - - JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; - halo = H, - size = N, - longitude = λr, - latitude = φr, - topology = (TX, Bounded, Flat)) - - boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) - times = jra55_times(native_times) - - if backend isa JRA55NetCDFBackend - fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - backend, - time_indexing, - boundary_conditions, - path = filepath, - name = shortname) - - # Fill the data in a GPU-friendly manner - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) - - return fts - else - # Make times into an array for later preprocessing - if !totally_in_memory - times = collect(times) - end - - native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - time_indexing, - boundary_conditions) - - # Fill the data in a GPU-friendly manner - copyto!(interior(native_fts, :, :, 1, :), data) - fill_halo_regions!(native_fts) - - if on_native_grid && totally_in_memory - return native_fts - - elseif totally_in_memory # but not on the native grid! - boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) - fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) - interpolate!(fts, native_fts) - return fts - end - end - - @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - - preprocessing_grid = on_native_grid ? JRA55_native_grid : grid - - # Re-open the dataset! - ds = Dataset(filepath) - all_datetimes = ds["time"][time_indices] - all_Nt = length(all_datetimes) - - all_times = jra55_times(all_datetimes) - - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; - boundary_conditions, - backend = OnDisk(), - path = jld2_filepath, - name = fts_name) - - # Save data to disk, one field at a time - start_clock = time_ns() - n = 1 # on disk - m = 0 # in memory - - times_in_memory = all_times[time_indices_in_memory] - - fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; - boundary_conditions, - backend = InMemory(), - path = jld2_filepath, - name = fts_name) - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) - end - - while n <= all_Nt - print(" ... processing time index $n of $all_Nt \r") - - if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory - m += 1 - else # load new data - # Update time_indices - time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size - n₁ = first(time_indices_in_memory) - - # Clip time_indices if they extend past the end of the dataset - if last(time_indices_in_memory) > all_Nt - time_indices_in_memory = UnitRange(n₁, all_Nt) - end - - # Re-compute times - new_times = jra55_times(all_times[time_indices_in_memory], all_times[n₁]) - native_fts.times = new_times - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - fts.times = new_times - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) - end - - m = 1 # reset - end - - set!(on_disk_fts, fts[m], n, fts.times[m]) - - n += 1 - end - - elapsed = 1e-9 * (time_ns() - start_clock) - elapsed_str = prettytime(elapsed) - @info " ... done ($elapsed_str)" * repeat(" ", 20) - - close(ds) - - user_fts = FieldTimeSeries(jld2_filepath, fts_name; architecture, backend, time_indexing) - fill_halo_regions!(user_fts) - - return user_fts -end diff --git a/src/DataWrangling/jra55_metadata.jl b/src/DataWrangling/jra55_metadata.jl index e9b84fe9a..75a8dfc3c 100644 --- a/src/DataWrangling/jra55_metadata.jl +++ b/src/DataWrangling/jra55_metadata.jl @@ -30,7 +30,7 @@ end # Convenience functions short_name(data::JRA55Metadata) = jra55_short_names[data.name] -field_location(data::JRA55Metadata) = jra55_location[data.name] +field_location(data::JRA55Metadata) = (Center, Center, Center) # A list of all variables provided in the JRA55 dataset: JRA55_variable_names = (:river_freshwater_flux, @@ -91,7 +91,7 @@ field_time_series_short_names = Dict( :northward_velocity => "va", # Northward near-surface wind ) -urls = Dict( +jra55_repeat_year_urls = Dict( :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", @@ -135,10 +135,12 @@ urls = Dict( variable_is_three_dimensional(data::JRA55Metadata) = false # URLs for the JRA55 datasets specific to each version -function urls(metadata::JRA55Metadata) +function urls(metadata::Metadata{<:Any, <:JRA55MultipleYears}) return "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" end +urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = jra55_repeat_year_urls[metadata.name] + function download_dataset!(metadata::JRA55Metadata; url = urls(metadata)) @@ -147,7 +149,6 @@ function download_dataset!(metadata::JRA55Metadata; shortname = short_name(data) if !isfile(filename) - fileurl = joinpath(url, shortname, year, filename) download(url, filepath) end end From 7f4af8822759dca18384ad545c7e54b0f32e34fe Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 8 Nov 2024 15:37:27 +0100 Subject: [PATCH 005/203] in their folder --- src/DataWrangling/{ => JRA55}/JRA55.jl | 0 src/DataWrangling/{ => JRA55}/jra55_field_time_series.jl | 0 src/DataWrangling/{ => JRA55}/jra55_metadata.jl | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/DataWrangling/{ => JRA55}/JRA55.jl (100%) rename src/DataWrangling/{ => JRA55}/jra55_field_time_series.jl (100%) rename src/DataWrangling/{ => JRA55}/jra55_metadata.jl (100%) diff --git a/src/DataWrangling/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl similarity index 100% rename from src/DataWrangling/JRA55.jl rename to src/DataWrangling/JRA55/JRA55.jl diff --git a/src/DataWrangling/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl similarity index 100% rename from src/DataWrangling/jra55_field_time_series.jl rename to src/DataWrangling/JRA55/jra55_field_time_series.jl diff --git a/src/DataWrangling/jra55_metadata.jl b/src/DataWrangling/JRA55/jra55_metadata.jl similarity index 100% rename from src/DataWrangling/jra55_metadata.jl rename to src/DataWrangling/JRA55/jra55_metadata.jl From 8d9401e953ccbcb437c736b7cef641db0042c51b Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 8 Nov 2024 15:45:41 +0100 Subject: [PATCH 006/203] modernize --- src/DataWrangling/DataWrangling.jl | 2 +- src/DataWrangling/ECCO/ECCO_metadata.jl | 41 +- src/DataWrangling/JRA55/JRA55.jl | 573 +----------------- .../JRA55/JRA55_prescribed_atmosphere.jl | 92 +++ .../JRA55/jra55_field_time_series.jl | 502 ++++++++++----- src/DataWrangling/JRA55/jra55_metadata.jl | 6 +- src/DataWrangling/ecco_metadata.jl | 140 ----- src/DataWrangling/metadata.jl | 38 +- 8 files changed, 494 insertions(+), 900 deletions(-) create mode 100644 src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl delete mode 100644 src/DataWrangling/ecco_metadata.jl diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index c0b956883..d118b9cb0 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -73,7 +73,7 @@ end include("metadata.jl") include("inpaint_mask.jl") -include("JRA55.jl") +include("JRA55/JRA55.jl") include("ECCO/ECCO.jl") using .ECCO diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index 8d933f1f7..6d3bcb980 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -10,21 +10,7 @@ struct ECCO2Monthly end struct ECCO2Daily end struct ECCO4Monthly end -""" - ECCOMetadata{D, V} - -Metadata holding the ECCO dataset information: -- `name`: The name of the dataset. -- `dates`: The dates of the dataset, in a `AbstractCFDateTime` format. -- `version`: The version of the dataset, could be ECCO2Monthly, ECCO2Daily, or ECCO4Monthly. -- `dir`: The directory where the dataset is stored. -""" -struct ECCOMetadata{D, V} - name :: Symbol - dates :: D - version :: V - dir :: String -end +const ECCOMetadata{D, V} = Union{Metadata{T, V<:ECCO4Monthly}, Metadata{T, V<:ECCO2Daily}, Metadata{T, V<:ECCO2Monthly}} where {T, V} Base.show(io::IO, metadata::ECCOMetadata) = print(io, "ECCOMetadata:", '\n', @@ -60,32 +46,11 @@ function ECCOMetadata(name::Symbol; version = ECCO4Monthly(), dir = download_ECCO_cache) - return ECCOMetadata(name, dates, version, dir) + return Metadata(name, dates, version, dir) end ECCOMetadata(name::Symbol, date, version=ECCO4Monthly(); dir=download_ECCO_cache) = - ECCOMetadata(name, date, version, dir) - -# Treat ECCOMetadata as an array to allow iteration over the dates. -Base.length(metadata::ECCOMetadata) = length(metadata.dates) -Base.eltype(metadata::ECCOMetadata) = Base.eltype(metadata.dates) -@propagate_inbounds Base.getindex(m::ECCOMetadata, i::Int) = ECCOMetadata(m.name, m.dates[i], m.version, m.dir) -@propagate_inbounds Base.first(m::ECCOMetadata) = ECCOMetadata(m.name, m.dates[1], m.version, m.dir) -@propagate_inbounds Base.last(m::ECCOMetadata) = ECCOMetadata(m.name, m.dates[end], m.version, m.dir) - -@inline function Base.iterate(m::ECCOMetadata, i=1) - if (i % UInt) - 1 < length(m) - return ECCOMetadata(m.name, m.dates[i], m.version, m.dir), i + 1 - else - return nothing - end -end - -Base.axes(metadata::ECCOMetadata{<:AbstractCFDateTime}) = 1 -Base.first(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata -Base.last(metadata::ECCOMetadata{<:AbstractCFDateTime}) = metadata -Base.iterate(metadata::ECCOMetadata{<:AbstractCFDateTime}) = (metadata, nothing) -Base.iterate(::ECCOMetadata{<:AbstractCFDateTime}, ::Any) = nothing + Metadata(name, date, version, dir) Base.size(data::ECCOMetadata{<:Any, <:ECCO2Daily}) = (1440, 720, 50, length(data.dates)) Base.size(data::ECCOMetadata{<:Any, <:ECCO2Monthly}) = (1440, 720, 50, length(data.dates)) diff --git a/src/DataWrangling/JRA55/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl index 3266f2d0f..069b58bdc 100644 --- a/src/DataWrangling/JRA55/JRA55.jl +++ b/src/DataWrangling/JRA55/JRA55.jl @@ -1,5 +1,7 @@ module JRA55 +export JRA55_field_time_series, JRA55_prescribed_atmosphere + using Oceananigans using Oceananigans.Units @@ -26,573 +28,8 @@ import Oceananigans.Fields: set! import Oceananigans.OutputReaders: new_backend, update_field_time_series! using Downloads: download -include("jra55_metadata.jl") - -download_jra55_cache::String = "" -function __init__() - global download_jra55_cache = @get_scratch!("JRA55") -end - -compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing -compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds - -function compute_bounding_nodes(x::Number, ::Nothing, LH, hnodes) - ϵ = convert(typeof(x), 0.001) # arbitrary? - return (x - ϵ, x + ϵ) -end - -# TODO: remove the allowscalar -function compute_bounding_nodes(::Nothing, grid, LH, hnodes) - hg = hnodes(grid, LH()) - h₁ = @allowscalar minimum(hg) - h₂ = @allowscalar maximum(hg) - return h₁, h₂ -end - -function compute_bounding_indices(::Nothing, hc) - Nh = length(hc) - return 1, Nh -end - -function compute_bounding_indices(bounds::Tuple, hc) - h₁, h₂ = bounds - Nh = length(hc) - - # The following should work. If ᵒ are the extrema of nodes we want to - # interpolate to, and the following is a sketch of the JRA55 native grid, - # - # 1 2 3 4 5 - # | | | | | | - # | x ᵒ | x | x | x ᵒ | x | - # | | | | | | - # 1 2 3 4 5 6 - # - # then for example, we should find that (iᵢ, i₂) = (1, 5). - # So we want to reduce the first index by one, and limit them - # both by the available data. There could be some mismatch due - # to the use of different coordinate systems (ie whether λ ∈ (0, 360) - # which we may also need to handle separately. - i₁ = searchsortedfirst(hc, h₁) - i₂ = searchsortedfirst(hc, h₂) - i₁ = max(1, i₁ - 1) - i₂ = min(Nh, i₂) - - return i₁, i₂ -end - -infer_longitudinal_topology(::Nothing) = Periodic - -function infer_longitudinal_topology(λbounds) - λ₁, λ₂ = λbounds - TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded - return TX -end - -function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) - λbounds = compute_bounding_nodes(longitude, grid, LX, λnodes) - φbounds = compute_bounding_nodes(latitude, grid, LY, φnodes) - - i₁, i₂ = compute_bounding_indices(λbounds, λc) - j₁, j₂ = compute_bounding_indices(φbounds, φc) - TX = infer_longitudinal_topology(λbounds) - - return i₁, i₂, j₁, j₂, TX -end - -# Convert dates to range until Oceananigans supports dates natively -function jra55_times(native_times, start_time=native_times[1]) - - times = [] - for native_time in native_times - time = native_time - start_time - time = Second(time).value - push!(times, time) - end - - return times -end - -struct JRA55NetCDFBackend <: AbstractInMemoryBackend{Int} - start :: Int - length :: Int -end - -""" - JRA55NetCDFBackend(length) - -Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. -""" -JRA55NetCDFBackend(length) = JRA55NetCDFBackend(1, length) - -Base.length(backend::JRA55NetCDFBackend) = backend.length -Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") - -const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} - -function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) - - ds = Dataset(path) - - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - LX, LY, LZ = location(fts) - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) - - ti = time_indices(fts) - ti = collect(ti) - data = ds[name][i₁:i₂, j₁:j₂, ti] - close(ds) - - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) - - return nothing -end - -new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length) - -""" - JRA55_field_time_series(variable_name; - architecture = CPU(), - time_indices = nothing, - latitude = nothing, - longitude = nothing, - location = nothing, - url = nothing, - filename = nothing, - shortname = nothing, - backend = InMemory(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU()) - -Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, -which describes one of the variables in the "repeat year forcing" dataset derived -from the Japanese 55-year atmospheric reanalysis for driving ocean-sea-ice models (JRA55-do). -For more information about the derivation of the repeat year forcing dataset, see - -"Stewart et al., JRA55-do-based repeat year forcing datasets for driving ocean–sea-ice models", -Ocean Modelling, 2020, https://doi.org/10.1016/j.ocemod.2019.101557. - -The `variable_name`s (and their `shortname`s used in NetCDF files) -available from the JRA55-do are: - - - `:river_freshwater_flux` ("friver") - - `:rain_freshwater_flux` ("prra") - - `:snow_freshwater_flux` ("prsn") - - `:iceberg_freshwater_flux` ("licalvf") - - `:specific_humidity` ("huss") - - `:sea_level_pressure` ("psl") - - `:relative_humidity` ("rhuss") - - `:downwelling_longwave_radiation` ("rlds") - - `:downwelling_shortwave_radiation` ("rsds") - - `:temperature` ("ras") - - `:eastward_velocity` ("uas") - - `:northward_velocity` ("vas") - -Keyword arguments -================= - - - `architecture`: Architecture for the `FieldTimeSeries`. - Default: CPU() - - - `time_indices`: Indices of the timeseries to extract from file. - For example, `time_indices=1:3` returns a - `FieldTimeSeries` with the first three time snapshots - of `variable_name`. - - - `latitude`: Guiding latitude bounds for the resulting grid. - Used to slice the data when loading into memory. - Default: nothing, which retains the latitude range of the native grid. - - - `longitude`: Guiding longitude bounds for the resulting grid. - Used to slice the data when loading into memory. - Default: nothing, which retains the longitude range of the native grid. - - - `url`: The url accessed to download the data for `variable_name`. - Default: `ClimaOcean.JRA55.urls[variable_name]`. - - - `filename`: The name of the downloaded file. - Default: `ClimaOcean.JRA55.filenames[variable_name]`. - - - `shortname`: The "short name" of `variable_name` inside its NetCDF file. - Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. - - - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. - If it does not exist it will be generated. - - - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is - loaded (not recommended). -""" -function JRA55_field_time_series(variable_name; - architecture = CPU(), - grid = nothing, - location = nothing, - url = nothing, - dir = download_jra55_cache, - filename = nothing, - shortname = nothing, - latitude = nothing, - longitude = nothing, - backend = InMemory(), - time_indexing = Cyclical(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) - - # OnDisk backends do not support time interpolation! - # Disallow OnDisk for JRA55 dataset loading - if backend isa OnDisk - msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") - throw(ArgumentError(msg)) - end - - if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) - variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) - variables_msg = prod(variable_strs) - - msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', - "The variables provided by the JRA55-do dataset are:", '\n', - variables_msg) - - throw(ArgumentError(msg)) - end - - filepath = isnothing(filename) ? joinpath(dir, filenames[variable_name]) : joinpath(dir, filename) - - if !isnothing(filename) && !isfile(filepath) && isnothing(url) - throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ - If intended, please provide both the filename and url that should be used \n \ - to download the new file.")) - end - - isnothing(filename) && (filename = filenames[variable_name]) - isnothing(shortname) && (shortname = jra55_short_names[variable_name]) - isnothing(url) && (url = urls[variable_name]) - - # Record some important user decisions - totally_in_memory = backend isa TotallyInMemory - on_native_grid = isnothing(grid) - !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") - - jld2_filepath = joinpath(dir, string("JRA55_repeat_year_", variable_name, ".jld2")) - fts_name = field_time_series_short_names[variable_name] - - # Note, we don't re-use existing jld2 files. - isfile(filepath) || download(url, filepath) - isfile(jld2_filepath) && rm(jld2_filepath) - - # Determine default time indices - if totally_in_memory - # In this case, the whole time series is in memory. - # Either the time series is short, or we are doing a limited-area - # simulation, like in a single column. So, we conservatively - # set a default `time_indices = 1:2`. - isnothing(time_indices) && (time_indices = 1:2) - time_indices_in_memory = time_indices - native_fts_architecture = architecture - else - # In this case, part or all of the time series will be stored in a file. - # Note: if the user has provided a grid, we will have to preprocess the - # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers - # to the time_indices that we will preprocess; - # by default we choose all of them. The architecture is only the - # architecture used for preprocessing, which typically will be CPU() - # even if we would like the final FieldTimeSeries on the GPU. - isnothing(time_indices) && (time_indices = :) - - if backend isa JRA55NetCDFBackend - time_indices_in_memory = 1:length(backend) - native_fts_architecture = architecture - else # then `time_indices_in_memory` refers to preprocessing - maximum_index = min(preprocess_chunk_size, length(time_indices)) - time_indices_in_memory = 1:maximum_index - native_fts_architecture = preprocess_architecture - end - end - - # Set a default location. - if isnothing(location) - LX = LY = Center - else - LX, LY = location - end - - ds = Dataset(filepath) - - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - - # Interfaces for the "native" JRA55 grid - λn = ds["lon_bnds"][1, :] - φn = ds["lat_bnds"][1, :] - - # The .nc coordinates lon_bnds and lat_bnds do not include - # the last interface, so we push them here. - push!(φn, 90) - push!(λn, λn[1] + 360) - - # TODO: support loading just part of the JRA55 data. - # Probably with arguments that take latitude, longitude bounds. - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) - - native_times = ds["time"][time_indices] - data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - λr = λn[i₁:i₂+1] - φr = φn[j₁:j₂+1] - Nrx, Nry, Nt = size(data) - close(ds) - - N = (Nrx, Nry) - H = min.(N, (3, 3)) - - JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; - halo = H, - size = N, - longitude = λr, - latitude = φr, - topology = (TX, Bounded, Flat)) - - boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) - times = jra55_times(native_times) - - if backend isa JRA55NetCDFBackend - fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - backend, - time_indexing, - boundary_conditions, - path = filepath, - name = shortname) - - # Fill the data in a GPU-friendly manner - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) - - return fts - else - # Make times into an array for later preprocessing - if !totally_in_memory - times = collect(times) - end - - native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - time_indexing, - boundary_conditions) - - # Fill the data in a GPU-friendly manner - copyto!(interior(native_fts, :, :, 1, :), data) - fill_halo_regions!(native_fts) - - if on_native_grid && totally_in_memory - return native_fts - - elseif totally_in_memory # but not on the native grid! - boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) - fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) - interpolate!(fts, native_fts) - return fts - end - end - - @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - - preprocessing_grid = on_native_grid ? JRA55_native_grid : grid - - # Re-open the dataset! - ds = Dataset(filepath) - all_datetimes = ds["time"][time_indices] - all_Nt = length(all_datetimes) - - all_times = jra55_times(all_datetimes) - - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; - boundary_conditions, - backend = OnDisk(), - path = jld2_filepath, - name = fts_name) - - # Save data to disk, one field at a time - start_clock = time_ns() - n = 1 # on disk - m = 0 # in memory - - times_in_memory = all_times[time_indices_in_memory] - - fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; - boundary_conditions, - backend = InMemory(), - path = jld2_filepath, - name = fts_name) - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) - end - - while n <= all_Nt - print(" ... processing time index $n of $all_Nt \r") - - if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory - m += 1 - else # load new data - # Update time_indices - time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size - n₁ = first(time_indices_in_memory) - - # Clip time_indices if they extend past the end of the dataset - if last(time_indices_in_memory) > all_Nt - time_indices_in_memory = UnitRange(n₁, all_Nt) - end - - # Re-compute times - new_times = jra55_times(all_times[time_indices_in_memory], all_times[n₁]) - native_fts.times = new_times - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - fts.times = new_times - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) - end - - m = 1 # reset - end - - set!(on_disk_fts, fts[m], n, fts.times[m]) - - n += 1 - end - - elapsed = 1e-9 * (time_ns() - start_clock) - elapsed_str = prettytime(elapsed) - @info " ... done ($elapsed_str)" * repeat(" ", 20) - - close(ds) - - user_fts = FieldTimeSeries(jld2_filepath, fts_name; architecture, backend, time_indexing) - fill_halo_regions!(user_fts) - - return user_fts -end - -const AA = Oceananigans.Architectures.AbstractArchitecture - -JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = - JRA55_prescribed_atmosphere(CPU(), time_indices; kw...) - -JRA55_prescribed_atmosphere(arch::Distributed, time_indices=Colon(); kw...) = - JRA55_prescribed_atmosphere(child_architecture(arch), time_indices; kw...) - -# TODO: allow the user to pass dates -""" - JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); - backend = nothing, - time_indexing = Cyclical(), - reference_height = 10, # meters - include_rivers_and_icebergs = false, - other_kw...) - -Return a `PrescribedAtmosphere` representing JRA55 reanalysis data. -""" -function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); - backend = nothing, - time_indexing = Cyclical(), - reference_height = 10, # meters - include_rivers_and_icebergs = false, - other_kw...) - - if isnothing(backend) # apply a default - Ni = try - length(time_indices) - catch - Inf - end - - # Manufacture a default for the number of fields to keep InMemory - Nf = min(24, Ni) - backend = JRA55NetCDFBackend(Nf) - end - - kw = (; time_indices, time_indexing, backend, architecture) - kw = merge(kw, other_kw) - - ua = JRA55_field_time_series(:eastward_velocity; kw...) - va = JRA55_field_time_series(:northward_velocity; kw...) - Ta = JRA55_field_time_series(:temperature; kw...) - qa = JRA55_field_time_series(:specific_humidity; kw...) - pa = JRA55_field_time_series(:sea_level_pressure; kw...) - Fra = JRA55_field_time_series(:rain_freshwater_flux; kw...) - Fsn = JRA55_field_time_series(:snow_freshwater_flux; kw...) - Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) - Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) - - freshwater_flux = (rain = Fra, - snow = Fsn) - - # Remember that rivers and icebergs are on a different grid and have - # a different frequency than the rest of the JRA55 data. We use `PrescribedAtmospheres` - # "auxiliary_freshwater_flux" feature to represent them. - if include_rivers_and_icebergs - Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) - Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) - auxiliary_freshwater_flux = (rivers = Fri, icebergs = Fic) - else - auxiliary_freshwater_flux = nothing - end - - times = ua.times - - velocities = (u = ua, - v = va) - - tracers = (T = Ta, - q = qa) - - pressure = pa - - downwelling_radiation = TwoBandDownwellingRadiation(shortwave=Qs, longwave=Ql) - - FT = eltype(ua) - reference_height = convert(FT, reference_height) - - atmosphere = PrescribedAtmosphere(times, FT; - velocities, - freshwater_flux, - auxiliary_freshwater_flux, - tracers, - downwelling_radiation, - reference_height, - pressure) - - return atmosphere -end +include("JRA55_metadata.jl") +include("JRA55_field_time_series.jl") +include("JRA55_prescribed_atmosphere.jl") end # module diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl new file mode 100644 index 000000000..8f5eec377 --- /dev/null +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -0,0 +1,92 @@ + +const AA = Oceananigans.Architectures.AbstractArchitecture + +JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = + JRA55_prescribed_atmosphere(CPU(), time_indices; kw...) + +JRA55_prescribed_atmosphere(arch::Distributed, time_indices=Colon(); kw...) = + JRA55_prescribed_atmosphere(child_architecture(arch), time_indices; kw...) + +# TODO: allow the user to pass dates +""" + JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); + backend = nothing, + time_indexing = Cyclical(), + reference_height = 10, # meters + include_rivers_and_icebergs = false, + other_kw...) + +Return a `PrescribedAtmosphere` representing JRA55 reanalysis data. +""" +function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); + backend = nothing, + time_indexing = Cyclical(), + reference_height = 10, # meters + include_rivers_and_icebergs = false, + other_kw...) + + if isnothing(backend) # apply a default + Ni = try + length(time_indices) + catch + Inf + end + + # Manufacture a default for the number of fields to keep InMemory + Nf = min(24, Ni) + backend = JRA55NetCDFBackend(Nf) + end + + kw = (; time_indices, time_indexing, backend, architecture) + kw = merge(kw, other_kw) + + ua = JRA55_field_time_series(:eastward_velocity; kw...) + va = JRA55_field_time_series(:northward_velocity; kw...) + Ta = JRA55_field_time_series(:temperature; kw...) + qa = JRA55_field_time_series(:specific_humidity; kw...) + pa = JRA55_field_time_series(:sea_level_pressure; kw...) + Fra = JRA55_field_time_series(:rain_freshwater_flux; kw...) + Fsn = JRA55_field_time_series(:snow_freshwater_flux; kw...) + Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) + Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) + + freshwater_flux = (rain = Fra, + snow = Fsn) + + # Remember that rivers and icebergs are on a different grid and have + # a different frequency than the rest of the JRA55 data. We use `PrescribedAtmospheres` + # "auxiliary_freshwater_flux" feature to represent them. + if include_rivers_and_icebergs + Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) + Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) + auxiliary_freshwater_flux = (rivers = Fri, icebergs = Fic) + else + auxiliary_freshwater_flux = nothing + end + + times = ua.times + + velocities = (u = ua, + v = va) + + tracers = (T = Ta, + q = qa) + + pressure = pa + + downwelling_radiation = TwoBandDownwellingRadiation(shortwave=Qs, longwave=Ql) + + FT = eltype(ua) + reference_height = convert(FT, reference_height) + + atmosphere = PrescribedAtmosphere(times, FT; + velocities, + freshwater_flux, + auxiliary_freshwater_flux, + tracers, + downwelling_radiation, + reference_height, + pressure) + + return atmosphere +end diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl index 649001d40..a9004f910 100644 --- a/src/DataWrangling/JRA55/jra55_field_time_series.jl +++ b/src/DataWrangling/JRA55/jra55_field_time_series.jl @@ -1,53 +1,108 @@ -using Oceananigans.Units -using Oceananigans.Grids: node, on_architecture -using Oceananigans.Fields: interpolate!, interpolate, location, instantiated_location -using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices -using Oceananigans.Utils: Time -using CUDA: @allowscalar -using Base +download_jra55_cache::String = "" +function __init__() + global download_jra55_cache = @get_scratch!("JRA55") +end + +compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing +compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds + +function compute_bounding_nodes(x::Number, ::Nothing, LH, hnodes) + ϵ = convert(typeof(x), 0.001) # arbitrary? + return (x - ϵ, x + ϵ) +end + +# TODO: remove the allowscalar +function compute_bounding_nodes(::Nothing, grid, LH, hnodes) + hg = hnodes(grid, LH()) + h₁ = @allowscalar minimum(hg) + h₂ = @allowscalar maximum(hg) + return h₁, h₂ +end + +function compute_bounding_indices(::Nothing, hc) + Nh = length(hc) + return 1, Nh +end + +function compute_bounding_indices(bounds::Tuple, hc) + h₁, h₂ = bounds + Nh = length(hc) + + # The following should work. If ᵒ are the extrema of nodes we want to + # interpolate to, and the following is a sketch of the JRA55 native grid, + # + # 1 2 3 4 5 + # | | | | | | + # | x ᵒ | x | x | x ᵒ | x | + # | | | | | | + # 1 2 3 4 5 6 + # + # then for example, we should find that (iᵢ, i₂) = (1, 5). + # So we want to reduce the first index by one, and limit them + # both by the available data. There could be some mismatch due + # to the use of different coordinate systems (ie whether λ ∈ (0, 360) + # which we may also need to handle separately. + i₁ = searchsortedfirst(hc, h₁) + i₂ = searchsortedfirst(hc, h₂) + i₁ = max(1, i₁ - 1) + i₂ = min(Nh, i₂) + + return i₁, i₂ +end -using NCDatasets -using JLD2 -using Dates +infer_longitudinal_topology(::Nothing) = Periodic -using ClimaOcean: stateindex -using ClimaOcean.DataWrangling: native_times +function infer_longitudinal_topology(λbounds) + λ₁, λ₂ = λbounds + TX = λ₂ - λ₁ ≈ 360 ? Periodic : Bounded + return TX +end + +function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + λbounds = compute_bounding_nodes(longitude, grid, LX, λnodes) + φbounds = compute_bounding_nodes(latitude, grid, LY, φnodes) + + i₁, i₂ = compute_bounding_indices(λbounds, λc) + j₁, j₂ = compute_bounding_indices(φbounds, φc) + TX = infer_longitudinal_topology(λbounds) + + return i₁, i₂, j₁, j₂, TX +end -import Oceananigans.Fields: set! -import Oceananigans.OutputReaders: new_backend, update_field_time_series! +# Convert dates to range until Oceananigans supports dates natively +function jra55_times(native_times, start_time=native_times[1]) -@inline instantiate(T::DataType) = T() -@inline instantiate(T) = T + times = [] + for native_time in native_times + time = native_time - start_time + time = Second(time).value + push!(times, time) + end + + return times +end -struct JRA55NetCDFBackend{N} <: AbstractInMemoryBackend{Int} +struct JRA55NetCDFBackend <: AbstractInMemoryBackend{Int} start :: Int length :: Int - - JRA55NetCDFBackend{N}(start::Int, length::Int) where N = new{N}(start, length) end """ JRA55NetCDFBackend(length) -Represents an JRA55 FieldTimeSeries backed by JRA55 native .nc files. -Each time instance is stored in an individual file. +Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. """ -JRA55NetCDFBackend(length; on_native_grid = false) = JRA55NetCDFBackend{on_native_grid}(1, length) +JRA55NetCDFBackend(length) = JRA55NetCDFBackend(1, length) -Base.length(backend::JRA55NetCDFBackend) = backend.length +Base.length(backend::JRA55NetCDFBackend) = backend.length Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") -const JRA55NetCDFFTS{N} = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <: JRA55NetCDFBackend{N}} where N +const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} -new_backend(::JRA55NetCDFBackend{N}, start, length) where N = JRA55ONetCDFBackend{N}(start, length) -on_native_grid(::JRA55NetCDFBackend{N}) where N = N +function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) -function set!(fts::JRA55NetCDFFTS, path::JRA55Metadata=fts.path, name::String=fts.name) - - # Do different things based on the Backend... - filename = metadata_filename(path) - ds = filename isa String ? Dataset(filename) : Dataset(filename[1]) + ds = Dataset(path) # Note that each file should have the variables # - ds["time"]: time coordinate @@ -64,54 +119,185 @@ function set!(fts::JRA55NetCDFFTS, path::JRA55Metadata=fts.path, name::String=ft i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) ti = time_indices(fts) - - if on_native_grid(fts.backend) - ti = collect(ti) - data = ds[name][i₁:i₂, j₁:j₂, ti] - copyto!(interior(fts, :, :, 1, :), data) - end - + ti = collect(ti) + data = ds[name][i₁:i₂, j₁:j₂, ti] close(ds) + + copyto!(interior(fts, :, :, 1, :), data) fill_halo_regions!(fts) - + return nothing end +new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length) + """ - JRA55_field_time_series(metadata::ECCOMetadata; - architecture = CPU(), - time_indices_in_memory = 2, - time_indexing = Cyclical(), - grid = nothing) - -Create a field time series object for JRA55 data. - -Arguments: -=========== -- metadata: An JRA55Metadata object containing information about the JRA55 dataset. - -Keyword Arguments: -===================== -- architecture: The architecture to use for computations (default: CPU()). -- time_indices_in_memory: The number of time indices to keep in memory (default: 2). -- time_indexing: The time indexing scheme to use (default: Cyclical()). -- grid: if not a `nothing`, the ECCO data is directly interpolated on the `grid`, + JRA55_field_time_series(variable_name; + architecture = CPU(), + time_indices = nothing, + latitude = nothing, + longitude = nothing, + location = nothing, + url = nothing, + filename = nothing, + shortname = nothing, + backend = InMemory(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU()) + +Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, +which describes one of the variables in the "repeat year forcing" dataset derived +from the Japanese 55-year atmospheric reanalysis for driving ocean-sea-ice models (JRA55-do). +For more information about the derivation of the repeat year forcing dataset, see + +"Stewart et al., JRA55-do-based repeat year forcing datasets for driving ocean–sea-ice models", +Ocean Modelling, 2020, https://doi.org/10.1016/j.ocemod.2019.101557. + +The `variable_name`s (and their `shortname`s used in NetCDF files) +available from the JRA55-do are: + + - `:river_freshwater_flux` ("friver") + - `:rain_freshwater_flux` ("prra") + - `:snow_freshwater_flux` ("prsn") + - `:iceberg_freshwater_flux` ("licalvf") + - `:specific_humidity` ("huss") + - `:sea_level_pressure` ("psl") + - `:relative_humidity` ("rhuss") + - `:downwelling_longwave_radiation` ("rlds") + - `:downwelling_shortwave_radiation` ("rsds") + - `:temperature` ("ras") + - `:eastward_velocity` ("uas") + - `:northward_velocity` ("vas") + +Keyword arguments +================= + + - `architecture`: Architecture for the `FieldTimeSeries`. + Default: CPU() + + - `time_indices`: Indices of the timeseries to extract from file. + For example, `time_indices=1:3` returns a + `FieldTimeSeries` with the first three time snapshots + of `variable_name`. + + - `latitude`: Guiding latitude bounds for the resulting grid. + Used to slice the data when loading into memory. + Default: nothing, which retains the latitude range of the native grid. + + - `longitude`: Guiding longitude bounds for the resulting grid. + Used to slice the data when loading into memory. + Default: nothing, which retains the longitude range of the native grid. + + - `url`: The url accessed to download the data for `variable_name`. + Default: `ClimaOcean.JRA55.urls[variable_name]`. + + - `filename`: The name of the downloaded file. + Default: `ClimaOcean.JRA55.filenames[variable_name]`. + + - `shortname`: The "short name" of `variable_name` inside its NetCDF file. + Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. + + - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. + If it does not exist it will be generated. + + - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is + loaded (not recommended). """ -function JRA55_field_time_series(metadata::JRA55Metadata; - architecture = CPU(), - time_indices_in_memory = 2, - time_indexing = Cyclical(), +function JRA55_field_time_series(variable_name; + architecture = CPU(), grid = nothing, + location = nothing, + url = nothing, + dir = download_jra55_cache, + filename = nothing, + shortname = nothing, latitude = nothing, - longitude = nothing) + longitude = nothing, + backend = InMemory(), + time_indexing = Cyclical(), + preprocess_chunk_size = 10, + preprocess_architecture = CPU(), + time_indices = nothing) + + # OnDisk backends do not support time interpolation! + # Disallow OnDisk for JRA55 dataset loading + if backend isa OnDisk + msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") + throw(ArgumentError(msg)) + end - backend = JRA55NetCDFBackend(time_indices_in_memory; on_native_grid = isnothing(grid)) + if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) + variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) + variables_msg = prod(variable_strs) - # Making sure all the required individual files are downloaded - download_dataset!(metadata) + msg = string("The variable :$variable_name is not provided by the JRA55-do dataset!", '\n', + "The variables provided by the JRA55-do dataset are:", '\n', + variables_msg) - filename = metadata_filename(metadata) - ds = Dataset(filename) + throw(ArgumentError(msg)) + end + + filepath = isnothing(filename) ? joinpath(dir, filenames[variable_name]) : joinpath(dir, filename) + + if !isnothing(filename) && !isfile(filepath) && isnothing(url) + throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ + If intended, please provide both the filename and url that should be used \n \ + to download the new file.")) + end + + isnothing(filename) && (filename = filenames[variable_name]) + isnothing(shortname) && (shortname = jra55_short_names[variable_name]) + isnothing(url) && (url = urls[variable_name]) + + # Record some important user decisions + totally_in_memory = backend isa TotallyInMemory + on_native_grid = isnothing(grid) + !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") + + jld2_filepath = joinpath(dir, string("JRA55_repeat_year_", variable_name, ".jld2")) + fts_name = field_time_series_short_names[variable_name] + + # Note, we don't re-use existing jld2 files. + isfile(filepath) || download(url, filepath) + isfile(jld2_filepath) && rm(jld2_filepath) + + # Determine default time indices + if totally_in_memory + # In this case, the whole time series is in memory. + # Either the time series is short, or we are doing a limited-area + # simulation, like in a single column. So, we conservatively + # set a default `time_indices = 1:2`. + isnothing(time_indices) && (time_indices = 1:2) + time_indices_in_memory = time_indices + native_fts_architecture = architecture + else + # In this case, part or all of the time series will be stored in a file. + # Note: if the user has provided a grid, we will have to preprocess the + # .nc JRA55 data into a .jld2 file. In this case, `time_indices` refers + # to the time_indices that we will preprocess; + # by default we choose all of them. The architecture is only the + # architecture used for preprocessing, which typically will be CPU() + # even if we would like the final FieldTimeSeries on the GPU. + isnothing(time_indices) && (time_indices = :) + + if backend isa JRA55NetCDFBackend + time_indices_in_memory = 1:length(backend) + native_fts_architecture = architecture + else # then `time_indices_in_memory` refers to preprocessing + maximum_index = min(preprocess_chunk_size, length(time_indices)) + time_indices_in_memory = 1:maximum_index + native_fts_architecture = preprocess_architecture + end + end + + # Set a default location. + if isnothing(location) + LX = LY = Center + else + LX, LY = location + end + + ds = Dataset(filepath) # Note that each file should have the variables # - ds["time"]: time coordinate @@ -148,7 +334,7 @@ function JRA55_field_time_series(metadata::JRA55Metadata; N = (Nrx, Nry) H = min.(N, (3, 3)) - JRA55_native_grid = LatitudeLongitudeGrid(architecture, Float32; + JRA55_native_grid = LatitudeLongitudeGrid(native_fts_architecture, Float32; halo = H, size = N, longitude = λr, @@ -156,92 +342,134 @@ function JRA55_field_time_series(metadata::JRA55Metadata; topology = (TX, Bounded, Flat)) boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) + times = jra55_times(native_times) - location = field_location(metadata) - shortname = short_name(metadata) + if backend isa JRA55NetCDFBackend + fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = filepath, + name = shortname) - boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, location) - times = native_times(metadata) + # Fill the data in a GPU-friendly manner + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) + + return fts + else + # Make times into an array for later preprocessing + if !totally_in_memory + times = collect(times) + end + + native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + time_indexing, + boundary_conditions) + + # Fill the data in a GPU-friendly manner + copyto!(interior(native_fts, :, :, 1, :), data) + fill_halo_regions!(native_fts) + + if on_native_grid && totally_in_memory + return native_fts + + elseif totally_in_memory # but not on the native grid! + boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) + fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) + interpolate!(fts, native_fts) + return fts + end + end - fts_grid = isnothing(grid) ? JRA55_native_grid : grid + @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - path = metadata - - fts = FieldTimeSeries{location...}(fts_grid, times; - backend, - time_indexing, - boundary_conditions, - path, - name = metadata.name) + preprocessing_grid = on_native_grid ? JRA55_native_grid : grid - # Let's set the data - set!(fts) + # Re-open the dataset! + ds = Dataset(filepath) + all_datetimes = ds["time"][time_indices] + all_Nt = length(all_datetimes) - return fts -end + all_times = jra55_times(all_datetimes) -JRA55_field_time_series(variable_name::Symbol, version=JRA55RepeatYear(); kw...) = - JRA55_field_time_series(Metadata(variable_name, all_dates(version), version); kw...) + on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; + boundary_conditions, + backend = OnDisk(), + path = jld2_filepath, + name = fts_name) -""" - JRA55_field_time_series(variable_name; - architecture = CPU(), - location = nothing, - url = nothing, - filename = nothing, - shortname = nothing, - backend = InMemory(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU(), - time_indices = nothing) + # Save data to disk, one field at a time + start_clock = time_ns() + n = 1 # on disk + m = 0 # in memory -Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, -which describes one of the variables in the "repeat year forcing" dataset derived -from the Japanese 55-year atmospheric reanalysis for driving ocean-sea-ice models (JRA55-do). -For more information about the derivation of the repeat year forcing dataset, see + times_in_memory = all_times[time_indices_in_memory] -"Stewart et al., JRA55-do-based repeat year forcing datasets for driving ocean–sea-ice models", -Ocean Modelling, 2020, https://doi.org/10.1016/j.ocemod.2019.101557. + fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; + boundary_conditions, + backend = InMemory(), + path = jld2_filepath, + name = fts_name) -The `variable_name`s (and their `shortname`s used in NetCDF files) -available from the JRA55-do are: + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - - `:river_freshwater_flux` ("friver") - - `:rain_freshwater_flux` ("prra") - - `:snow_freshwater_flux` ("prsn") - - `:iceberg_freshwater_flux` ("licalvf") - - `:specific_humidity` ("huss") - - `:sea_level_pressure` ("psl") - - `:relative_humidity` ("rhuss") - - `:downwelling_longwave_radiation` ("rlds") - - `:downwelling_shortwave_radiation` ("rsds") - - `:temperature` ("ras") - - `:eastward_velocity` ("uas") - - `:northward_velocity` ("vas") + if !on_native_grid + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + end -Keyword arguments -================= + while n <= all_Nt + print(" ... processing time index $n of $all_Nt \r") - - `architecture`: Architecture for the `FieldTimeSeries`. - Default: CPU() + if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory + m += 1 + else # load new data + # Update time_indices + time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size + n₁ = first(time_indices_in_memory) - - `time_indices`: Indices of the timeseries to extract from file. - For example, `time_indices=1:3` returns a - `FieldTimeSeries` with the first three time snapshots - of `variable_name`. + # Clip time_indices if they extend past the end of the dataset + if last(time_indices_in_memory) > all_Nt + time_indices_in_memory = UnitRange(n₁, all_Nt) + end - - `url`: The url accessed to download the data for `variable_name`. - Default: `ClimaOcean.JRA55.urls[variable_name]`. + # Re-compute times + new_times = jra55_times(all_times[time_indices_in_memory], all_times[n₁]) + native_fts.times = new_times - - `filename`: The name of the downloaded file. - Default: `ClimaOcean.JRA55.filenames[variable_name]`. + # Re-compute data + new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + fts.times = new_times - - `shortname`: The "short name" of `variable_name` inside its NetCDF file. - Default: `ClimaOcean.JRA55.jra55_short_names[variable_name]`. + if !on_native_grid + copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) + fill_halo_regions!(native_fts) + interpolate!(fts, native_fts) + else + copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + end - - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. - If it does not exist it will be generated. + m = 1 # reset + end - - `time_chunks_in_memory`: number of fields held in memory. If `nothing` the whole timeseries is - loaded (not recommended). -""" + set!(on_disk_fts, fts[m], n, fts.times[m]) + + n += 1 + end + + elapsed = 1e-9 * (time_ns() - start_clock) + elapsed_str = prettytime(elapsed) + @info " ... done ($elapsed_str)" * repeat(" ", 20) + + close(ds) + + user_fts = FieldTimeSeries(jld2_filepath, fts_name; architecture, backend, time_indexing) + fill_halo_regions!(user_fts) + + return user_fts +end \ No newline at end of file diff --git a/src/DataWrangling/JRA55/jra55_metadata.jl b/src/DataWrangling/JRA55/jra55_metadata.jl index 75a8dfc3c..52669a0b4 100644 --- a/src/DataWrangling/JRA55/jra55_metadata.jl +++ b/src/DataWrangling/JRA55/jra55_metadata.jl @@ -9,7 +9,7 @@ using ClimaOcean.DataWrangling: Metadata struct JRA55MultipleYears end struct JRA55RepeatYear end -const JRA55Metadata{T} = Union{Metadata{T, <:JRA55MultipleYears}, Metadata{<:JRA55RepeatYear}} where T +const JRA55Metadata{T, V} = Union{Metadata{T, V<:JRA55MultipleYears}, Metadata{T, V<:JRA55RepeatYear}} where {T, V} Base.size(data::JRA55Metadata) = (640, 320, length(data.dates)) Base.size(::JRA55Metadata{<:AbstractCFDateTime}) = (640, 320, 1) @@ -29,8 +29,8 @@ function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55Repea end # Convenience functions -short_name(data::JRA55Metadata) = jra55_short_names[data.name] -field_location(data::JRA55Metadata) = (Center, Center, Center) +short_name(data::JRA55Metadata) = jra55_short_names[data.name] +location(data::JRA55Metadata) = (Center, Center, Center) # A list of all variables provided in the JRA55 dataset: JRA55_variable_names = (:river_freshwater_flux, diff --git a/src/DataWrangling/ecco_metadata.jl b/src/DataWrangling/ecco_metadata.jl deleted file mode 100644 index c2e61f5c7..000000000 --- a/src/DataWrangling/ecco_metadata.jl +++ /dev/null @@ -1,140 +0,0 @@ -using CFTime -using Dates -import Dates: year, month, day -import Oceananigans.Fields: set! -import Base - -using ClimaOcean.DataWrangling: Metadata - -struct ECCO2Monthly end -struct ECCO2Daily end -struct ECCO4Monthly end - -const ECCOMetadata{T} = Union{Metadata{T, <:ECCO4Monthly}, Metadata{T, <:ECCO2Daily}, Metadata{T, <:ECCO2Monthly}} where T - -Base.size(data::Metadata{<:Any, <:ECCO2Daily}) = (1440, 720, 50, length(data.dates)) -Base.size(data::Metadata{<:Any, <:ECCO2Monthly}) = (1440, 720, 50, length(data.dates)) -Base.size(data::Metadata{<:Any, <:ECCO4Monthly}) = (720, 360, 50, length(data.dates)) - -Base.size(::Metadata{<:AbstractCFDateTime, <:ECCO2Daily}) = (1440, 720, 50, 1) -Base.size(::Metadata{<:AbstractCFDateTime, <:ECCO2Monthly}) = (1440, 720, 50, 1) -Base.size(::Metadata{<:AbstractCFDateTime, <:ECCO4Monthly}) = (720, 360, 50, 1) - -# The whole range of dates in the different dataset versions -all_ecco_dates(::ECCO4Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) -all_ecco_dates(::ECCO2Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) -all_ecco_dates(::ECCO2Daily) = DateTimeProlepticGregorian(1992, 1, 4) : Day(1) : DateTimeProlepticGregorian(2023, 12, 31) - -# File name generation specific to each Dataset version -function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:ECCO4Monthly}) - shortname = short_name(metadata) - yearstr = string(Dates.year(metadata.dates)) - monthstr = string(Dates.month(metadata.dates), pad=2) - return shortname * "_" * yearstr * "_" * monthstr * ".nc" -end - -function metadata_filename(metadata::ECCOMetadata{<:AbstractCFDateTime}) - shortname = short_name(metadata) - yearstr = string(Dates.year(metadata.dates)) - monthstr = string(Dates.month(metadata.dates), pad=2) - postfix = variable_is_three_dimensional(metadata) ? ".1440x720x50." : ".1440x720." - - if metadata.version isa ECCO2Monthly - return shortname * postfix * yearstr * monthstr * ".nc" - elseif metadata.version isa ECCO2Daily - daystr = string(Dates.day(metadata.dates), pad=2) - return shortname * postfix * yearstr * monthstr * daystr * ".nc" - end -end - -# Convenience functions -short_name(data::Metadata{<:Any, <:ECCO2Daily}) = ecco2_short_names[data.name] -short_name(data::Metadata{<:Any, <:ECCO2Monthly}) = ecco2_short_names[data.name] -short_name(data::Metadata{<:Any, <:ECCO4Monthly}) = ecco4_short_names[data.name] - -field_location(data::ECCOMetadata) = ecco_location[data.name] - -variable_is_three_dimensional(data::ECCOMetadata) = - data.name == :temperature || - data.name == :salinity || - data.name == :u_velocity || - data.name == :v_velocity - -ecco4_short_names = Dict( - :temperature => "THETA", - :salinity => "SALT", - :u_velocity => "EVEL", - :v_velocity => "NVEL", - :sea_ice_thickness => "SIheff", - :sea_ice_area_fraction => "SIarea" -) - -ecco2_short_names = Dict( - :temperature => "THETA", - :salinity => "SALT", - :u_velocity => "UVEL", - :v_velocity => "VVEL", - :sea_ice_thickness => "SIheff", - :sea_ice_area_fraction => "SIarea" -) - -ecco_location = Dict( - :temperature => (Center, Center, Center), - :salinity => (Center, Center, Center), - :sea_ice_thickness => (Center, Center, Nothing), - :sea_ice_area_fraction => (Center, Center, Nothing), - :u_velocity => (Face, Center, Center), - :v_velocity => (Center, Face, Center), -) - -# URLs for the ECCO datasets specific to each version -urls(::Metadata{<:Any, <:ECCO2Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" -urls(::Metadata{<:Any, <:ECCO2Daily}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/daily/" -urls(::Metadata{<:Any, <:ECCO4Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" - -""" - download_dataset!(metadata::Metadata) - -Download the dataset specified by the given metadata. If the metadata contains a single date, -the dataset is downloaded directly. If the metadata contains multiple dates, the dataset is -downloaded for each date individually. -The data download requires a username and password to be provided in the ECCO_USERNAME and ECCO_PASSWORD -environment variables. This can be done by exporting the environment variables in the shell before running the script, -or by launching julia with - -ECCO_USERNAME=myuser ECCO_PASSWORD=mypasswrd julia - -# Arguments -- `metadata::Metadata`: The metadata specifying the dataset to be downloaded. -""" -function download_dataset!(metadata::ECCOMetadata; - url = urls(metadata)) - - username = get(ENV, "ECCO_USERNAME", nothing) - password = get(ENV, "ECCO_PASSWORD", nothing) - - for data in metadata - filename = metadata_filename(data) - shortname = short_name(data) - - if !isfile(filename) - - isnothing(username) && throw(ArgumentError("Could not find the username for $(url). Please provide a username in the ECCO_USERNAME environment variable.")) - isnothing(password) && throw(ArgumentError("Could not find the username for $(url). Please provide a password in the ECCO_PASSWORD environment variable.")) - - # Version specific download file url - if data.version isa ECCO2Monthly || data.version isa ECCO2Daily - fileurl = joinpath(url, shortname, filename) - elseif data.version isa ECCO4Monthly - year = string(Dates.year(data.dates)) - fileurl = joinpath(url, shortname, year, filename) - end - - cmd = `wget --http-user=$(username) --http-passwd=$(password) $(fileurl)` - - run(cmd) - end - end - - return nothing -end \ No newline at end of file diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 523fdd2c0..df8de0dd0 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -1,12 +1,19 @@ -# Metadata holding the ECCO dataset information: -# - `name`: The name of the dataset. -# - `dates`: The dates of the dataset, in a `AbstractCFDateTime` format. -# - `version`: The version of the dataset, could be ECCO2Monthly, ECCO2Daily, or ECCO4Monthly. + +""" + Metadata{D, V} + +Metadata holding the dataset information: +- `name`: The name of the dataset. +- `dates`: The dates of the dataset, in a `AbstractCFDateTime` format. +- `version`: The version of the dataset, could be ECCO2Monthly, ECCO2Daily, or ECCO4Monthly. +- `dir`: The directory where the dataset is stored. +""" struct Metadata{D, V} name :: Symbol dates :: D version :: V + dir :: String end Base.show(io::IO, metadata::Metadata) = @@ -15,13 +22,21 @@ Base.show(io::IO, metadata::Metadata) = "├── dates: $(metadata.dates)", '\n', "└── data version: $(metadata.version)") + # Treat Metadata as an array to allow iteration over the dates. -Base.getindex(metadata::Metadata, i::Int) = @inbounds Metadata(metadata.name, metadata.dates[i], metadata.version) -Base.length(metadata::Metadata) = length(metadata.dates) -Base.eltype(metadata::Metadata) = Base.eltype(metadata.dates) -Base.first(metadata::Metadata) = @inbounds Metadata(metadata.name, metadata.dates[1], metadata.version) -Base.last(metadata::Metadata) = @inbounds Metadata(metadata.name, metadata.dates[end], metadata.version) -Base.iterate(metadata::Metadata, i=1) = (@inline; (i % UInt) - 1 < length(metadata) ? (@inbounds Metadata(metadata.name, metadata.dates[i], metadata.version), i + 1) : nothing) +Base.length(metadata::Metadata) = length(metadata.dates) +Base.eltype(metadata::Metadata) = Base.eltype(metadata.dates) +@propagate_inbounds Base.getindex(m::Metadata, i::Int) = Metadata(m.name, m.dates[i], m.version, m.dir) +@propagate_inbounds Base.first(m::Metadata) = Metadata(m.name, m.dates[1], m.version, m.dir) +@propagate_inbounds Base.last(m::Metadata) = Metadata(m.name, m.dates[end], m.version, m.dir) + +@inline function Base.iterate(m::Metadata, i=1) + if (i % UInt) - 1 < length(m) + return ECCOMetadata(m.name, m.dates[i], m.version, m.dir), i + 1 + else + return nothing + end +end Base.axes(metadata::Metadata{<:AbstractCFDateTime}) = 1 Base.first(metadata::Metadata{<:AbstractCFDateTime}) = metadata @@ -29,9 +44,6 @@ Base.last(metadata::Metadata{<:AbstractCFDateTime}) = metadata Base.iterate(metadata::Metadata{<:AbstractCFDateTime}) = (metadata, nothing) Base.iterate(::Metadata{<:AbstractCFDateTime}, ::Any) = nothing -Base.size(data::Metadata{<:Any, <:JRA55ThreeHourly}) = (640, 320, 1, length(data.dates)) - - """ native_times(metadata; start_time = metadata.dates[1]) From a7a3268419419fa75ada68e2b6d03573701d3ee2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 8 Nov 2024 16:23:34 +0100 Subject: [PATCH 007/203] start changing stuff --- .../JRA55/jra55_field_time_series.jl | 6 +-- src/DataWrangling/JRA55/jra55_metadata.jl | 41 ++++++------------- 2 files changed, 16 insertions(+), 31 deletions(-) diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl index a9004f910..a11be48f6 100644 --- a/src/DataWrangling/JRA55/jra55_field_time_series.jl +++ b/src/DataWrangling/JRA55/jra55_field_time_series.jl @@ -132,9 +132,9 @@ end new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length) """ - JRA55_field_time_series(variable_name; - architecture = CPU(), - time_indices = nothing, + JRA55_field_time_series(variable_name, [architecture = CPU()]; + version = JRA55RepeatYear(), + dates = all_JRA55_dates(version), latitude = nothing, longitude = nothing, location = nothing, diff --git a/src/DataWrangling/JRA55/jra55_metadata.jl b/src/DataWrangling/JRA55/jra55_metadata.jl index 52669a0b4..b309dd00a 100644 --- a/src/DataWrangling/JRA55/jra55_metadata.jl +++ b/src/DataWrangling/JRA55/jra55_metadata.jl @@ -14,6 +14,10 @@ const JRA55Metadata{T, V} = Union{Metadata{T, V<:JRA55MultipleYears}, Metadata{T Base.size(data::JRA55Metadata) = (640, 320, length(data.dates)) Base.size(::JRA55Metadata{<:AbstractCFDateTime}) = (640, 320, 1) +# The whole range of dates in the different dataset versions +all_JRA55_times(::JRA55RepeatYear) = DateTimeProlepticGregorian(1990, 1, 1) : Hour(3) : DateTimeProlepticGregorian(1991, 1, 1) +all_JRA55_times(::JRA55MultipleYears) = DateTimeProlepticGregorian(1958, 1, 1) : Hour(3) : DateTimeProlepticGregorian(2018, 12, 1) + # File name generation specific to each Dataset version function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) # fix the filename @@ -23,9 +27,8 @@ end # File name generation specific to each Dataset version function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55RepeatYear}) - # fix the filename - - return filename + shortname = short_name(metadata) + return "RYF." * shortname * ".1990_1991.nc" end # Convenience functions @@ -46,22 +49,7 @@ JRA55_variable_names = (:river_freshwater_flux, :eastward_velocity, :northward_velocity) -filenames = Dict( - :river_freshwater_flux => "RYF.friver.1990_1991.nc", # Freshwater fluxes from rivers - :rain_freshwater_flux => "RYF.prra.1990_1991.nc", # Freshwater flux from rainfall - :snow_freshwater_flux => "RYF.prsn.1990_1991.nc", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "RYF.licalvf.1990_1991.nc", # Freshwater flux from calving icebergs - :specific_humidity => "RYF.huss.1990_1991.nc", # Surface specific humidity - :sea_level_pressure => "RYF.psl.1990_1991.nc", # Sea level pressure - :relative_humidity => "RYF.rhuss.1990_1991.nc", # Surface relative humidity - :downwelling_longwave_radiation => "RYF.rlds.1990_1991.nc", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "RYF.rsds.1990_1991.nc", # Downwelling shortwave radiation - :temperature => "RYF.tas.1990_1991.nc", # Near-surface air temperature - :eastward_velocity => "RYF.uas.1990_1991.nc", # Eastward near-surface wind - :northward_velocity => "RYF.vas.1990_1991.nc", # Northward near-surface wind -) - -jra55_short_names = Dict( +JRA55_short_names = Dict( :river_freshwater_flux => "friver", # Freshwater fluxes from rivers :rain_freshwater_flux => "prra", # Freshwater flux from rainfall :snow_freshwater_flux => "prsn", # Freshwater flux from snowfall @@ -91,6 +79,8 @@ field_time_series_short_names = Dict( :northward_velocity => "va", # Northward near-surface wind ) +urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = jra55_repeat_year_urls[metadata.name] + jra55_repeat_year_urls = Dict( :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", @@ -134,22 +124,17 @@ jra55_repeat_year_urls = Dict( variable_is_three_dimensional(data::JRA55Metadata) = false -# URLs for the JRA55 datasets specific to each version -function urls(metadata::Metadata{<:Any, <:JRA55MultipleYears}) - return "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly/" -end - urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = jra55_repeat_year_urls[metadata.name] function download_dataset!(metadata::JRA55Metadata; - url = urls(metadata)) + url = urls(metadata), + dir = download_jra55_cache) for data in metadata filename = metadata_filename(data) - shortname = short_name(data) - + if !isfile(filename) - download(url, filepath) + download(url, dir) end end From f8e7fe72970924b0098fc03ba4a9e4efee734125 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 8 Nov 2024 16:54:02 +0100 Subject: [PATCH 008/203] starting a bit --- src/DataWrangling/JRA55/jra55_metadata.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/DataWrangling/JRA55/jra55_metadata.jl b/src/DataWrangling/JRA55/jra55_metadata.jl index b309dd00a..9777703a0 100644 --- a/src/DataWrangling/JRA55/jra55_metadata.jl +++ b/src/DataWrangling/JRA55/jra55_metadata.jl @@ -15,14 +15,17 @@ Base.size(data::JRA55Metadata) = (640, 320, length(data.dates)) Base.size(::JRA55Metadata{<:AbstractCFDateTime}) = (640, 320, 1) # The whole range of dates in the different dataset versions -all_JRA55_times(::JRA55RepeatYear) = DateTimeProlepticGregorian(1990, 1, 1) : Hour(3) : DateTimeProlepticGregorian(1991, 1, 1) -all_JRA55_times(::JRA55MultipleYears) = DateTimeProlepticGregorian(1958, 1, 1) : Hour(3) : DateTimeProlepticGregorian(2018, 12, 1) +all_JRA55_times(::JRA55RepeatYear) = DateTimeProlepticGregorian(1990, 1, 1, 3) : Hour(3) : DateTimeProlepticGregorian(1991, 1, 1) +all_JRA55_times(::JRA55MultipleYears) = DateTimeProlepticGregorian(1958, 1, 1) : Hour(3) : DateTimeProlepticGregorian(2021, 1, 1) # File name generation specific to each Dataset version function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) # fix the filename - - return filename + shortname = short_name(metadata) + year = Dates.year(metadata.dates) + suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" + dates = "($year)01010130-($year)12312330.nc" + return shortname * suffix * dates * ".nc" end # File name generation specific to each Dataset version From fdef030e645744a7b2115b314805e46d82f8231d Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 5 Dec 2024 08:33:13 +0100 Subject: [PATCH 009/203] let's go --- src/DataWrangling/metadata.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index df8de0dd0..4c9f49aee 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -1,12 +1,10 @@ - - """ Metadata{D, V} Metadata holding the dataset information: - `name`: The name of the dataset. - `dates`: The dates of the dataset, in a `AbstractCFDateTime` format. -- `version`: The version of the dataset, could be ECCO2Monthly, ECCO2Daily, or ECCO4Monthly. +- `version`: The version of the dataset, could be ECCO2Monthly, ECCO2Daily, ECCO4Monthly, JRA55RepeatYear, or JRA55MultipleYears. - `dir`: The directory where the dataset is stored. """ struct Metadata{D, V} From f4d63a1c4e46d46e4655dc52ab2b518c09ba627f Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 5 Dec 2024 09:51:05 +0100 Subject: [PATCH 010/203] correct alias --- src/DataWrangling/ECCO/ECCO_metadata.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index 0babb1a28..3b8d1163f 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -13,7 +13,7 @@ struct ECCO2Monthly end struct ECCO2Daily end struct ECCO4Monthly end -const ECCOMetadata{D, V} = Union{Metadata{T, V<:ECCO4Monthly}, Metadata{T, V<:ECCO2Daily}, Metadata{T, V<:ECCO2Monthly}} where {T, V} +const ECCOMetadata{D, V} = Union{Metadata{D, V<:ECCO4Monthly}, Metadata{D, V<:ECCO2Daily}, Metadata{D, V<:ECCO2Monthly}} where {D, V} Base.show(io::IO, metadata::ECCOMetadata) = print(io, "ECCOMetadata:", '\n', From a130e73d7df960bce1169867ef393ff25b50a4bd Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 5 Dec 2024 09:53:36 +0100 Subject: [PATCH 011/203] correct dates --- src/DataWrangling/JRA55/jra55_metadata.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/JRA55/jra55_metadata.jl b/src/DataWrangling/JRA55/jra55_metadata.jl index 9777703a0..5dfa6dd26 100644 --- a/src/DataWrangling/JRA55/jra55_metadata.jl +++ b/src/DataWrangling/JRA55/jra55_metadata.jl @@ -15,8 +15,8 @@ Base.size(data::JRA55Metadata) = (640, 320, length(data.dates)) Base.size(::JRA55Metadata{<:AbstractCFDateTime}) = (640, 320, 1) # The whole range of dates in the different dataset versions -all_JRA55_times(::JRA55RepeatYear) = DateTimeProlepticGregorian(1990, 1, 1, 3) : Hour(3) : DateTimeProlepticGregorian(1991, 1, 1) -all_JRA55_times(::JRA55MultipleYears) = DateTimeProlepticGregorian(1958, 1, 1) : Hour(3) : DateTimeProlepticGregorian(2021, 1, 1) +all_JRA55_times(::JRA55RepeatYear) = DateTimeProlepticGregorian(1990, 1, 1) : Hour(3) : DateTimeProlepticGregorian(1991, 1, 1) +all_JRA55_times(::JRA55MultipleYears) = DateTimeProlepticGregorian(1958, 1, 1) : Hour(3) : DateTimeProlepticGregorian(2021, 1, 1) # File name generation specific to each Dataset version function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) From 08b377fc49e682159c666cbe223c9050c91f26b9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 23 Dec 2024 09:40:28 +0100 Subject: [PATCH 012/203] syntax --- src/DataWrangling/JRA55/JRA55.jl | 4 ++-- .../JRA55/JRA55_prescribed_atmosphere.jl | 22 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl index 069b58bdc..7f27ed08b 100644 --- a/src/DataWrangling/JRA55/JRA55.jl +++ b/src/DataWrangling/JRA55/JRA55.jl @@ -1,6 +1,6 @@ module JRA55 -export JRA55_field_time_series, JRA55_prescribed_atmosphere +export JRA55_field_time_series, JRA55PrescribedAtmosphere using Oceananigans using Oceananigans.Units @@ -30,6 +30,6 @@ using Downloads: download include("JRA55_metadata.jl") include("JRA55_field_time_series.jl") -include("JRA55_prescribed_atmosphere.jl") +include("JRA55PrescribedAtmosphere.jl") end # module diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index 8f5eec377..42f9730b5 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -1,24 +1,24 @@ const AA = Oceananigans.Architectures.AbstractArchitecture -JRA55_prescribed_atmosphere(time_indices=Colon(); kw...) = - JRA55_prescribed_atmosphere(CPU(), time_indices; kw...) +JRA55PrescribedAtmosphere(time_indices=Colon(); kw...) = + JRA55PrescribedAtmosphere(CPU(), time_indices; kw...) -JRA55_prescribed_atmosphere(arch::Distributed, time_indices=Colon(); kw...) = - JRA55_prescribed_atmosphere(child_architecture(arch), time_indices; kw...) +JRA55PrescribedAtmosphere(arch::Distributed, time_indices=Colon(); kw...) = + JRA55PrescribedAtmosphere(child_architecture(arch), time_indices; kw...) # TODO: allow the user to pass dates """ - JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); - backend = nothing, - time_indexing = Cyclical(), - reference_height = 10, # meters - include_rivers_and_icebergs = false, - other_kw...) + JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon(); + backend = nothing, + time_indexing = Cyclical(), + reference_height = 10, # meters + include_rivers_and_icebergs = false, + other_kw...) Return a `PrescribedAtmosphere` representing JRA55 reanalysis data. """ -function JRA55_prescribed_atmosphere(architecture::AA, time_indices=Colon(); +function JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon(); backend = nothing, time_indexing = Cyclical(), reference_height = 10, # meters From ba4bce0ade15ae4c95bf6a5e16b515d7ac1f5c9c Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 11:49:29 +0100 Subject: [PATCH 013/203] more updates --- src/DataWrangling/ECCO/ECCO_metadata.jl | 11 +++-- src/DataWrangling/ECCO/ECCO_restoring.jl | 8 ++-- src/DataWrangling/JRA55/JRA55.jl | 2 + .../JRA55/JRA55_prescribed_atmosphere.jl | 37 +++++++++-------- .../JRA55/jra55_field_time_series.jl | 40 +++++++++---------- src/DataWrangling/JRA55/jra55_metadata.jl | 24 ++++++----- src/DataWrangling/metadata.jl | 17 +++++++- 7 files changed, 79 insertions(+), 60 deletions(-) diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index c9882e694..b0c24504b 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -4,18 +4,17 @@ using ClimaOcean.DataWrangling using ClimaOcean.DataWrangling: netrc_downloader import Dates: year, month, day - -using Base: @propagate_inbounds using Downloads import Oceananigans.Fields: set!, location import Base +import ClimaOcean.DataWrangling: all_dates struct ECCO2Monthly end struct ECCO2Daily end struct ECCO4Monthly end -const ECCOMetadata{D, V} = Union{Metadata{D, V<:ECCO4Monthly}, Metadata{D, V<:ECCO2Daily}, Metadata{D, V<:ECCO2Monthly}} where {D, V} +const ECCOMetadata{D, V} = Metadata{D, V} where {D, V<:Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}} Base.show(io::IO, metadata::ECCOMetadata) = print(io, "ECCOMetadata:", '\n', @@ -77,9 +76,9 @@ Base.size(::ECCOMetadata{<:AbstractCFDateTime, <:ECCO2Monthly}) = (1440, 720, 50 Base.size(::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) = (720, 360, 50, 1) # The whole range of dates in the different dataset versions -all_ECCO_dates(::ECCO4Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) -all_ECCO_dates(::ECCO2Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) -all_ECCO_dates(::ECCO2Daily) = DateTimeProlepticGregorian(1992, 1, 4) : Day(1) : DateTimeProlepticGregorian(2023, 12, 31) +all_dates(::ECCO4Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) +all_dates(::ECCO2Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) +all_dates(::ECCO2Daily) = DateTimeProlepticGregorian(1992, 1, 4) : Day(1) : DateTimeProlepticGregorian(2023, 12, 31) # File names of metadata containing multiple dates metadata_filename(metadata) = [metadata_filename(metadatum) for metadatum in metadata] diff --git a/src/DataWrangling/ECCO/ECCO_restoring.jl b/src/DataWrangling/ECCO/ECCO_restoring.jl index f0b4ffb80..712735c63 100644 --- a/src/DataWrangling/ECCO/ECCO_restoring.jl +++ b/src/DataWrangling/ECCO/ECCO_restoring.jl @@ -166,7 +166,7 @@ function ECCOFieldTimeSeries(metadata::ECCOMetadata, grid::AbstractGrid; end ECCOFieldTimeSeries(variable_name::Symbol, version=ECCO4Monthly(); kw...) = - ECCOFieldTimeSeries(ECCOMetadata(variable_name, all_ECCO_dates(version), version); kw...) + ECCOFieldTimeSeries(ECCOMetadata(variable_name, all_dates(version), version); kw...) # Variable names for restorable data struct Temperature end @@ -239,7 +239,7 @@ end """ ECCORestoring(variable_name::Symbol, [ arch_or_grid = CPU(), ]; version = ECCO4Monthly(), - dates = all_ECCO_dates(version), + dates = all_dates(version), time_indices_in_memory = 2, time_indexing = Cyclical(), mask = 1, @@ -285,7 +285,7 @@ Keyword Arguments - `version`: The version of the ECCO dataset. Default: `ECCO4Monthly()`. -- `dates`: The dates to use for the ECCO dataset. Default: `all_ECCO_dates(version)`. +- `dates`: The dates to use for the ECCO dataset. Default: `all_dates(version)`. - `time_indices_in_memory`: The number of time indices to keep in memory. The number is chosen based on a trade-off between increased performance (more indices in memory) and reduced @@ -308,7 +308,7 @@ Keyword Arguments function ECCORestoring(variable_name::Symbol, arch_or_grid = CPU(); version = ECCO4Monthly(), - dates = all_ECCO_dates(version), + dates = all_dates(version), dir = download_ECCO_cache, kw...) diff --git a/src/DataWrangling/JRA55/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl index 33fd9905d..3b2d5bada 100644 --- a/src/DataWrangling/JRA55/JRA55.jl +++ b/src/DataWrangling/JRA55/JRA55.jl @@ -13,6 +13,8 @@ using Oceananigans.Grids: λnodes, φnodes, on_architecture using Oceananigans.Fields: interpolate! using Oceananigans.OutputReaders: Cyclical, TotallyInMemory, AbstractInMemoryBackend, FlavorOfFTS, time_indices +using ClimaOcean: @root + using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere, TwoBandDownwellingRadiation diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index 42f9730b5..e8643e295 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -12,18 +12,21 @@ JRA55PrescribedAtmosphere(arch::Distributed, time_indices=Colon(); kw...) = JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon(); backend = nothing, time_indexing = Cyclical(), + dates = all_dates(metadata), reference_height = 10, # meters include_rivers_and_icebergs = false, other_kw...) Return a `PrescribedAtmosphere` representing JRA55 reanalysis data. """ -function JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon(); - backend = nothing, - time_indexing = Cyclical(), - reference_height = 10, # meters - include_rivers_and_icebergs = false, - other_kw...) +function JRA55PrescribedAtmosphere(metadata::JRA55Metadata, arch_or_grid = CPU(); + backend = nothing, + time_indexing = Cyclical(), + reference_height = 10, # meters + include_rivers_and_icebergs = false, + other_kw...) + + time_indices = JRA55_time_indices(metadata.version, metadata.dates) if isnothing(backend) # apply a default Ni = try @@ -40,15 +43,15 @@ function JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon(); kw = (; time_indices, time_indexing, backend, architecture) kw = merge(kw, other_kw) - ua = JRA55_field_time_series(:eastward_velocity; kw...) - va = JRA55_field_time_series(:northward_velocity; kw...) - Ta = JRA55_field_time_series(:temperature; kw...) - qa = JRA55_field_time_series(:specific_humidity; kw...) - pa = JRA55_field_time_series(:sea_level_pressure; kw...) - Fra = JRA55_field_time_series(:rain_freshwater_flux; kw...) - Fsn = JRA55_field_time_series(:snow_freshwater_flux; kw...) - Ql = JRA55_field_time_series(:downwelling_longwave_radiation; kw...) - Qs = JRA55_field_time_series(:downwelling_shortwave_radiation; kw...) + ua = JRA55FieldTimeSeries(:eastward_velocity; kw...) + va = JRA55FieldTimeSeries(:northward_velocity; kw...) + Ta = JRA55FieldTimeSeries(:temperature; kw...) + qa = JRA55FieldTimeSeries(:specific_humidity; kw...) + pa = JRA55FieldTimeSeries(:sea_level_pressure; kw...) + Fra = JRA55FieldTimeSeries(:rain_freshwater_flux; kw...) + Fsn = JRA55FieldTimeSeries(:snow_freshwater_flux; kw...) + Ql = JRA55FieldTimeSeries(:downwelling_longwave_radiation; kw...) + Qs = JRA55FieldTimeSeries(:downwelling_shortwave_radiation; kw...) freshwater_flux = (rain = Fra, snow = Fsn) @@ -57,8 +60,8 @@ function JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon(); # a different frequency than the rest of the JRA55 data. We use `PrescribedAtmospheres` # "auxiliary_freshwater_flux" feature to represent them. if include_rivers_and_icebergs - Fri = JRA55_field_time_series(:river_freshwater_flux; kw...) - Fic = JRA55_field_time_series(:iceberg_freshwater_flux; kw...) + Fri = JRA55FieldTimeSeries(:river_freshwater_flux; kw...) + Fic = JRA55FieldTimeSeries(:iceberg_freshwater_flux; kw...) auxiliary_freshwater_flux = (rivers = Fri, icebergs = Fic) else auxiliary_freshwater_flux = nothing diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl index 1043ab2f2..1fa1d0edd 100644 --- a/src/DataWrangling/JRA55/jra55_field_time_series.jl +++ b/src/DataWrangling/JRA55/jra55_field_time_series.jl @@ -1,3 +1,4 @@ +using ClimaOcean.DataWrangling: all_dates, native_times download_JRA55_cache::String = "" @@ -71,19 +72,6 @@ function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) return i₁, i₂, j₁, j₂, TX end -# Convert dates to range until Oceananigans supports dates natively -function JRA55_times(native_times, start_time=native_times[1]) - - times = [] - for native_time in native_times - time = native_time - start_time - time = Second(time).value - push!(times, time) - end - - return times -end - struct JRA55NetCDFBackend <: AbstractInMemoryBackend{Int} start :: Int length :: Int @@ -221,13 +209,21 @@ Keyword arguments - `time_chunks_in_memory`: number of fields held in memory. If `nothing` then the whole timeseries is loaded (not recommended). """ -function JRA55FieldTimeSeries(variable_name, architecture=CPU(); +function JRA55FieldTimeSeries(variable_name::Symbol, + arch_or_grid = CPU(); version = JRA55RepeatYear(), - dates = all_JRA55_dates(version), + dates = all_dates(version), + dir = download_JRA55_cache, + kw...) + + metadata = Metadata(variable_name, dates, version, dir) + + return JRA55FieldTimeSeries(metadata, arch_or_grid; kw...) +end + +function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(); grid = nothing, location = nothing, - url = nothing, - dir = download_JRA55_cache, filename = nothing, shortname = nothing, latitude = nothing, @@ -237,7 +233,7 @@ function JRA55FieldTimeSeries(variable_name, architecture=CPU(); preprocess_chunk_size = 10, preprocess_architecture = CPU()) - time_indices = JRA55_time_indices(dates) + time_indices = JRA55_time_indices(metadata.version, metadata.dates) # OnDisk backends do not support time interpolation! # Disallow OnDisk for JRA55 dataset loading @@ -346,7 +342,7 @@ function JRA55FieldTimeSeries(variable_name, architecture=CPU(); # Probably with arguments that take latitude, longitude bounds. i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) - native_times = ds["time"][time_indices] + native_JRA55_times = ds["time"][time_indices] data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] φr = φn[j₁:j₂+1] @@ -364,7 +360,7 @@ function JRA55FieldTimeSeries(variable_name, architecture=CPU(); topology = (TX, Bounded, Flat)) boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) - times = JRA55_times(native_times) + times = native_times(native_JRA55_times) if backend isa JRA55NetCDFBackend fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; @@ -413,7 +409,7 @@ function JRA55FieldTimeSeries(variable_name, architecture=CPU(); all_datetimes = ds["time"][time_indices] all_Nt = length(all_datetimes) - all_times = JRA55_times(all_datetimes) + all_times = native_times(all_datetimes) on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; boundary_conditions, @@ -461,7 +457,7 @@ function JRA55FieldTimeSeries(variable_name, architecture=CPU(); end # Re-compute times - new_times = JRA55_times(all_times[time_indices_in_memory], all_times[n₁]) + new_times = native_times(all_times[time_indices_in_memory], all_times[n₁]) native_fts.times = new_times # Re-compute data diff --git a/src/DataWrangling/JRA55/jra55_metadata.jl b/src/DataWrangling/JRA55/jra55_metadata.jl index 5dfa6dd26..513b1ac79 100644 --- a/src/DataWrangling/JRA55/jra55_metadata.jl +++ b/src/DataWrangling/JRA55/jra55_metadata.jl @@ -5,18 +5,24 @@ import Oceananigans.Fields: set! import Base using ClimaOcean.DataWrangling: Metadata +import ClimaOcean.DataWrangling: all_dates struct JRA55MultipleYears end struct JRA55RepeatYear end -const JRA55Metadata{T, V} = Union{Metadata{T, V<:JRA55MultipleYears}, Metadata{T, V<:JRA55RepeatYear}} where {T, V} +const JRA55Metadata{T, V} = Metadata{T, V} where {T, V<:Union{<:JRA55MultipleYears, <:JRA55RepeatYear}} Base.size(data::JRA55Metadata) = (640, 320, length(data.dates)) Base.size(::JRA55Metadata{<:AbstractCFDateTime}) = (640, 320, 1) # The whole range of dates in the different dataset versions -all_JRA55_times(::JRA55RepeatYear) = DateTimeProlepticGregorian(1990, 1, 1) : Hour(3) : DateTimeProlepticGregorian(1991, 1, 1) -all_JRA55_times(::JRA55MultipleYears) = DateTimeProlepticGregorian(1958, 1, 1) : Hour(3) : DateTimeProlepticGregorian(2021, 1, 1) +all_dates(::JRA55RepeatYear) = DateTimeProlepticGregorian(1990, 1, 1) : Hour(3) : DateTimeProlepticGregorian(1991, 1, 1) +all_dates(::JRA55MultipleYears) = DateTimeProlepticGregorian(1958, 1, 1) : Hour(3) : DateTimeProlepticGregorian(2021, 1, 1) + +function JRA55_time_indices(version, dates) + all_JRA55_dates = all_dates(version) + return findall(all_JRA55_dates .== dates) +end # File name generation specific to each Dataset version function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) @@ -35,7 +41,7 @@ function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55Repea end # Convenience functions -short_name(data::JRA55Metadata) = jra55_short_names[data.name] +short_name(data::JRA55Metadata) = JRA55_short_names[data.name] location(data::JRA55Metadata) = (Center, Center, Center) # A list of all variables provided in the JRA55 dataset: @@ -82,9 +88,7 @@ field_time_series_short_names = Dict( :northward_velocity => "va", # Northward near-surface wind ) -urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = jra55_repeat_year_urls[metadata.name] - -jra55_repeat_year_urls = Dict( +JRA55_repeat_year_urls = Dict( :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", @@ -127,11 +131,13 @@ jra55_repeat_year_urls = Dict( variable_is_three_dimensional(data::JRA55Metadata) = false -urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = jra55_repeat_year_urls[metadata.name] +urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] +# TODO: +# urls(metadata::Metadata{<:Any, <:JRA55MultipleYears}) = ... function download_dataset!(metadata::JRA55Metadata; url = urls(metadata), - dir = download_jra55_cache) + dir = download_JRA55_cache) for data in metadata filename = metadata_filename(data) diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 4c9f49aee..8fc93dc52 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -1,3 +1,7 @@ +using CFTime +using Dates +using Base: @propagate_inbounds + """ Metadata{D, V} @@ -24,13 +28,14 @@ Base.show(io::IO, metadata::Metadata) = # Treat Metadata as an array to allow iteration over the dates. Base.length(metadata::Metadata) = length(metadata.dates) Base.eltype(metadata::Metadata) = Base.eltype(metadata.dates) + @propagate_inbounds Base.getindex(m::Metadata, i::Int) = Metadata(m.name, m.dates[i], m.version, m.dir) @propagate_inbounds Base.first(m::Metadata) = Metadata(m.name, m.dates[1], m.version, m.dir) @propagate_inbounds Base.last(m::Metadata) = Metadata(m.name, m.dates[end], m.version, m.dir) @inline function Base.iterate(m::Metadata, i=1) if (i % UInt) - 1 < length(m) - return ECCOMetadata(m.name, m.dates[i], m.version, m.dir), i + 1 + return Metadata(m.name, m.dates[i], m.version, m.dir), i + 1 else return nothing end @@ -65,4 +70,12 @@ function native_times(metadata; start_time = first(metadata).dates) end return times -end \ No newline at end of file +end + +""" + all_dates(metadata) + +Extracts all the dates of the given metadata formatted using the `DateTimeProlepticGregorian` type. +Needs to be extended by any new dataset version. +""" +all_dates(metadata) = all_dates(metadata.version) From 68dfdb09970a2607d16461b704eb5a275ab7c5f5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 12:57:31 +0100 Subject: [PATCH 014/203] all this should work? --- src/DataWrangling/DataWrangling.jl | 2 + src/DataWrangling/ECCO/ECCO_metadata.jl | 8 +-- src/DataWrangling/ECCO/ECCO_restoring.jl | 31 +-------- .../JRA55/jra55_field_time_series.jl | 67 +++++++------------ src/DataWrangling/JRA55/jra55_metadata.jl | 60 +++++++++++------ src/DataWrangling/metadata.jl | 18 +++-- test/test_ecco.jl | 8 +-- 7 files changed, 85 insertions(+), 109 deletions(-) diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index b45f3d75d..b1f2e064f 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -1,5 +1,7 @@ module DataWrangling +export Metadata + using Oceananigans using Downloads using Printf diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index b0c24504b..11e73fe01 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -1,14 +1,14 @@ using CFTime using Dates using ClimaOcean.DataWrangling -using ClimaOcean.DataWrangling: netrc_downloader +using ClimaOcean.DataWrangling: netrc_downloader, metadata_path import Dates: year, month, day using Downloads import Oceananigans.Fields: set!, location import Base -import ClimaOcean.DataWrangling: all_dates +import ClimaOcean.DataWrangling: all_dates, metadata_filename struct ECCO2Monthly end struct ECCO2Daily end @@ -80,9 +80,6 @@ all_dates(::ECCO4Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : all_dates(::ECCO2Monthly) = DateTimeProlepticGregorian(1992, 1, 1) : Month(1) : DateTimeProlepticGregorian(2023, 12, 1) all_dates(::ECCO2Daily) = DateTimeProlepticGregorian(1992, 1, 4) : Day(1) : DateTimeProlepticGregorian(2023, 12, 31) -# File names of metadata containing multiple dates -metadata_filename(metadata) = [metadata_filename(metadatum) for metadatum in metadata] - # File name generation specific to each Dataset version function metadata_filename(metadata::ECCOMetadata{<:AbstractCFDateTime, <:ECCO4Monthly}) shortname = short_name(metadata) @@ -106,7 +103,6 @@ function metadata_filename(metadata::ECCOMetadata{<:AbstractCFDateTime}) end # Convenience functions -metadata_path(metadata) = joinpath(metadata.dir, metadata_filename(metadata)) short_name(data::ECCOMetadata{<:Any, <:ECCO2Daily}) = ECCO2_short_names[data.name] short_name(data::ECCOMetadata{<:Any, <:ECCO2Monthly}) = ECCO2_short_names[data.name] short_name(data::ECCOMetadata{<:Any, <:ECCO4Monthly}) = ECCO4_short_names[data.name] diff --git a/src/DataWrangling/ECCO/ECCO_restoring.jl b/src/DataWrangling/ECCO/ECCO_restoring.jl index 712735c63..337d0cbcd 100644 --- a/src/DataWrangling/ECCO/ECCO_restoring.jl +++ b/src/DataWrangling/ECCO/ECCO_restoring.jl @@ -10,7 +10,7 @@ using JLD2 using Dates: Second using ClimaOcean: stateindex -using ClimaOcean.DataWrangling: NearestNeighborInpainting +using ClimaOcean.DataWrangling: NearestNeighborInpainting, native_times import Oceananigans.Fields: set! import Oceananigans.Forcings: regularize_forcing @@ -78,33 +78,6 @@ function set!(fts::ECCOFieldTimeSeries) return nothing end -""" - ECCO_times(metadata; start_time = first(metadata).dates) - -Extract the time values from the given metadata and calculates the time difference -from the start time. - -Arguments -========= -- `metadata`: The metadata containing the date information. -- `start_time`: The start time for calculating the time difference. Defaults to the first date in the metadata. - -Returns -======= -An array of time differences in seconds. -""" -function ECCO_times(metadata; start_time = first(metadata).dates) - times = zeros(length(metadata)) - for (t, data) in enumerate(metadata) - date = data.dates - time = date - start_time - time = Second(time).value - times[t] = time - end - - return times -end - """ ECCOFieldTimeSeries(metadata::ECCOMetadata [, arch_or_grid=CPU() ]; time_indices_in_memory = 2, @@ -156,7 +129,7 @@ function ECCOFieldTimeSeries(metadata::ECCOMetadata, grid::AbstractGrid; inpainting isa Int && (inpainting = NearestNeighborInpainting(inpainting)) backend = ECCONetCDFBackend(time_indices_in_memory, metadata; on_native_grid, inpainting, cache_inpainted_data) - times = ECCO_times(metadata) + times = native_times(metadata) loc = LX, LY, LZ = location(metadata) boundary_conditions = FieldBoundaryConditions(grid, loc) fts = FieldTimeSeries{LX, LY, LZ}(grid, times; backend, time_indexing, boundary_conditions) diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl index 1fa1d0edd..c604e213f 100644 --- a/src/DataWrangling/JRA55/jra55_field_time_series.jl +++ b/src/DataWrangling/JRA55/jra55_field_time_series.jl @@ -1,4 +1,5 @@ using ClimaOcean.DataWrangling: all_dates, native_times +using Oceananigans.Grids: AbstractGrid download_JRA55_cache::String = "" @@ -89,6 +90,7 @@ Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backen const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} +# TODO: This will need to change when we add a method for JRA55MultipleYears function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) ds = Dataset(path) @@ -194,15 +196,6 @@ Keyword arguments Used to slice the data when loading into memory. Default: nothing, which retains the longitude range of the native grid. -- `url`: The url accessed to download the data for `variable_name`. - Default: `ClimaOcean.JRA55.urls[variable_name]`. - -- `filename`: The name of the downloaded file. - Default: `ClimaOcean.JRA55.filenames[variable_name]`. - -- `shortname`: The "short name" of `variable_name` inside its NetCDF file. - Default: `ClimaOcean.JRA55.JRA55_short_names[variable_name]`. - - `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. If it does not exist it will be generated. @@ -221,11 +214,7 @@ function JRA55FieldTimeSeries(variable_name::Symbol, return JRA55FieldTimeSeries(metadata, arch_or_grid; kw...) end -function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(); - grid = nothing, - location = nothing, - filename = nothing, - shortname = nothing, +function JRA55FieldTimeSeries(metadata::JRA55Metadata, arch_or_grid = CPU(); latitude = nothing, longitude = nothing, backend = InMemory(), @@ -233,7 +222,25 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(); preprocess_chunk_size = 10, preprocess_architecture = CPU()) + # First thing: we download the dataset! + download_dataset!(metadata) + + # Unpack metadata details time_indices = JRA55_time_indices(metadata.version, metadata.dates) + shortname = short_name(metadata) + dir = metadata.dir + variable_name = metadata.name + + filepath = metadata_path(metadata) # Might be multiple paths!!! + filepath = filepath isa AbstractArray ? first(filepath) : filepath + + if arch_or_grid isa AbstractGrid + grid = arch_or_grid + architecture = Oceananigans.Grids.architecture(grid) + else + grid = nothing + architecture = arch_or_grid + end # OnDisk backends do not support time interpolation! # Disallow OnDisk for JRA55 dataset loading @@ -242,7 +249,7 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(); throw(ArgumentError(msg)) end - if isnothing(filename) && !(variable_name ∈ JRA55_variable_names) + if !(variable_name ∈ JRA55_variable_names) variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) variables_msg = prod(variable_strs) @@ -253,18 +260,6 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(); throw(ArgumentError(msg)) end - filepath = isnothing(filename) ? joinpath(dir, filenames[variable_name]) : joinpath(dir, filename) - - if !isnothing(filename) && !isfile(filepath) && isnothing(url) - throw(ArgumentError("A filename was provided without a url, but the file does not exist.\n \ - If intended, please provide both the filename and url that should be used \n \ - to download the new file.")) - end - - isnothing(filename) && (filename = filenames[variable_name]) - isnothing(shortname) && (shortname = JRA55_short_names[variable_name]) - isnothing(url) && (url = urls[variable_name]) - # Record some important user decisions totally_in_memory = backend isa TotallyInMemory on_native_grid = isnothing(grid) @@ -273,12 +268,6 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(); jld2_filepath = joinpath(dir, string("JRA55_repeat_year_", variable_name, ".jld2")) fts_name = field_time_series_short_names[variable_name] - # Note, we don't re-use existing jld2 files. - @root begin - isfile(filepath) || download(url, filepath; progress=download_progress) - isfile(jld2_filepath) && rm(jld2_filepath) - end - # Determine default time indices if totally_in_memory # In this case, the whole time series is in memory. @@ -308,13 +297,6 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(); end end - # Set a default location. - if isnothing(location) - LX = LY = Center - else - LX, LY = location - end - ds = Dataset(filepath) # Note that each file should have the variables @@ -340,9 +322,8 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(); # TODO: support loading just part of the JRA55 data. # Probably with arguments that take latitude, longitude bounds. - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, Center, Center, λc, φc) - native_JRA55_times = ds["time"][time_indices] data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] φr = φn[j₁:j₂+1] @@ -360,7 +341,7 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(); topology = (TX, Bounded, Flat)) boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) - times = native_times(native_JRA55_times) + times = native_times(metadata) if backend isa JRA55NetCDFBackend fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; diff --git a/src/DataWrangling/JRA55/jra55_metadata.jl b/src/DataWrangling/JRA55/jra55_metadata.jl index 513b1ac79..977afb50c 100644 --- a/src/DataWrangling/JRA55/jra55_metadata.jl +++ b/src/DataWrangling/JRA55/jra55_metadata.jl @@ -1,11 +1,17 @@ using CFTime using Dates +using Downloads + +using ClimaOcean.DataWrangling +using ClimaOcean.DataWrangling: Metadata, metadata_path, download_progress + import Dates: year, month, day import Oceananigans.Fields: set! import Base +import ClimaOcean.DataWrangling: all_dates, metadata_filename -using ClimaOcean.DataWrangling: Metadata -import ClimaOcean.DataWrangling: all_dates +import Oceananigans.Fields: set!, location +import ClimaOcean.DataWrangling: all_dates, metadata_filename struct JRA55MultipleYears end struct JRA55RepeatYear end @@ -21,25 +27,32 @@ all_dates(::JRA55MultipleYears) = DateTimeProlepticGregorian(1958, 1, 1) : Hour( function JRA55_time_indices(version, dates) all_JRA55_dates = all_dates(version) - return findall(all_JRA55_dates .== dates) -end + indices = Int[] + + for date in dates + index = findfirst(x -> x == date, all_JRA55_dates) + push!(indices, index) + end -# File name generation specific to each Dataset version -function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) - # fix the filename - shortname = short_name(metadata) - year = Dates.year(metadata.dates) - suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" - dates = "($year)01010130-($year)12312330.nc" - return shortname * suffix * dates * ".nc" + return indices end # File name generation specific to each Dataset version -function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55RepeatYear}) +function metadata_filename(metadata::Metadata{<:Any, <:JRA55RepeatYear}) # No difference shortname = short_name(metadata) return "RYF." * shortname * ".1990_1991.nc" end +# TODO: Implement this function for JRA55MultipleYears +# function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) +# # fix the filename +# shortname = short_name(metadata) +# year = Dates.year(metadata.dates) +# suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" +# dates = "($year)01010130-($year)12312330.nc" +# return shortname * suffix * dates * ".nc" +# end + # Convenience functions short_name(data::JRA55Metadata) = JRA55_short_names[data.name] location(data::JRA55Metadata) = (Center, Center, Center) @@ -131,19 +144,22 @@ JRA55_repeat_year_urls = Dict( variable_is_three_dimensional(data::JRA55Metadata) = false -urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] +urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] # TODO: # urls(metadata::Metadata{<:Any, <:JRA55MultipleYears}) = ... -function download_dataset!(metadata::JRA55Metadata; - url = urls(metadata), - dir = download_JRA55_cache) +metadata_url(prefix, m::Metadata{<:Any, <:JRA55RepeatYear}) = prefix # No specific name for this url + +# TODO: This will need to change when we add a method for JRA55MultipleYears +function download_dataset!(metadata::JRA55Metadata; url = urls(metadata)) + + asyncmap(metadata, ntasks=10) do metadatum # Distribute the download among tasks + + fileurl = metadata_url(url, metadatum) + filepath = metadata_path(metadatum) - for data in metadata - filename = metadata_filename(data) - - if !isfile(filename) - download(url, dir) + if !isfile(filepath) + Downloads.download(fileurl, filepath; progress=download_progress) end end diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 8fc93dc52..794234639 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -47,20 +47,25 @@ Base.last(metadata::Metadata{<:AbstractCFDateTime}) = metadata Base.iterate(metadata::Metadata{<:AbstractCFDateTime}) = (metadata, nothing) Base.iterate(::Metadata{<:AbstractCFDateTime}, ::Any) = nothing +metadata_path(metadata) = joinpath(metadata.dir, metadata_filename(metadata)) + + """ - native_times(metadata; start_time = metadata.dates[1]) + native_times(metadata; start_time = first(metadata).dates) -Extracts the time values from the given metadata and calculates the time difference +Extract the time values from the given metadata and calculates the time difference from the start time. -# Arguments +Arguments +========= - `metadata`: The metadata containing the date information. - `start_time`: The start time for calculating the time difference. Defaults to the first date in the metadata. -# Returns +Returns +======= An array of time differences in seconds. """ -function native_times(metadata; start_time = first(metadata).dates) +function native_times(metadata; start_time=first(metadata).dates) times = zeros(length(metadata)) for (t, data) in enumerate(metadata) date = data.dates @@ -79,3 +84,6 @@ Extracts all the dates of the given metadata formatted using the `DateTimeProlep Needs to be extended by any new dataset version. """ all_dates(metadata) = all_dates(metadata.version) + +# File names of metadata containing multiple dates +metadata_filename(metadata) = [metadata_filename(metadatum) for metadatum in metadata] diff --git a/test/test_ecco.jl b/test/test_ecco.jl index 04a125d36..3910ae0ea 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -5,7 +5,7 @@ using Dates using ClimaOcean using ClimaOcean.ECCO -using ClimaOcean.ECCO: ECCO_field, metadata_path, ECCO_times +using ClimaOcean.ECCO: ECCO_field, metadata_path, native_times using ClimaOcean.DataWrangling: NearestNeighborInpainting using Oceananigans.Grids: topology @@ -47,8 +47,8 @@ inpainting = NearestNeighborInpainting(2) @test Nz == size(metadata)[3] @test Nt == size(metadata)[4] - @test fts.times[1] == ECCO_times(metadata)[1] - @test fts.times[end] == ECCO_times(metadata)[end] + @test fts.times[1] == native_times(metadata)[1] + @test fts.times[end] == native_times(metadata)[end] datum = first(metadata) ψ = ECCO_field(datum, architecture=arch, inpainting=NearestNeighborInpainting(2)) @@ -207,7 +207,7 @@ end rate = 1 / 1000.0, inpainting) - times = ECCO_times(t_restoring.field_time_series.backend.metadata) + times = native_times(t_restoring.field_time_series.backend.metadata) ocean = ocean_simulation(grid, forcing = (; T = t_restoring)) ocean.model.clock.time = times[3] + 2 * Units.days From f212e885d2f434bf904b5be128ae5e0bf65030a7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 12:59:04 +0100 Subject: [PATCH 015/203] clear comments --- src/DataWrangling/JRA55/jra55_field_time_series.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl index c604e213f..f1a0129a8 100644 --- a/src/DataWrangling/JRA55/jra55_field_time_series.jl +++ b/src/DataWrangling/JRA55/jra55_field_time_series.jl @@ -144,13 +144,9 @@ new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, len dates = all_JRA55_dates(version), latitude = nothing, longitude = nothing, - location = nothing, - url = nothing, dir = download_JRA55_cache, filename = nothing, shortname = nothing, - latitude = nothing, - longitude = nothing, backend = InMemory(), time_indexing = Cyclical(), preprocess_chunk_size = 10, From 1a68d4e8aa4d90c4d097187d7616e1a41c48c1e4 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 12:59:51 +0100 Subject: [PATCH 016/203] vestigial code --- compact_data.jl | 71 ------------------------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 compact_data.jl diff --git a/compact_data.jl b/compact_data.jl deleted file mode 100644 index 3cdf31791..000000000 --- a/compact_data.jl +++ /dev/null @@ -1,71 +0,0 @@ -using Oceananigans -using Oceananigans.Grids: halo_size -using Oceananigans.Fields: location -using JLD2 - -const Nx = 256 -const Ny = 128 -const Nz = 1 -const nx = 256 ÷ 2 -const ny = 128 ÷ 2 - -grid = TripolarGrid(size=(Nx, Ny, Nz)) -Hx, Hy, Hz = halo_size(grid) - -function read_bathymetry(prefix) - bottom_height = zeros(Nx, Ny) - - for xrank in 0:1, yrank in 0:1 - rank = yrank + 2 * xrank - file = jldopen(prefix * "_$(rank).jld2") - irange = nx * xrank + 1 : nx * (xrank + 1) - jrange = ny * yrank + 1 : ny * (yrank + 1) - - data = file["serialized/grid"].immersed_boundary.bottom_height[Hx+1:nx+Hx, Hy+1:ny+Hy, 1] - bottom_height[irange, jrange] .= data - close(file) - end - - return bottom_height -end - -bottom_height = read_bathymetry("surface_fields") - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) - -file0 = jldopen("surface_fields_0.jld2") -iters = keys(file0["timeseries/t"]) -times = Float64[file0["timeseries/t/$(iter)"] for iter in iters] -close(file0) - -utmp = FieldTimeSeries{Face, Center, Nothing}(grid, times; backend=OnDisk(), path="surface_fields.jld2", name="u") -vtmp = FieldTimeSeries{Center, Face, Nothing}(grid, times; backend=OnDisk(), path="surface_fields.jld2", name="v") -Ttmp = FieldTimeSeries{Center, Center, Nothing}(grid, times; backend=OnDisk(), path="surface_fields.jld2", name="T") -Stmp = FieldTimeSeries{Center, Center, Nothing}(grid, times; backend=OnDisk(), path="surface_fields.jld2", name="S") -etmp = FieldTimeSeries{Center, Center, Nothing}(grid, times; backend=OnDisk(), path="surface_fields.jld2", name="e") - -function set_distributed_field_time_series!(fts, prefix) - field = Field{location(fts)...}(grid) - Ny = size(fts, 2) - for (idx, iter) in enumerate(iters) - @info "doing iter $idx of $(length(iters))" - for xrank in 0:1, yrank in 0:1 - rank = yrank + 2 * xrank - file = jldopen(prefix * "_$(rank).jld2") - irange = nx * xrank + 1 : nx * (xrank + 1) - jrange = ny * yrank + 1 : ny * (yrank + 1) - data = file["timeseries/$(fts.name)/$(iter)"][Hx+1:nx+Hx, Hy+1:ny+Hy, 1] - - interior(field, irange, jrange, 1) .= data - close(file) - end - - set!(fts, field, idx) - end -end - -set_distributed_field_time_series!(utmp, "surface_fields") -set_distributed_field_time_series!(vtmp, "surface_fields") -set_distributed_field_time_series!(Ttmp, "surface_fields") -set_distributed_field_time_series!(Stmp, "surface_fields") -set_distributed_field_time_series!(etmp, "surface_fields") \ No newline at end of file From c318e54498bbbd9bbf01de94e017c7ba11301d70 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 13:06:56 +0100 Subject: [PATCH 017/203] works --- src/DataWrangling/JRA55/jra55_field_time_series.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl index f1a0129a8..77b2ef1cb 100644 --- a/src/DataWrangling/JRA55/jra55_field_time_series.jl +++ b/src/DataWrangling/JRA55/jra55_field_time_series.jl @@ -245,7 +245,7 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, arch_or_grid = CPU(); throw(ArgumentError(msg)) end - if !(variable_name ∈ JRA55_variable_names) + if !(variable_name ∈ JRA55_variable_names) variable_strs = Tuple(" - :$name \n" for name in JRA55_variable_names) variables_msg = prod(variable_strs) From 79b593534370d11124b97690198e8042e7329b24 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 13:21:31 +0100 Subject: [PATCH 018/203] veeery much simplified --- .../JRA55/jra55_field_time_series.jl | 171 +++--------------- 1 file changed, 22 insertions(+), 149 deletions(-) diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl index 77b2ef1cb..006df82f4 100644 --- a/src/DataWrangling/JRA55/jra55_field_time_series.jl +++ b/src/DataWrangling/JRA55/jra55_field_time_series.jl @@ -176,13 +176,15 @@ The `variable_name`s (and their `shortname`s used in NetCDF files) available fro Keyword arguments ================= -- `architecture`: Architecture for the `FieldTimeSeries`. - Default: CPU() +- `architecture`: Architecture for the `FieldTimeSeries`. Default: CPU() -- `time_indices`: Indices of the timeseries to extract from file. - For example, `time_indices=1:3` returns a - `FieldTimeSeries` with the first three time snapshots - of `variable_name`. +- `dates`: The date(s) of the metadata. Note this can either be a single date, + representing a snapshot, or a range of dates, representing a time-series. + Default: `all_dates(version)` (see `all_dates`). + +- `version`: The data version. The only supported versions is `JRA55RepeatYear()` + +- `dir`: The directory of the data file. Default: `ClimaOcean.JRA55.download_JRA55_cache`. - `latitude`: Guiding latitude bounds for the resulting grid. Used to slice the data when loading into memory. @@ -192,14 +194,13 @@ Keyword arguments Used to slice the data when loading into memory. Default: nothing, which retains the longitude range of the native grid. -- `interpolated_file`: file holding an Oceananigans compatible version of the JRA55 data. - If it does not exist it will be generated. - -- `time_chunks_in_memory`: number of fields held in memory. If `nothing` then the whole timeseries - is loaded (not recommended). +- `backend`: Backend for the `FieldTimeSeries`. The two options are + * `InMemory()`: the whole time series is loaded into memory. + * `JRA55NetCDFBackend(total_time_instances_in_memory)`: only a subset of the time series is loaded into memory. + Default: `InMemory()`. """ function JRA55FieldTimeSeries(variable_name::Symbol, - arch_or_grid = CPU(); + architecture = CPU(); version = JRA55RepeatYear(), dates = all_dates(version), dir = download_JRA55_cache, @@ -207,16 +208,14 @@ function JRA55FieldTimeSeries(variable_name::Symbol, metadata = Metadata(variable_name, dates, version, dir) - return JRA55FieldTimeSeries(metadata, arch_or_grid; kw...) + return JRA55FieldTimeSeries(metadata, architecture; kw...) end -function JRA55FieldTimeSeries(metadata::JRA55Metadata, arch_or_grid = CPU(); +function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture = CPU(); latitude = nothing, longitude = nothing, backend = InMemory(), - time_indexing = Cyclical(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU()) + time_indexing = Cyclical()) # First thing: we download the dataset! download_dataset!(metadata) @@ -224,24 +223,15 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, arch_or_grid = CPU(); # Unpack metadata details time_indices = JRA55_time_indices(metadata.version, metadata.dates) shortname = short_name(metadata) - dir = metadata.dir variable_name = metadata.name filepath = metadata_path(metadata) # Might be multiple paths!!! filepath = filepath isa AbstractArray ? first(filepath) : filepath - if arch_or_grid isa AbstractGrid - grid = arch_or_grid - architecture = Oceananigans.Grids.architecture(grid) - else - grid = nothing - architecture = arch_or_grid - end - # OnDisk backends do not support time interpolation! # Disallow OnDisk for JRA55 dataset loading - if backend isa OnDisk - msg = string("We cannot load the JRA55 dataset with an `OnDisk` backend") + if !(backend isa JRA55NetCDFBackend) && !(backend isa TotallyInMemory) + msg = string("We cannot load the JRA55 dataset with an `OnDisk` or a `PartiallyInMemory` backend") throw(ArgumentError(msg)) end @@ -258,11 +248,6 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, arch_or_grid = CPU(); # Record some important user decisions totally_in_memory = backend isa TotallyInMemory - on_native_grid = isnothing(grid) - !on_native_grid && backend isa JRA55NetCDFBackend && error("Can't use custom grid with JRA55NetCDFBackend.") - - jld2_filepath = joinpath(dir, string("JRA55_repeat_year_", variable_name, ".jld2")) - fts_name = field_time_series_short_names[variable_name] # Determine default time indices if totally_in_memory @@ -270,7 +255,6 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, arch_or_grid = CPU(); # Either the time series is short, or we are doing a limited-area # simulation, like in a single column. So, we conservatively # set a default `time_indices = 1:2`. - isnothing(time_indices) && (time_indices = 1:2) time_indices_in_memory = time_indices native_fts_architecture = architecture else @@ -281,16 +265,8 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, arch_or_grid = CPU(); # by default we choose all of them. The architecture is only the # architecture used for preprocessing, which typically will be CPU() # even if we would like the final FieldTimeSeries on the GPU. - isnothing(time_indices) && (time_indices = :) - - if backend isa JRA55NetCDFBackend - time_indices_in_memory = 1:length(backend) - native_fts_architecture = architecture - else # then `time_indices_in_memory` refers to preprocessing - maximum_index = min(preprocess_chunk_size, length(time_indices)) - time_indices_in_memory = 1:maximum_index - native_fts_architecture = preprocess_architecture - end + time_indices_in_memory = 1:length(backend) + native_fts_architecture = architecture end ds = Dataset(filepath) @@ -353,118 +329,15 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, arch_or_grid = CPU(); return fts else - # Make times into an array for later preprocessing - if !totally_in_memory - times = collect(times) - end - native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; time_indexing, + backend, boundary_conditions) # Fill the data in a GPU-friendly manner copyto!(interior(native_fts, :, :, 1, :), data) fill_halo_regions!(native_fts) - if on_native_grid && totally_in_memory - return native_fts - - elseif totally_in_memory # but not on the native grid! - boundary_conditions = FieldBoundaryConditions(grid, (LX, LY, Nothing)) - fts = FieldTimeSeries{LX, LY, Nothing}(grid, times; time_indexing, boundary_conditions) - interpolate!(fts, native_fts) - return fts - end - end - - @info "Pre-processing JRA55 $variable_name data into a JLD2 file..." - - preprocessing_grid = on_native_grid ? JRA55_native_grid : grid - - # Re-open the dataset! - ds = Dataset(filepath) - all_datetimes = ds["time"][time_indices] - all_Nt = length(all_datetimes) - - all_times = native_times(all_datetimes) - - on_disk_fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, all_times; - boundary_conditions, - backend = OnDisk(), - path = jld2_filepath, - name = fts_name) - - # Save data to disk, one field at a time - start_clock = time_ns() - n = 1 # on disk - m = 0 # in memory - - times_in_memory = all_times[time_indices_in_memory] - - fts = FieldTimeSeries{LX, LY, Nothing}(preprocessing_grid, times_in_memory; - boundary_conditions, - backend = InMemory(), - path = jld2_filepath, - name = fts_name) - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) + return native_fts end - - while n <= all_Nt - print(" ... processing time index $n of $all_Nt \r") - - if time_indices_in_memory isa Colon || n ∈ time_indices_in_memory - m += 1 - else # load new data - # Update time_indices - time_indices_in_memory = time_indices_in_memory .+ preprocess_chunk_size - n₁ = first(time_indices_in_memory) - - # Clip time_indices if they extend past the end of the dataset - if last(time_indices_in_memory) > all_Nt - time_indices_in_memory = UnitRange(n₁, all_Nt) - end - - # Re-compute times - new_times = native_times(all_times[time_indices_in_memory], all_times[n₁]) - native_fts.times = new_times - - # Re-compute data - new_data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] - fts.times = new_times - - if !on_native_grid - copyto!(interior(native_fts, :, :, 1, :), new_data[:, :, :]) - fill_halo_regions!(native_fts) - interpolate!(fts, native_fts) - else - copyto!(interior(fts, :, :, 1, :), new_data[:, :, :]) - end - - m = 1 # reset - end - - set!(on_disk_fts, fts[m], n, fts.times[m]) - - n += 1 - end - - elapsed = 1e-9 * (time_ns() - start_clock) - elapsed_str = prettytime(elapsed) - @info " ... done ($elapsed_str)" * repeat(" ", 20) - - close(ds) - - user_fts = FieldTimeSeries(jld2_filepath, fts_name; architecture, backend, time_indexing) - fill_halo_regions!(user_fts) - - return user_fts end From 91e1169e7b324f46ffce2c01361c13fc3e60a94c Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 13:21:53 +0100 Subject: [PATCH 019/203] this part is already done --- src/DataWrangling/JRA55/jra55_field_time_series.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl index 006df82f4..bb24bce65 100644 --- a/src/DataWrangling/JRA55/jra55_field_time_series.jl +++ b/src/DataWrangling/JRA55/jra55_field_time_series.jl @@ -292,8 +292,6 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture = CPU(); push!(φn, 90) push!(λn, λn[1] + 360) - # TODO: support loading just part of the JRA55 data. - # Probably with arguments that take latitude, longitude bounds. i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, Center, Center, λc, φc) data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] From b6fb198fa90803d2c8a3775a777f8ab0f5c18d43 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 14:20:10 +0100 Subject: [PATCH 020/203] back to working --- .../JRA55/JRA55_prescribed_atmosphere.jl | 60 +++++++------------ .../JRA55/jra55_field_time_series.jl | 2 +- .../PrescribedAtmospheres.jl | 18 +++--- 3 files changed, 31 insertions(+), 49 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index e8643e295..0c16ce5bd 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -1,57 +1,42 @@ - const AA = Oceananigans.Architectures.AbstractArchitecture -JRA55PrescribedAtmosphere(time_indices=Colon(); kw...) = - JRA55PrescribedAtmosphere(CPU(), time_indices; kw...) - -JRA55PrescribedAtmosphere(arch::Distributed, time_indices=Colon(); kw...) = - JRA55PrescribedAtmosphere(child_architecture(arch), time_indices; kw...) +JRA55PrescribedAtmosphere(arch::Distributed; kw...) = + JRA55PrescribedAtmosphere(child_architecture(arch); kw...) # TODO: allow the user to pass dates """ - JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon(); + JRA55PrescribedAtmosphere(architecture::AA; + version = JRA55RepeatYear(), + dates = all_dates(version), backend = nothing, time_indexing = Cyclical(), - dates = all_dates(metadata), reference_height = 10, # meters include_rivers_and_icebergs = false, other_kw...) Return a `PrescribedAtmosphere` representing JRA55 reanalysis data. """ -function JRA55PrescribedAtmosphere(metadata::JRA55Metadata, arch_or_grid = CPU(); - backend = nothing, +function JRA55PrescribedAtmosphere(architecture; + version = JRA55RepeatYear(), + dates = all_dates(version), + backend = JRA55NetCDFBackend(10), time_indexing = Cyclical(), reference_height = 10, # meters include_rivers_and_icebergs = false, other_kw...) - time_indices = JRA55_time_indices(metadata.version, metadata.dates) - - if isnothing(backend) # apply a default - Ni = try - length(time_indices) - catch - Inf - end - - # Manufacture a default for the number of fields to keep InMemory - Nf = min(24, Ni) - backend = JRA55NetCDFBackend(Nf) - end - - kw = (; time_indices, time_indexing, backend, architecture) + kw = (; time_indexing, backend, dates, version) kw = merge(kw, other_kw) - ua = JRA55FieldTimeSeries(:eastward_velocity; kw...) - va = JRA55FieldTimeSeries(:northward_velocity; kw...) - Ta = JRA55FieldTimeSeries(:temperature; kw...) - qa = JRA55FieldTimeSeries(:specific_humidity; kw...) - pa = JRA55FieldTimeSeries(:sea_level_pressure; kw...) - Fra = JRA55FieldTimeSeries(:rain_freshwater_flux; kw...) - Fsn = JRA55FieldTimeSeries(:snow_freshwater_flux; kw...) - Ql = JRA55FieldTimeSeries(:downwelling_longwave_radiation; kw...) - Qs = JRA55FieldTimeSeries(:downwelling_shortwave_radiation; kw...) + ua = JRA55FieldTimeSeries(:eastward_velocity, architecture; kw...) + va = JRA55FieldTimeSeries(:northward_velocity, architecture; kw...) + Ta = JRA55FieldTimeSeries(:temperature, architecture; kw...) + qa = JRA55FieldTimeSeries(:specific_humidity, architecture; kw...) + pa = JRA55FieldTimeSeries(:sea_level_pressure, architecture; kw...) + Fra = JRA55FieldTimeSeries(:rain_freshwater_flux, architecture; kw...) + Fsn = JRA55FieldTimeSeries(:snow_freshwater_flux, architecture; kw...) + Ql = JRA55FieldTimeSeries(:downwelling_longwave_radiation, architecture; kw...) + Qs = JRA55FieldTimeSeries(:downwelling_shortwave_radiation, architecture; kw...) freshwater_flux = (rain = Fra, snow = Fsn) @@ -60,14 +45,15 @@ function JRA55PrescribedAtmosphere(metadata::JRA55Metadata, arch_or_grid = CPU() # a different frequency than the rest of the JRA55 data. We use `PrescribedAtmospheres` # "auxiliary_freshwater_flux" feature to represent them. if include_rivers_and_icebergs - Fri = JRA55FieldTimeSeries(:river_freshwater_flux; kw...) - Fic = JRA55FieldTimeSeries(:iceberg_freshwater_flux; kw...) + Fri = JRA55FieldTimeSeries(:river_freshwater_flux, architecture; kw...) + Fic = JRA55FieldTimeSeries(:iceberg_freshwater_flux, architecture; kw...) auxiliary_freshwater_flux = (rivers = Fri, icebergs = Fic) else auxiliary_freshwater_flux = nothing end times = ua.times + grid = ua.grid velocities = (u = ua, v = va) @@ -82,7 +68,7 @@ function JRA55PrescribedAtmosphere(metadata::JRA55Metadata, arch_or_grid = CPU() FT = eltype(ua) reference_height = convert(FT, reference_height) - atmosphere = PrescribedAtmosphere(times, FT; + atmosphere = PrescribedAtmosphere(grid, times; velocities, freshwater_flux, auxiliary_freshwater_flux, diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/jra55_field_time_series.jl index bb24bce65..04876a790 100644 --- a/src/DataWrangling/JRA55/jra55_field_time_series.jl +++ b/src/DataWrangling/JRA55/jra55_field_time_series.jl @@ -292,7 +292,7 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture = CPU(); push!(φn, 90) push!(λn, λn[1] + 360) - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, grid, Center, Center, λc, φc) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, nothing, Center, Center, λc, φc) data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 79a8fafd4..e485da207 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -287,9 +287,8 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters ##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic) ##### -struct PrescribedAtmosphere{FT, M, G, U, P, C, F, I, R, TP, TI} +struct PrescribedAtmosphere{FT, G, U, P, C, F, I, R, TP, TI} grid :: G - metadata :: M velocities :: U pressure :: P tracers :: C @@ -349,22 +348,20 @@ end """ PrescribedAtmosphere(grid, times; - metadata = nothing, reference_height = 10, # meters boundary_layer_height = 600 # meters, thermodynamics_parameters = PrescribedAtmosphereThermodynamicsParameters(FT), - auxiliary_freshwater_flux = nothing, - 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)) + auxiliary_freshwater_flux = nothing, + 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)) Return a representation of a prescribed time-evolving atmospheric state with data given at `times`. """ function PrescribedAtmosphere(grid, times; - metadata = nothing, reference_height = convert(eltype(grid), 10), boundary_layer_height = convert(eltype(grid), 600), thermodynamics_parameters = nothing, @@ -381,7 +378,6 @@ function PrescribedAtmosphere(grid, times; end return PrescribedAtmosphere(grid, - metadata, velocities, pressure, tracers, From e81bdfb3ab3f84c650583b8685b99361438ba0b9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 14:23:40 +0100 Subject: [PATCH 021/203] works --- src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index 0c16ce5bd..1fe097cc5 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -3,7 +3,6 @@ const AA = Oceananigans.Architectures.AbstractArchitecture JRA55PrescribedAtmosphere(arch::Distributed; kw...) = JRA55PrescribedAtmosphere(child_architecture(arch); kw...) -# TODO: allow the user to pass dates """ JRA55PrescribedAtmosphere(architecture::AA; version = JRA55RepeatYear(), From afbd1ccadb9e64e8e2496995258dc4d7d21b3299 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 14:26:38 +0100 Subject: [PATCH 022/203] improve show method --- src/DataWrangling/ECCO/ECCO_metadata.jl | 7 ------- src/DataWrangling/metadata.jl | 10 +++++----- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index 11e73fe01..0899d0277 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -16,13 +16,6 @@ struct ECCO4Monthly end const ECCOMetadata{D, V} = Metadata{D, V} where {D, V<:Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}} -Base.show(io::IO, metadata::ECCOMetadata) = - print(io, "ECCOMetadata:", '\n', - "├── name: $(metadata.name)", '\n', - "├── dates: $(metadata.dates)", '\n', - "├── version: $(metadata.version)", '\n', - "└── dir: $(metadata.dir)") - Base.summary(md::ECCOMetadata{<:Any, <:ECCO2Daily}) = "ECCO2Daily $(md.name) metadata ($(first(md.dates))--$(last(md.dates)))" Base.summary(md::ECCOMetadata{<:Any, <:ECCO2Monthly}) = "ECCO2Monthly $(md.name) metadata ($(first(md.dates))--$(last(md.dates)))" Base.summary(md::ECCOMetadata{<:Any, <:ECCO4Monthly}) = "ECCO4Monthly $(md.name) metadata ($(first(md.dates))--$(last(md.dates)))" diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 794234639..5241eeed4 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -18,12 +18,12 @@ struct Metadata{D, V} dir :: String end -Base.show(io::IO, metadata::Metadata) = - print(io, "Metadata:", '\n', - "├── field: $(metadata.name)", '\n', +Base.show(io::IO, metadata::EMetadata) = + print(io, "ECCOMetadata:", '\n', + "├── name: $(metadata.name)", '\n', "├── dates: $(metadata.dates)", '\n', - "└── data version: $(metadata.version)") - + "├── version: $(metadata.version)", '\n', + "└── data directory: $(metadata.dir)") # Treat Metadata as an array to allow iteration over the dates. Base.length(metadata::Metadata) = length(metadata.dates) From 8599314412c5e5cb5ce4e0ff2a7d43bb1d7b6945 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 14:28:22 +0100 Subject: [PATCH 023/203] change names --- .../{jra55_field_time_series.jl => JRA55_field_time_series.jl} | 0 src/DataWrangling/JRA55/{jra55_metadata.jl => JRA55_metadata.jl} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/DataWrangling/JRA55/{jra55_field_time_series.jl => JRA55_field_time_series.jl} (100%) rename src/DataWrangling/JRA55/{jra55_metadata.jl => JRA55_metadata.jl} (100%) diff --git a/src/DataWrangling/JRA55/jra55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl similarity index 100% rename from src/DataWrangling/JRA55/jra55_field_time_series.jl rename to src/DataWrangling/JRA55/JRA55_field_time_series.jl diff --git a/src/DataWrangling/JRA55/jra55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl similarity index 100% rename from src/DataWrangling/JRA55/jra55_metadata.jl rename to src/DataWrangling/JRA55/JRA55_metadata.jl From bb246333003dff9ffe181ee3eb1ffe9f7fe0d176 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 14:29:39 +0100 Subject: [PATCH 024/203] go ahead --- src/DataWrangling/JRA55/JRA55_metadata.jl | 34 ++++++----------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 977afb50c..659cbe484 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -43,19 +43,18 @@ function metadata_filename(metadata::Metadata{<:Any, <:JRA55RepeatYear}) # No di return "RYF." * shortname * ".1990_1991.nc" end -# TODO: Implement this function for JRA55MultipleYears -# function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) -# # fix the filename -# shortname = short_name(metadata) -# year = Dates.year(metadata.dates) -# suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" -# dates = "($year)01010130-($year)12312330.nc" -# return shortname * suffix * dates * ".nc" -# end +function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) + # fix the filename + shortname = short_name(metadata) + year = Dates.year(metadata.dates) + suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" + dates = "($year)01010130-($year)12312330.nc" + return shortname * suffix * dates * ".nc" +end # Convenience functions short_name(data::JRA55Metadata) = JRA55_short_names[data.name] -location(data::JRA55Metadata) = (Center, Center, Center) +location(::JRA55Metadata) = (Center, Center, Center) # A list of all variables provided in the JRA55 dataset: JRA55_variable_names = (:river_freshwater_flux, @@ -86,21 +85,6 @@ JRA55_short_names = Dict( :northward_velocity => "vas", # Northward near-surface wind ) -field_time_series_short_names = Dict( - :river_freshwater_flux => "Fri", # Freshwater fluxes from rivers - :rain_freshwater_flux => "Fra", # Freshwater flux from rainfall - :snow_freshwater_flux => "Fsn", # Freshwater flux from snowfall - :iceberg_freshwater_flux => "Fic", # Freshwater flux from calving icebergs - :specific_humidity => "qa", # Surface specific humidity - :sea_level_pressure => "pa", # Sea level pressure - :relative_humidity => "rh", # Surface relative humidity - :downwelling_longwave_radiation => "Ql", # Downwelling longwave radiation - :downwelling_shortwave_radiation => "Qs", # Downwelling shortwave radiation - :temperature => "Ta", # Near-surface air temperature - :eastward_velocity => "ua", # Eastward near-surface wind - :northward_velocity => "va", # Northward near-surface wind -) - JRA55_repeat_year_urls = Dict( :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", From 4f05dbbdfbc804ea39350e236d4c271d6ac8ef05 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 14:34:40 +0100 Subject: [PATCH 025/203] fix it --- src/DataWrangling/JRA55/JRA55_metadata.jl | 6 ++++-- src/DataWrangling/metadata.jl | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 659cbe484..199ef59c3 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -129,8 +129,10 @@ JRA55_repeat_year_urls = Dict( variable_is_three_dimensional(data::JRA55Metadata) = false urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] -# TODO: -# urls(metadata::Metadata{<:Any, <:JRA55MultipleYears}) = ... +function urls(metadata::Metadata{<:Any, <:JRA55MultipleYears}) + shotname = short_name(metadata) + return "https://esgf-data2.llnl.gov/thredds/fileServer/user_pub_work/input4MIPs/CMIP6/OMIP/MRI/MRI-JRA55-do-1-5-0/atmos/$(shortname)/prra/gr/v20200916/" +end metadata_url(prefix, m::Metadata{<:Any, <:JRA55RepeatYear}) = prefix # No specific name for this url diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 5241eeed4..e61dec10a 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -18,7 +18,7 @@ struct Metadata{D, V} dir :: String end -Base.show(io::IO, metadata::EMetadata) = +Base.show(io::IO, metadata::Metadata) = print(io, "ECCOMetadata:", '\n', "├── name: $(metadata.name)", '\n', "├── dates: $(metadata.dates)", '\n', From fe6dc72f724896cf7f244d73eb028d20f1e70b29 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Feb 2025 15:14:54 +0100 Subject: [PATCH 026/203] this should work --- .../JRA55/JRA55_field_time_series.jl | 92 ++++++++++--------- src/DataWrangling/JRA55/JRA55_metadata.jl | 17 ++-- 2 files changed, 61 insertions(+), 48 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 04876a790..b1e0db4a0 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -73,17 +73,20 @@ function compute_bounding_indices(longitude, latitude, grid, LX, LY, λc, φc) return i₁, i₂, j₁, j₂, TX end -struct JRA55NetCDFBackend <: AbstractInMemoryBackend{Int} +struct JRA55NetCDFBackend{M} <: AbstractInMemoryBackend{Int} start :: Int length :: Int + metadata :: M end +Adapt.adapt_structure(to, b::JRA55NetCDFBackend) = JRA55NetCDFBackend(b.start, b.length, nothing) + """ JRA55NetCDFBackend(length) Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. """ -JRA55NetCDFBackend(length) = JRA55NetCDFBackend(1, length) +JRA55NetCDFBackend(length, metadata) = JRA55NetCDFBackend(1, length, metadata) Base.length(backend::JRA55NetCDFBackend) = backend.length Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") @@ -91,52 +94,59 @@ Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backen const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} # TODO: This will need to change when we add a method for JRA55MultipleYears -function set!(fts::JRA55NetCDFFTS, path::String=fts.path, name::String=fts.name) +function set!(fts::JRA55NetCDFFTS) - ds = Dataset(path) + backend = fts.backend + metadata = backend.metadata - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - LX, LY, LZ = location(fts) - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) - - nn = time_indices(fts) - nn = collect(nn) + filepath = metadata_path(metadata) + + for path in filepath + ds = Dataset(path) + + # Note that each file should have the variables + # - ds["time"]: time coordinate + # - ds["lon"]: longitude at the location of the variable + # - ds["lat"]: latitude at the location of the variable + # - ds["lon_bnds"]: bounding longitudes between which variables are averaged + # - ds["lat_bnds"]: bounding latitudes between which variables are averaged + # - ds[shortname]: the variable data + + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + LX, LY, LZ = location(fts) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) + + nn = time_indices(fts) + nn = collect(nn) + + if issorted(nn) + data = ds[name][i₁:i₂, j₁:j₂, nn] + else + # The time indices may be cycling past 1; eg ti = [6, 7, 8, 1]. + # However, DiskArrays does not seem to support loading data with unsorted + # indices. So to handle this, we load the data in chunks, where each chunk's + # indices are sorted, and then glue the data together. + m = findfirst(n -> n == 1, nn) + n1 = nn[1:m-1] + n2 = nn[m:end] + + data1 = ds[name][i₁:i₂, j₁:j₂, n1] + data2 = ds[name][i₁:i₂, j₁:j₂, n2] + data = cat(data1, data2, dims=3) + end + + close(ds) - if issorted(nn) - data = ds[name][i₁:i₂, j₁:j₂, nn] - else - # The time indices may be cycling past 1; eg ti = [6, 7, 8, 1]. - # However, DiskArrays does not seem to support loading data with unsorted - # indices. So to handle this, we load the data in chunks, where each chunk's - # indices are sorted, and then glue the data together. - m = findfirst(n -> n == 1, nn) - n1 = nn[1:m-1] - n2 = nn[m:end] - - data1 = ds[name][i₁:i₂, j₁:j₂, n1] - data2 = ds[name][i₁:i₂, j₁:j₂, n2] - data = cat(data1, data2, dims=3) + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) end - - close(ds) - - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) - + return nothing end -new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length) +new_backend(b::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, length, b.metadata) """ JRA55FieldTimeSeries(variable_name [, arch_or_grid=CPU() ]; diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 199ef59c3..f88bf6600 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -48,7 +48,12 @@ function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55Multi shortname = short_name(metadata) year = Dates.year(metadata.dates) suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" - dates = "($year)01010130-($year)12312330.nc" + + if shortname == "tas" + dates = "$(year)01010000-$(year)12312100" + else + dates = "$(year)01010130-$(year)12312330" + end return shortname * suffix * dates * ".nc" end @@ -129,17 +134,15 @@ JRA55_repeat_year_urls = Dict( variable_is_three_dimensional(data::JRA55Metadata) = false urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] -function urls(metadata::Metadata{<:Any, <:JRA55MultipleYears}) - shotname = short_name(metadata) - return "https://esgf-data2.llnl.gov/thredds/fileServer/user_pub_work/input4MIPs/CMIP6/OMIP/MRI/MRI-JRA55-do-1-5-0/atmos/$(shortname)/prra/gr/v20200916/" -end +urls(metadata::Metadata{<:Any, <:JRA55MultipleYears}) = "https://esgf-data2.llnl.gov/thredds/fileServer/user_pub_work/input4MIPs/CMIP6/OMIP/MRI/MRI-JRA55-do-1-5-0/atmos/3hrPt" -metadata_url(prefix, m::Metadata{<:Any, <:JRA55RepeatYear}) = prefix # No specific name for this url +metadata_url(prefix, m::Metadata{<:Any, <:JRA55RepeatYear}) = prefix # No specific name for this url +metadata_url(prefix, m::Metadata{<:Any, <:JRA55MultipleYears}) = prefix * "/" * short_name(m) * "/gr/v20200916/" * metadata_filename(m) # TODO: This will need to change when we add a method for JRA55MultipleYears function download_dataset!(metadata::JRA55Metadata; url = urls(metadata)) - asyncmap(metadata, ntasks=10) do metadatum # Distribute the download among tasks + for metadatum in metadata # Distribute the download among tasks fileurl = metadata_url(url, metadatum) filepath = metadata_path(metadatum) From 787ebc91ba47150c312d9ee6c3bcf37709de9cdd Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 11:18:17 +0100 Subject: [PATCH 027/203] add a new constructor --- src/DataWrangling/metadata.jl | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 546b4140e..9f4e10a36 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -31,7 +31,7 @@ Keyword Arguments """ function Metadata(variable_name; dataset, - dates=all_dates(dataset, variable_name)[1], + dates=all_dates(dataset, variable_name)[1:1], dir=default_download_folder(dataset)) return Metadata(variable_name, dates, dataset, dir) @@ -40,6 +40,15 @@ end const AnyDateTime = Union{AbstractCFDateTime, Dates.AbstractDateTime} const Metadatum = Metadata{<:AnyDateTime} +# A constructor for a single date +function Metadatum(variable_name; + dataset, + date=first_date(dataset, variable_name), + dir=default_download_folder(dataset)) + + return Metadata(variable_name, date, dataset, dir) +end + default_download_folder(dataset) = "./" Base.show(io::IO, metadata::Metadata) = @@ -104,6 +113,10 @@ function native_times(metadata; start_time=first(metadata).dates) return times end +#### +#### Some utilities +#### + """ all_dates(metadata) @@ -112,7 +125,25 @@ Needs to be extended by any new dataset dataset. """ all_dates(metadata) = all_dates(metadata.dataset, metadata.name) +""" + first_date(dataset, variable_name) + +Extracts the first date of the given dataset and variable name formatted using the `DateTime` type. +""" +first_date(dataset, variable_name) = first(all_dates(dataset, variable_name)) + +""" + end_date(dataset, variable_name) + +Extracts the last date of the given dataset and variable name formatted using the `DateTime` type. +""" +end_date(dataset, variable_name) = last(all_dates(dataset, variable_name)) + +""" + metadata_filename(metadata) + # File names of metadata containing multiple dates +""" metadata_filename(metadata) = [metadata_filename(metadatum) for metadatum in metadata] """ From 7c519a1ac328b06900719e3eeb67e5322fc7f36f Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 11:19:48 +0100 Subject: [PATCH 028/203] set with ECCOMetadatum --- src/DataWrangling/ECCO/ECCO.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ECCO/ECCO.jl b/src/DataWrangling/ECCO/ECCO.jl index ec625bcc5..0d51c5470 100644 --- a/src/DataWrangling/ECCO/ECCO.jl +++ b/src/DataWrangling/ECCO/ECCO.jl @@ -256,7 +256,7 @@ end inpainted_metadata_path(metadata::ECCOMetadata) = joinpath(metadata.dir, inpainted_metadata_filename(metadata)) -function set!(field::Field, ECCO_metadata::ECCOMetadata; kw...) +function set!(field::Field, ECCO_metadata::ECCOMetadatum; kw...) # Fields initialized from ECCO grid = field.grid From 78a53cd2e0ac2f230f84aaab19a8926d6f21b765 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 11:20:54 +0100 Subject: [PATCH 029/203] some changes --- src/DataWrangling/ECCO/ECCO.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ECCO/ECCO.jl b/src/DataWrangling/ECCO/ECCO.jl index 0d51c5470..141cb2462 100644 --- a/src/DataWrangling/ECCO/ECCO.jl +++ b/src/DataWrangling/ECCO/ECCO.jl @@ -88,7 +88,7 @@ const ECCO_z = [ 0.0, ] -empty_ECCO_field(variable_name::Symbol; kw...) = empty_ECCO_field(ECCOMetadata(variable_name); kw...) +empty_ECCO_field(variable_name::Symbol; kw...) = empty_ECCO_field(Metadatum(variable_name, dataset=ECCO4Monthly()); kw...) function empty_ECCO_field(metadata::ECCOMetadata; architecture = CPU(), From 1e71d6719dfb3760aceff8fab3065cca98abb960 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 11:30:01 +0100 Subject: [PATCH 030/203] improvement to UI --- src/DataWrangling/DataWrangling.jl | 2 +- src/DataWrangling/ECCO/ECCO_restoring.jl | 15 ++++++-- .../JRA55/JRA55_field_time_series.jl | 12 ++++--- .../JRA55/JRA55_prescribed_atmosphere.jl | 36 ++++++++----------- src/DataWrangling/metadata.jl | 16 ++++++--- 5 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index 3514c6738..71b43ec01 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -1,6 +1,6 @@ module DataWrangling -export Metadata, all_dates +export Metadata, all_dates, first_date, end_date using Oceananigans using Downloads diff --git a/src/DataWrangling/ECCO/ECCO_restoring.jl b/src/DataWrangling/ECCO/ECCO_restoring.jl index 23483d032..ea20fe5f7 100644 --- a/src/DataWrangling/ECCO/ECCO_restoring.jl +++ b/src/DataWrangling/ECCO/ECCO_restoring.jl @@ -141,10 +141,13 @@ end function ECCOFieldTimeSeries(variable_name::Symbol; dataset = ECCO4Monthly(), architecture = CPU(), - dates = all_dates(dataset, variable_name), + start_date = first_date(dataset, variable_name), + end_date = first_date(dataset, variable_name), dir = download_ECCO_cache, kw...) + native_dates = all_dates(dataset, variable_name) + dates = compute_native_date_range(native_dates, start_date, end_date) metadata = Metadata(variable_name, dates, dataset, dir) return ECCOFieldTimeSeries(metadata, architecture; kw...) end @@ -266,7 +269,9 @@ Keyword Arguments - `dataset`: The dataset of the ECCO dataset. Default: `ECCO4Monthly()`. -- `dates`: The dates to use for the ECCO dataset. Default: `all_dates(dataset, variable_name)`. +- `start_date`: The starting date to use for the ECCO dataset. Default: `first_date(dataset, variable_name)`. + +- `end_date`: The ending date to use for the ECCO dataset. Default: `end_date(dataset, variable_name)`. - `time_indices_in_memory`: The number of time indices to keep in memory. The number is chosen based on a trade-off between increased performance (more indices in memory) and reduced @@ -289,11 +294,15 @@ Keyword Arguments function ECCORestoring(variable_name::Symbol, arch_or_grid = CPU(); dataset = ECCO4Monthly(), - dates = all_dates(dataset, variable_name), + start_date = first_date(dataset, variable_name), + end_date = last_date(dataset, variable_name), dir = download_ECCO_cache, kw...) + native_dates = all_dates(dataset, variable_name) + dates = compute_native_date_range(native_dates, start_date, end_date) metadata = Metadata(variable_name, dates, dataset, dir) + return ECCORestoring(metadata, arch_or_grid; kw...) end diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 73386836b..62eed3f47 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -180,9 +180,9 @@ Keyword arguments - `architecture`: Architecture for the `FieldTimeSeries`. Default: CPU() -- `dates`: The date(s) of the metadata. Note this can either be a single date, - representing a snapshot, or a range of dates, representing a time-series. - Default: `all_dates(dataset, name)` (see `all_dates`). +- `start_date`: The starting date to use for the ECCO dataset. Default: `first_date(dataset, variable_name)`. + +- `end_date`: The ending date to use for the ECCO dataset. Default: `end_date(dataset, variable_name)`. - `dataset`: The data dataset. The only supported datasets is `JRA55RepeatYear()` @@ -203,10 +203,14 @@ Keyword arguments """ function JRA55FieldTimeSeries(variable_name::Symbol, architecture = CPU(), FT=Float32; dataset = JRA55RepeatYear(), - dates = all_dates(dataset, variable_name), + start_date = first_date(dataset, variable_name), + end_date = last_date(dataset, variable_name), dir = download_JRA55_cache, kw...) + native_dates = all_dates(dataset, variable_name) + dates = compute_native_date_range(native_dates, start_date, end_date) + metadata = Metadata(variable_name, dates, dataset, dir) return JRA55FieldTimeSeries(metadata, architecture, FT; kw...) diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index 9ea6b4d9a..97ca8db37 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -17,29 +17,26 @@ Return a `PrescribedAtmosphere` representing JRA55 reanalysis data. """ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; dataset = JRA55RepeatYear(), - start_date = first(all_dates(dataset, :temperature)), - end_date = last(all_dates(dataset, :temperature)), + start_date = first_date(dataset, :temperature), + end_date = last_date(dataset, :temperature), backend = JRA55NetCDFBackend(10), time_indexing = Cyclical(), surface_layer_height = 10, # meters include_rivers_and_icebergs = false, other_kw...) - native_dates = all_dates(dataset, :temperature) - dates = compute_native_date_range(native_dates, start_date, end_date) - - kw = (; time_indexing, dates, backend, dataset) + kw = (; time_indexing, dates, backend, start_date, end_date, dataset) kw = merge(kw, other_kw) - ua = JRA55FieldTimeSeries(:eastward_velocity, architecture, FT; dates, kw...) - va = JRA55FieldTimeSeries(:northward_velocity, architecture, FT; dates, kw...) - Ta = JRA55FieldTimeSeries(:temperature, architecture, FT; dates, kw...) - qa = JRA55FieldTimeSeries(:specific_humidity, architecture, FT; dates, kw...) - pa = JRA55FieldTimeSeries(:sea_level_pressure, architecture, FT; dates, kw...) - Fra = JRA55FieldTimeSeries(:rain_freshwater_flux, architecture, FT; dates, kw...) - Fsn = JRA55FieldTimeSeries(:snow_freshwater_flux, architecture, FT; dates, kw...) - Ql = JRA55FieldTimeSeries(:downwelling_longwave_radiation, architecture, FT; dates, kw...) - Qs = JRA55FieldTimeSeries(:downwelling_shortwave_radiation, architecture, FT; dates, 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...) + Ql = JRA55FieldTimeSeries(:downwelling_longwave_radiation, architecture, FT; kw...) + Qs = JRA55FieldTimeSeries(:downwelling_shortwave_radiation, architecture, FT; kw...) freshwater_flux = (rain = Fra, snow = Fsn) @@ -47,12 +44,9 @@ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; # Remember that rivers and icebergs are on a different grid and have # a different frequency than the rest of the JRA55 data. We use `PrescribedAtmospheres` # "auxiliary_freshwater_flux" feature to represent them. - if include_rivers_and_icebergs - native_dates = all_dates(dataset, :river_freshwater_flux) - dates = compute_native_date_range(native_dates, start_date, end_date) - - Fri = JRA55FieldTimeSeries(:river_freshwater_flux, architecture; dates, kw...) - Fic = JRA55FieldTimeSeries(:iceberg_freshwater_flux, architecture; dates, kw...) + if include_rivers_and_icebergs + Fri = JRA55FieldTimeSeries(:river_freshwater_flux, architecture; kw...) + Fic = JRA55FieldTimeSeries(:iceberg_freshwater_flux, architecture; kw...) auxiliary_freshwater_flux = (rivers = Fri, icebergs = Fic) else auxiliary_freshwater_flux = nothing diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 9f4e10a36..9380b94be 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -23,8 +23,8 @@ Arguments Keyword Arguments ================= -- `dates`: The dates of the dataset, in a `AbstractCFDateTime` format.. Note this can either be a single date, - representing a snapshot, or a range of dates, representing a time-series. +- `dates`: The dates of the dataset, in a `AbstractCFDateTime` format.. Note this can either be a range or a vector of dates, + representing a time-series. For a single date, use the [`Metadatum`](@ref) constructor . - `dataset`: The dataset of the dataset. Supported datasets are `ECCO2Monthly()`, `ECCO2Daily()`, `ECCO4Monthly()`, `JRA55RepeatYear()`, or `JRA55MultipleYears()`. - `dir`: The directory where the dataset is stored. @@ -40,7 +40,14 @@ end const AnyDateTime = Union{AbstractCFDateTime, Dates.AbstractDateTime} const Metadatum = Metadata{<:AnyDateTime} -# A constructor for a single date +""" + Metadatum(variable_name; + dataset, + date=first_date(dataset, variable_name), + dir=default_download_folder(dataset)) + +Specific constructor for a `Metadata` object with a single date, representative of a snapshot in time. +""" function Metadatum(variable_name; dataset, date=first_date(dataset, variable_name), @@ -142,7 +149,8 @@ end_date(dataset, variable_name) = last(all_dates(dataset, variable_name)) """ metadata_filename(metadata) -# File names of metadata containing multiple dates +File names of metadata containing multiple dates. The specific version for a `Metadatum` object is +extended in the data specific modules. """ metadata_filename(metadata) = [metadata_filename(metadatum) for metadatum in metadata] From 4f7fdb24def5e24e6ee1ba5e7d62f4b086a15156 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 11:35:40 +0100 Subject: [PATCH 031/203] change examples --- examples/ecco_inspect_temperature_salinity.jl | 9 ++++----- examples/ecco_mixed_layer_depth.jl | 12 ++++-------- examples/generate_surface_fluxes.jl | 4 ++-- ...editerranean_simulation_with_ecco_restoring.jl | 15 ++++++--------- examples/near_global_ocean_simulation.jl | 4 ++-- examples/one_degree_simulation.jl | 3 +-- examples/single_column_os_papa_simulation.jl | 4 ++-- 7 files changed, 21 insertions(+), 30 deletions(-) diff --git a/examples/ecco_inspect_temperature_salinity.jl b/examples/ecco_inspect_temperature_salinity.jl index a1b4f4890..da1bc0b87 100644 --- a/examples/ecco_inspect_temperature_salinity.jl +++ b/examples/ecco_inspect_temperature_salinity.jl @@ -39,15 +39,14 @@ sb = SeawaterBuoyancy(; equation_of_state) tracers = (T=T, S=S) b = Field(buoyancy(sb, grid, tracers)) -start = DateTime(1993, 1, 1) -stop = DateTime(1999, 1, 1) -dates = range(start; stop, step=Month(1)) +start_date = DateTime(1993, 1, 1) +end_date = DateTime(1999, 1, 1) Tmeta = Metadata(:temperature; dates, dataset=ECCO4Monthly()) Smeta = Metadata(:salinity; dates, dataset=ECCO4Monthly()) -Tt = ECCOFieldTimeSeries(Tmeta, grid; time_indices_in_memory=length(dates)) -St = ECCOFieldTimeSeries(Smeta, grid; time_indices_in_memory=length(dates)) +Tt = ECCOFieldTimeSeries(:temperature, grid; start_date, end_date, time_indices_in_memory=length(dates)) +St = ECCOFieldTimeSeries(:salinity, grid; start_date, end_date, time_indices_in_memory=length(dates)) fig = Figure(size=(900, 1050)) diff --git a/examples/ecco_mixed_layer_depth.jl b/examples/ecco_mixed_layer_depth.jl index a444e734f..e712eaa64 100644 --- a/examples/ecco_mixed_layer_depth.jl +++ b/examples/ecco_mixed_layer_depth.jl @@ -30,15 +30,11 @@ bottom_height = regrid_bathymetry(grid; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) -start = DateTimeProlepticGregorian(1993, 1, 1) -stop = DateTimeProlepticGregorian(2003, 1, 1) -dates = range(start; stop, step=Month(1)) +start_date = DateTimeProlepticGregorian(1993, 1, 1) +end_date = DateTimeProlepticGregorian(2003, 1, 1) -Tmeta = Metadata(:temperature; dates, dataset=ECCO4Monthly()) -Smeta = Metadata(:salinity; dates, dataset=ECCO4Monthly()) - -Tt = ECCOFieldTimeSeries(Tmeta, grid; time_indices_in_memory=2) -St = ECCOFieldTimeSeries(Smeta, grid; time_indices_in_memory=2) +Tt = ECCOFieldTimeSeries(Tmeta, grid; start_date, end_date, time_indices_in_memory=2) +St = ECCOFieldTimeSeries(Smeta, grid; start_date, end_date, time_indices_in_memory=2) ht = FieldTimeSeries{Center, Center, Nothing}(grid, Tt.times) equation_of_state = TEOS10EquationOfState() diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index c762d9d2d..7ef0087c4 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -52,8 +52,8 @@ ocean = ocean_simulation(grid, closure=nothing) # Now that we have an atmosphere and ocean, we `set!` the ocean temperature and salinity # to the ECCO2 data by first creating T, S metadata objects, -T_metadata = Metadata(:temperature; dataset=ECCO4Monthly()) -S_metadata = Metadata(:salinity; dataset=ECCO4Monthly()) +T_metadata = Metadatum(:temperature; date=DateTime(1993, 1, 1), dataset=ECCO4Monthly()) +S_metadata = Metadatum(:salinity; date=DateTime(1993, 1, 1), dataset=ECCO4Monthly()) # Note that if a date is not provided to `Metadata`, then the default Jan 1st, 1992 is used. # To copy the ECCO state into `ocean.model`, we use `set!`, diff --git a/examples/mediterranean_simulation_with_ecco_restoring.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl index d9bc528d4..665675402 100644 --- a/examples/mediterranean_simulation_with_ecco_restoring.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -23,8 +23,6 @@ using ClimaOcean.ECCO using ClimaOcean.ECCO: ECCO4Monthly using Oceananigans.Units using Printf - -using CFTime using Dates # ## Grid Configuration for the Mediterranean Sea @@ -73,13 +71,11 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) # using the function `ECCO_restoring_forcing` to apply restoring forcings for these tracers. # This allows us to nudge the model towards realistic temperature and salinity profiles. -dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1993, 12, 1) - -temperature = Metadata(:temperature; dates, dataset=ECCO4Monthly()) -salinity = Metadata(:salinity; dates, dataset=ECCO4Monthly()) +start_date = DateTime(1993, 1, 1) +end_date = DateTime(1993, 12, 1) -FT = ECCO_restoring_forcing(temperature; architecture = GPU(), timescale = 2days) -FS = ECCO_restoring_forcing(salinity; architecture = GPU(), timescale = 2days) +FT = ECCO_restoring_forcing(:temperature; start_date, end_date, architecture = GPU(), timescale = 2days) +FS = ECCO_restoring_forcing(:salinity; start_date, end_date, architecture = GPU(), timescale = 2days) # Constructing the Simulation # @@ -94,7 +90,8 @@ ocean = ocean_simulation(grid; forcing = (T = FT, S = FS)) # In this case, our ECCO dataset has access to a temperature and a salinity # field, so we initialize temperature T and salinity S from ECCO. -set!(ocean.model, T = temperature[1], S = salinity[1]) +set!(ocean.model, T = Metadatum(:temperature; date=start_date), + S = Metadatum(:salinity; date=start_date)) fig = Figure() ax = Axis(fig[1, 1]) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 1f005b7bd..ec45a3144 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -84,8 +84,8 @@ ocean.model # We initialize the ocean model with ECCO2 temperature and salinity for January 1, 1993. date = DateTimeProlepticGregorian(1993, 1, 1) -set!(ocean.model, T=Metadata(:temperature; dates=date, dataset=ECCO4Monthly()), - S=Metadata(:salinity; dates=date, dataset=ECCO4Monthly())) +set!(ocean.model, T=Metadatum(:temperature; date, dataset=ECCO4Monthly()), + S=Metadatum(:salinity; date, dataset=ECCO4Monthly())) # ### Prescribed atmosphere and radiation # diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index d1c2f6ecc..23deab866 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -100,8 +100,7 @@ ocean = ocean_simulation(grid; # We initialize the ocean from the ECCO state estimate. -set!(ocean.model, T=Metadata(:temperature; dates=first(dates), dataset=ECCO4Monthly()), - S=Metadata(:salinity; dates=first(dates), dataset=ECCO4Monthly())) +set!(ocean.model, T=temperature[1], S=salinity[1]) # ### Atmospheric forcing diff --git a/examples/single_column_os_papa_simulation.jl b/examples/single_column_os_papa_simulation.jl index dfed57dbd..dc19b52fe 100644 --- a/examples/single_column_os_papa_simulation.jl +++ b/examples/single_column_os_papa_simulation.jl @@ -51,8 +51,8 @@ ocean.model # We set initial conditions from ECCO: -set!(ocean.model, T=Metadata(:temperature, dataset=ECCO4Monthly()), - S=Metadata(:salinity, dataset=ECCO4Monthly())) +set!(ocean.model, T=Metadatum(:temperature), + S=Metadatum(:salinity)) # # A prescribed atmosphere based on JRA55 re-analysis # From 58662d25ea7ec9c90898d4effe217b12512a4fe6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 11:40:14 +0100 Subject: [PATCH 032/203] we don't need this --- examples/ecco_inspect_temperature_salinity.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/ecco_inspect_temperature_salinity.jl b/examples/ecco_inspect_temperature_salinity.jl index da1bc0b87..d3a77ce6d 100644 --- a/examples/ecco_inspect_temperature_salinity.jl +++ b/examples/ecco_inspect_temperature_salinity.jl @@ -42,9 +42,6 @@ b = Field(buoyancy(sb, grid, tracers)) start_date = DateTime(1993, 1, 1) end_date = DateTime(1999, 1, 1) -Tmeta = Metadata(:temperature; dates, dataset=ECCO4Monthly()) -Smeta = Metadata(:salinity; dates, dataset=ECCO4Monthly()) - Tt = ECCOFieldTimeSeries(:temperature, grid; start_date, end_date, time_indices_in_memory=length(dates)) St = ECCOFieldTimeSeries(:salinity, grid; start_date, end_date, time_indices_in_memory=length(dates)) From 22c8d08e215fe667b39787c061648a34d5940ae1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 11:41:01 +0100 Subject: [PATCH 033/203] chnages --- examples/ecco_mixed_layer_depth.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/ecco_mixed_layer_depth.jl b/examples/ecco_mixed_layer_depth.jl index e712eaa64..16b505d43 100644 --- a/examples/ecco_mixed_layer_depth.jl +++ b/examples/ecco_mixed_layer_depth.jl @@ -4,7 +4,6 @@ using ClimaOcean.DataWrangling.ECCO: ECCO_field, ECCOFieldTimeSeries, ECCO4Month using Oceananigans using CairoMakie using Printf -using CFTime using Dates using SeawaterPolynomials: TEOS10EquationOfState @@ -30,11 +29,11 @@ bottom_height = regrid_bathymetry(grid; grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height)) -start_date = DateTimeProlepticGregorian(1993, 1, 1) -end_date = DateTimeProlepticGregorian(2003, 1, 1) +start_date = DateTime(1993, 1, 1) +end_date = DateTime(2003, 1, 1) -Tt = ECCOFieldTimeSeries(Tmeta, grid; start_date, end_date, time_indices_in_memory=2) -St = ECCOFieldTimeSeries(Smeta, grid; start_date, end_date, time_indices_in_memory=2) +Tt = ECCOFieldTimeSeries(:temprature, grid; start_date, end_date, time_indices_in_memory=2) +St = ECCOFieldTimeSeries(:salinity, grid; start_date, end_date, time_indices_in_memory=2) ht = FieldTimeSeries{Center, Center, Nothing}(grid, Tt.times) equation_of_state = TEOS10EquationOfState() From 79f37ebb117935945d08586bab7fb6a4610760c2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 11:47:19 +0100 Subject: [PATCH 034/203] export ui functions --- src/ClimaOcean.jl | 3 +++ src/DataWrangling/DataWrangling.jl | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 670149b21..d37389aca 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -25,6 +25,9 @@ export PowerLawStretching, LinearStretching, exponential_z_faces, Metadata, + Metadatum, + first_date, + last_date, all_dates, JRA55FieldTimeSeries, ECCO_field, diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index 71b43ec01..e342d194d 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -1,6 +1,6 @@ module DataWrangling -export Metadata, all_dates, first_date, end_date +export Metadata, Metadatum, all_dates, first_date, end_date using Oceananigans using Downloads From a98669f6d662166236738478d5d3b436f0199f8f Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 11:56:51 +0100 Subject: [PATCH 035/203] last date --- src/DataWrangling/DataWrangling.jl | 2 +- src/DataWrangling/metadata.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index e342d194d..5ce954d26 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -1,6 +1,6 @@ module DataWrangling -export Metadata, Metadatum, all_dates, first_date, end_date +export Metadata, Metadatum, all_dates, first_date, last_date using Oceananigans using Downloads diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 9380b94be..0de805f35 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -140,11 +140,11 @@ Extracts the first date of the given dataset and variable name formatted using t first_date(dataset, variable_name) = first(all_dates(dataset, variable_name)) """ - end_date(dataset, variable_name) + last_date(dataset, variable_name) Extracts the last date of the given dataset and variable name formatted using the `DateTime` type. """ -end_date(dataset, variable_name) = last(all_dates(dataset, variable_name)) +last_date(dataset, variable_name) = last(all_dates(dataset, variable_name)) """ metadata_filename(metadata) From 5405ef374a2e11c77f2bd25935d7b903aa8b04c9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 13:13:38 +0100 Subject: [PATCH 036/203] vestigial dates --- src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index 97ca8db37..2f3c6ac19 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -25,7 +25,7 @@ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; include_rivers_and_icebergs = false, other_kw...) - kw = (; time_indexing, dates, backend, start_date, end_date, dataset) + kw = (; time_indexing, backend, start_date, end_date, dataset) kw = merge(kw, other_kw) ua = JRA55FieldTimeSeries(:eastward_velocity, architecture, FT; kw...) From b2ff520b256c1a2b8d740b842090d2e30e9a5b97 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 13:19:41 +0100 Subject: [PATCH 037/203] change docstrings --- .../JRA55/JRA55_field_time_series.jl | 8 +++----- .../JRA55/JRA55_prescribed_atmosphere.jl | 20 +++++++++++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 62eed3f47..8c9287742 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -147,12 +147,8 @@ new_backend(::JRA55NetCDFBackend, start, length) = JRA55NetCDFBackend(start, len latitude = nothing, longitude = nothing, dir = download_JRA55_cache, - filename = nothing, - shortname = nothing, backend = InMemory(), - time_indexing = Cyclical(), - preprocess_chunk_size = 10, - preprocess_architecture = CPU()) + time_indexing = Cyclical()) Return a `FieldTimeSeries` containing atmospheric reanalysis data for `variable_name`, which describes one of the variables in the "repeat year forcing" dataset derived @@ -188,6 +184,8 @@ Keyword arguments - `dir`: The directory of the data file. Default: `ClimaOcean.JRA55.download_JRA55_cache`. +- `time_indexing`: The time indexing scheme for the field time series. Default: `Cyclical()`. + - `latitude`: Guiding latitude bounds for the resulting grid. Used to slice the data when loading into memory. Default: nothing, which retains the latitude range of the native grid. diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index 2f3c6ac19..5a445b0f0 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -1,19 +1,31 @@ const AA = Oceananigans.Architectures.AbstractArchitecture -JRA55PrescribedAtmosphere(arch::Distributed; kw...) = +JRA55PrescribedAtmosphere(arch::Distributed, FT = Float32; kw...) = JRA55PrescribedAtmosphere(child_architecture(arch); kw...) + """ - JRA55PrescribedAtmosphere([architecture = CPU()]; + JRA55PrescribedAtmosphere([architecture = CPU(), FT = Float32]; dataset = JRA55RepeatYear(), - dates = all_dates(dataset), + start_date = first_date(dataset, :temperature), + end_date = last_date(dataset, :temperature), backend = JRA55NetCDFBackend(10), time_indexing = Cyclical(), surface_layer_height = 10, # meters include_rivers_and_icebergs = false, other_kw...) -Return a `PrescribedAtmosphere` representing JRA55 reanalysis data. +Return a [`PrescribedAtmosphere`](@ref) representing JRA55 reanalysis data. +The atmospheric data will be held in `JRA55FieldTimeSeries` objects containing: + +- velocities (`ua`, `va`) +- tracers (`Ta`, `qa`) +- pressure (`pa`) +- freshwater fluxes (`Fra`, `Fsn`) +- downwelling radiation (`Ql`, `Qs`) +- auxiliary freshwater fluxes (`Fri`, `Fic`) if `include_rivers_and_icebergs` is `true` + +For a detailed description of the keyword arguments, see the [`JRA55FieldTimeSeries`](@ref) constructor. """ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; dataset = JRA55RepeatYear(), From 992b4d7930e299425641a88c7750c2b6525a90c8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 11 Mar 2025 13:20:56 +0100 Subject: [PATCH 038/203] better like this --- src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index 5a445b0f0..eb763832e 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -16,15 +16,7 @@ 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: - -- velocities (`ua`, `va`) -- tracers (`Ta`, `qa`) -- pressure (`pa`) -- freshwater fluxes (`Fra`, `Fsn`) -- downwelling radiation (`Ql`, `Qs`) -- auxiliary freshwater fluxes (`Fri`, `Fic`) if `include_rivers_and_icebergs` is `true` - +The atmospheric data will be held in `JRA55FieldTimeSeries` objects containing. For a detailed description of the keyword arguments, see the [`JRA55FieldTimeSeries`](@ref) constructor. """ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; From e65b0ea3c384dadb44717e5b5f2e175cbcede474 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 12 Mar 2025 10:45:21 +0100 Subject: [PATCH 039/203] add native date range --- src/DataWrangling/ECCO/ECCO.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/ECCO/ECCO.jl b/src/DataWrangling/ECCO/ECCO.jl index 141cb2462..56a96a437 100644 --- a/src/DataWrangling/ECCO/ECCO.jl +++ b/src/DataWrangling/ECCO/ECCO.jl @@ -7,7 +7,7 @@ export ECCOFieldTimeSeries, ECCORestoring, LinearlyTaperedPolarMask using ClimaOcean using ClimaOcean.DistributedUtils using ClimaOcean.DataWrangling -using ClimaOcean.DataWrangling: inpaint_mask!, NearestNeighborInpainting, download_progress +using ClimaOcean.DataWrangling: inpaint_mask!, NearestNeighborInpainting, download_progress, compute_native_date_range using ClimaOcean.InitialConditions: three_dimensional_regrid!, interpolate! using Oceananigans From 40a9f2465d47b9924bef4a079ab06fada1d81c66 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 13 Mar 2025 09:53:54 +0100 Subject: [PATCH 040/203] change the url --- src/DataWrangling/ECCO/ECCO_metadata.jl | 25 +++++++++++------------ src/DataWrangling/JRA55/JRA55_metadata.jl | 11 ++++------ 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index b4b4f583a..3e3583b78 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -72,14 +72,6 @@ short_name(data::Metadata{<:Any, <:ECCO2Daily}) = ECCO2_short_names[data.name] short_name(data::Metadata{<:Any, <:ECCO2Monthly}) = ECCO2_short_names[data.name] short_name(data::Metadata{<:Any, <:ECCO4Monthly}) = ECCO4_short_names[data.name] -metadata_url(prefix, m::Metadata{<:Any, <:ECCO2Daily}) = prefix * "/" * short_name(m) * "/" * metadata_filename(m) -metadata_url(prefix, m::Metadata{<:Any, <:ECCO2Monthly}) = prefix * "/" * short_name(m) * "/" * metadata_filename(m) - -function metadata_url(prefix, m::Metadata{<:Any, <:ECCO4Monthly}) - year = string(Dates.year(m.dates)) - return prefix * "/" * short_name(m) * "/" * year * "/" * metadata_filename(m) -end - location(data::ECCOMetadata) = ECCO_location[data.name] variable_is_three_dimensional(data::ECCOMetadata) = @@ -121,10 +113,17 @@ ECCO_location = Dict( :v_velocity => (Center, Face, Center), ) +const ECCO2_url = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/" + # URLs for the ECCO datasets specific to each dataset -urls(::Metadata{<:Any, <:ECCO2Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/monthly" -urls(::Metadata{<:Any, <:ECCO2Daily}) = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/daily" -urls(::Metadata{<:Any, <:ECCO4Monthly}) = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly" +metadata_url(m::Metadata{<:Any, <:ECCO2Daily}) = ECCO2_url * "monthly/" * short_name(m) * "/" * metadata_filename(m) +metadata_url(m::Metadata{<:Any, <:ECCO2Monthly}) = ECCO2_url * "daily/" * short_name(m) * "/" * metadata_filename(m) + +function metadata_url(m::Metadata{<:Any, <:ECCO4Monthly}) + year = string(Dates.year(m.dates)) + prefix = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" + return prefix * short_name(m) * "/" * year * "/" * metadata_filename(m) +end """ download_dataset(metadata::ECCOMetadata; url = urls(metadata)) @@ -156,7 +155,7 @@ Arguments ========= - `metadata::ECCOMetadata`: The metadata specifying the dataset to be downloaded. """ -function download_dataset(metadata::ECCOMetadata; url = urls(metadata)) +function download_dataset(metadata::ECCOMetadata) username = get(ENV, "ECCO_USERNAME", nothing) password = get(ENV, "ECCO_PASSWORD", nothing) dir = metadata.dir @@ -173,7 +172,7 @@ function download_dataset(metadata::ECCOMetadata; url = urls(metadata)) asyncmap(metadata; ntasks) do metadatum # Distribute the download among tasks - fileurl = metadata_url(url, metadatum) + fileurl = metadata_url(metadatum) filepath = metadata_path(metadatum) if !isfile(filepath) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 23315ab29..038d4e0d1 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -150,18 +150,15 @@ JRA55_repeat_year_urls = Dict( variable_is_three_dimensional(data::JRA55Metadata) = false -urls(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] +metadata_url(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] # TODO: -# urls(metadata::Metadata{<:Any, <:JRA55MultipleYears}) = ... +# metadata_url(metadata::Metadata{<:Any, <:JRA55MultipleYears}) = ... -metadata_url(prefix, ::Metadata{<:Any, <:JRA55RepeatYear}) = prefix # No specific name for this url - -# TODO: This will need to change when we add a method for JRA55MultipleYears -function download_dataset(metadata::JRA55Metadata; url = urls(metadata)) +function download_dataset(metadata::JRA55Metadata) @root for metadatum in metadata - fileurl = metadata_url(url, metadatum) + fileurl = metadata_url(metadatum) filepath = metadata_path(metadatum) if !isfile(filepath) From 58d5c1102ffb504bfb806b251d2f308b229e8ebb Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 13 Mar 2025 09:59:44 +0100 Subject: [PATCH 041/203] fix tests --- test/test_ecco.jl | 30 ++++++++++++------------------ test/test_jra55.jl | 8 ++++---- test/test_surface_fluxes.jl | 12 ++++++------ 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/test/test_ecco.jl b/test/test_ecco.jl index ed6587564..d81aaba4a 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -60,7 +60,7 @@ end @testset "Inpainting algorithm" begin for arch in test_architectures - T_metadata = Metadata(:temperature; dates=dates[1], dataset=ECCO4Monthly()) + T_metadatum = Metadatum(:temperature; date=start_date, dataset=ECCO4Monthly()) grid = LatitudeLongitudeGrid(arch, size = (100, 100, 10), @@ -72,8 +72,8 @@ end fully_inpainted_field = CenterField(grid) partially_inpainted_field = CenterField(grid) - set!(fully_inpainted_field, T_metadata; inpainting = NearestNeighborInpainting(Inf)) - set!(partially_inpainted_field, T_metadata; inpainting = NearestNeighborInpainting(1)) + set!(fully_inpainted_field, T_metadatum; inpainting = NearestNeighborInpainting(Inf)) + set!(partially_inpainted_field, T_metadatum; inpainting = NearestNeighborInpainting(1)) fully_inpainted_interior = on_architecture(CPU(), interior(fully_inpainted_field)) partially_inpainted_interior = on_architecture(CPU(), interior(partially_inpainted_field)) @@ -102,9 +102,7 @@ end southern = (φ₁, φ₂), z = (z₁, 0)) - T_restoring = ECCORestoring(:temperature, arch; - dates, mask, inpainting, - rate=1/1000) + T_restoring = ECCORestoring(:temperature, arch; start_date, end_date, mask, inpainting, rate=1/1000) fill!(T_restoring.field_time_series[1], 1.0) fill!(T_restoring.field_time_series[2], 1.0) @@ -134,8 +132,8 @@ end field = CenterField(grid) @test begin - set!(field, Metadata(:temperature, dates=start_date, dataset=ECCO4Monthly())) - set!(field, Metadata(:salinity, dates=start_date, dataset=ECCO4Monthly())) + set!(field, Metadatum(:temperature, date=start_date, dataset=ECCO4Monthly())) + set!(field, Metadatum(:salinity, date=start_date, dataset=ECCO4Monthly())) true end end @@ -154,13 +152,12 @@ end field = CenterField(grid) @test begin - set!(field, Metadata(:temperature, dates=start_date, dataset=ECCO4Monthly())) - set!(field, Metadata(:salinity, dates=start_date, dataset=ECCO4Monthly())) + set!(field, Metadatum(:temperature, date=start_date, dataset=ECCO4Monthly())) + set!(field, Metadatum(:salinity, date=start_date, dataset=ECCO4Monthly())) true end - forcing_T = ECCORestoring(:temperature, arch; dates, inpainting, - rate = 1/1000) + forcing_T = ECCORestoring(:temperature, arch; start_date, end_date, inpainting, rate=1/1000) ocean = ocean_simulation(grid; forcing = (; T = forcing_T), verbose=false) @@ -183,8 +180,8 @@ end ocean = ocean_simulation(grid) date = DateTimeProlepticGregorian(1993, 1, 1) - set!(ocean.model, T=Metadata(:temperature; dates=start_date, dataset=ECCO4Monthly()), - S=Metadata(:salinity; dates=start_date, dataset=ECCO4Monthly())) + set!(ocean.model, T=Metadatum(:temperature; date=start_date, dataset=ECCO4Monthly()), + S=Metadatum(:salinity; date=start_date, dataset=ECCO4Monthly())) end end @@ -201,10 +198,7 @@ end end_date = DateTimeProlepticGregorian(1993, 5, 1) dates = start_date : Month(1) : end_date - T_restoring = ECCORestoring(:temperature, arch; - dates, - rate = 1 / 1000.0, - inpainting) + T_restoring = ECCORestoring(:temperature, arch; start_date, end_date, inpainting, rate=1/1000) times = native_times(T_restoring.field_time_series.backend.metadata) ocean = ocean_simulation(grid, forcing = (; T = T_restoring)) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 7222e2e72..4b160f762 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -11,9 +11,9 @@ using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere # This should download files called "RYF.rsds.1990_1991.nc" and "RYF.tas.1990_1991.nc" for test_name in (:downwelling_shortwave_radiation, :temperature) dates = ClimaOcean.DataWrangling.all_dates(JRA55.JRA55RepeatYear(), test_name) - dates = dates[1:3] + end_date = dates[3] - JRA55_fts = JRA55FieldTimeSeries(test_name, arch; dates) + JRA55_fts = JRA55FieldTimeSeries(test_name, arch; end_date) test_filename = joinpath(download_JRA55_cache, "RYF.rsds.1990_1991.nc") @test JRA55_fts isa FieldTimeSeries @@ -60,8 +60,8 @@ using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere name = :downwelling_shortwave_radiation dates = ClimaOcean.DataWrangling.all_dates(JRA55.JRA55RepeatYear(), name) - dates = dates[1:3] - JRA55_fts = JRA55FieldTimeSeries(name, arch; dates) + end_date = dates[3] + JRA55_fts = JRA55FieldTimeSeries(name, arch; end_date) # Make target grid and field resolution = 1 # degree, eg 1/4 diff --git a/test/test_surface_fluxes.jl b/test/test_surface_fluxes.jl index e7ea1f060..f8ba2a862 100644 --- a/test/test_surface_fluxes.jl +++ b/test/test_surface_fluxes.jl @@ -187,8 +187,8 @@ end closure = nothing, bottom_drag_coefficient = 0.0) - dates = all_dates(JRA55RepeatYear(), :temperature)[1:2] - atmosphere = JRA55PrescribedAtmosphere(arch; dates, backend = InMemory()) + dates = all_dates(JRA55RepeatYear(), :temperature) + atmosphere = JRA55PrescribedAtmosphere(arch; end_date=dates[2], backend = InMemory()) fill!(ocean.model.tracers.T, -2.0) @@ -230,13 +230,13 @@ end ocean = ocean_simulation(grid; momentum_advection, tracer_advection, closure, tracers, coriolis) - T_metadata = Metadata(:temperature, dates=DateTimeProlepticGregorian(1993, 1, 1), dataset=ECCO4Monthly()) - S_metadata = Metadata(:salinity, dates=DateTimeProlepticGregorian(1993, 1, 1), dataset=ECCO4Monthly()) + T_metadata = Metadatum(:temperature, date=DateTimeProlepticGregorian(1993, 1, 1), dataset=ECCO4Monthly()) + S_metadata = Metadatum(:salinity, date=DateTimeProlepticGregorian(1993, 1, 1), dataset=ECCO4Monthly()) set!(ocean.model; T=T_metadata, S=S_metadata) - dates = all_dates(JRA55RepeatYear(), :temperature)[1:10] - atmosphere = JRA55PrescribedAtmosphere(arch; dates, backend = InMemory()) + end_date = all_dates(JRA55RepeatYear(), :temperature)[10] + atmosphere = JRA55PrescribedAtmosphere(arch; end_date, backend = InMemory()) radiation = Radiation(ocean_albedo=0.1, ocean_emissivity=1.0) sea_ice = nothing From 4fc23948b8fff0f04477003b0404db334675f9b7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 13 Mar 2025 10:57:47 +0100 Subject: [PATCH 042/203] fixing the tests --- test/test_surface_fluxes.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_surface_fluxes.jl b/test/test_surface_fluxes.jl index f8ba2a862..c2710dcee 100644 --- a/test/test_surface_fluxes.jl +++ b/test/test_surface_fluxes.jl @@ -18,6 +18,9 @@ using Oceananigans.TimeSteppers: update_state! using Oceananigans.Units: hours, days using ClimaOcean.DataWrangling: all_dates +using ClimaSeaIce.SeaIceMomentumEquations +using ClimaSeaIce.Rheologies + import ClimaOcean.OceanSeaIceModels.InterfaceComputations: saturation_specific_humidity using Statistics: mean, std From 385a44ad61cf2fd3f52410a21fcd59b52994b15b Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 13 Mar 2025 14:40:03 +0100 Subject: [PATCH 043/203] fix tests --- test/test_ecco.jl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/test_ecco.jl b/test/test_ecco.jl index d81aaba4a..c91bfef71 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -1,6 +1,5 @@ include("runtests_setup.jl") -using CFTime using Dates using ClimaOcean @@ -15,8 +14,8 @@ using Oceananigans.Units using CUDA: @allowscalar -start_date = DateTimeProlepticGregorian(1993, 1, 1) -end_date = DateTimeProlepticGregorian(1993, 2, 1) +start_date = DateTime(1993, 1, 1) +end_date = DateTime(1993, 2, 1) dates = start_date : Month(1) : end_date # Inpaint only the first two cells inside the missing mask @@ -179,7 +178,7 @@ end halo = (7, 7, 7)) ocean = ocean_simulation(grid) - date = DateTimeProlepticGregorian(1993, 1, 1) + date = DateTime(1993, 1, 1) set!(ocean.model, T=Metadatum(:temperature; date=start_date, dataset=ECCO4Monthly()), S=Metadatum(:salinity; date=start_date, dataset=ECCO4Monthly())) end @@ -194,8 +193,8 @@ end z = (-200, 0), halo = (7, 7, 7)) - start_date = DateTimeProlepticGregorian(1993, 1, 1) - end_date = DateTimeProlepticGregorian(1993, 5, 1) + start_date = DateTime(1993, 1, 1) + end_date = DateTime(1993, 5, 1) dates = start_date : Month(1) : end_date T_restoring = ECCORestoring(:temperature, arch; start_date, end_date, inpainting, rate=1/1000) From 54e583829267c8a16f153530577d097c9cd6bada Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 14 Mar 2025 12:38:53 +0100 Subject: [PATCH 044/203] it's six dates not 5 --- test/test_ecco.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_ecco.jl b/test/test_ecco.jl index c91bfef71..6ff76364f 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -221,7 +221,7 @@ end end # The backend has cycled to the end - @test time_indices(T_restoring.field_time_series) == (5, 1) + @test time_indices(T_restoring.field_time_series) == (6, 1) end end From fb35d7816c72a7d31c7ec59b85a74ee64add031d Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Sat, 15 Mar 2025 10:57:30 +0100 Subject: [PATCH 045/203] this works --- .../JRA55/JRA55_field_time_series.jl | 2 + src/DataWrangling/JRA55/JRA55_metadata.jl | 47 ++++++++++++------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 0f503e88f..4698b3c80 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -3,6 +3,8 @@ using ClimaOcean.DataWrangling: compute_native_date_range using Oceananigans.Grids: AbstractGrid using Oceananigans.OutputReaders: PartlyInMemory +using Adapt + download_JRA55_cache::String = "" function __init__() diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 93f39d882..44187881e 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -25,6 +25,9 @@ default_download_folder(::Union{<:JRA55MultipleYears, <:JRA55RepeatYear}) = down Base.size(data::JRA55Metadata) = (640, 320, length(data.dates)) Base.size(::JRA55Metadatum) = (640, 320, 1) +# JRA55 is a spatially 2D dataset +variable_is_three_dimensional(data::JRA55Metadata) = false + # The whole range of dates in the different dataset datasets # NOTE! rivers and icebergs have a different frequency! (typical JRA55 data is three-hourly while rivers and icebergs are daily) function all_dates(::JRA55RepeatYear, name) @@ -59,22 +62,30 @@ function JRA55_time_indices(dataset, dates, name) end # File name generation specific to each Dataset dataset -function metadata_filename(metadata::Metadata{<:Any, <:JRA55RepeatYear}) # No difference +function metadata_filename(metadata::Metadatum{<:Any, <:JRA55RepeatYear}) # No difference shortname = short_name(metadata) return "RYF." * shortname * ".1990_1991.nc" end -function metadata_filename(metadata::Metadata{<:AbstractCFDateTime, <:JRA55MultipleYears}) +multiple_year_time_displaced_variables = [:rain_freshwater_flux, + :snow_freshwater_flux, + :downwelling_shortwave_radiation, + :downwelling_longwave_radiation] + +function metadata_filename(metadata::Metadatum{<:Any, <:JRA55MultipleYears}) # fix the filename shortname = short_name(metadata) year = Dates.year(metadata.dates) suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" - if shortname == "tas" - dates = "$(year)01010000-$(year)12312100" + if metadata.name ∈ [:river_freshwater_flux, :iceberg_freshwater_flux] + dates = "$(year)0101-$(year)1231" + elseif metadata.name ∈ multiple_year_time_displaced_variables + dates = "$(year)01010130-$(year)12312230" else - dates = "$(year)01010130-$(year)12312330" + dates = "$(year)01010000-$(year)12312100" end + return shortname * suffix * dates * ".nc" end @@ -89,7 +100,6 @@ JRA55_variable_names = (:river_freshwater_flux, :iceberg_freshwater_flux, :specific_humidity, :sea_level_pressure, - :relative_humidity, :downwelling_longwave_radiation, :downwelling_shortwave_radiation, :temperature, @@ -103,7 +113,6 @@ JRA55_short_names = Dict( :iceberg_freshwater_flux => "licalvf", # Freshwater flux from calving icebergs :specific_humidity => "huss", # Surface specific humidity :sea_level_pressure => "psl", # Sea level pressure - :relative_humidity => "rhuss", # Surface relative humidity :downwelling_longwave_radiation => "rlds", # Downwelling longwave radiation :downwelling_shortwave_radiation => "rsds", # Downwelling shortwave radiation :temperature => "tas", # Near-surface air temperature @@ -133,9 +142,6 @@ JRA55_repeat_year_urls = Dict( :sea_level_pressure => "https://www.dropbox.com/scl/fi/0fk332027oru1iiseykgp/" * "RYF.psl.1990_1991.nc?rlkey=4xpr9uah741483aukok6d7ctt&dl=0", - :relative_humidity => "https://www.dropbox.com/scl/fi/1agwsp0lzvntuyf8bm9la/" * - "RYF.rhuss.1990_1991.nc?rlkey=8cd0vs7iy1rw58b9pc9t68gtz&dl=0", - :downwelling_longwave_radiation => "https://www.dropbox.com/scl/fi/y6r62szkirrivua5nqq61/" * "RYF.rlds.1990_1991.nc?rlkey=wt9yq3cyrvs2rbowoirf4nkum&dl=0", @@ -152,19 +158,24 @@ JRA55_repeat_year_urls = Dict( "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", ) -variable_is_three_dimensional(data::JRA55Metadata) = false - metadata_url(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] -function url(metadata::Metadata{<:Any, <:JRA55MultipleYears}) - if metadata.name isa String - return "https://esgf-data2.llnl.gov/thredds/fileServer/user_pub_work/input4MIPs/CMIP6/OMIP/MRI/MRI-JRA55-do-1-5-0/atmos/3hrPt" +const JRA55_multiple_year_url = "https://esgf-data2.llnl.gov/thredds/fileServer/user_pub_work/input4MIPs/CMIP6/OMIP/MRI/MRI-JRA55-do-1-5-0/" + +function metadata_url(m::Metadata{<:Any, <:JRA55MultipleYears}) + + if m.name == :iceberg_freshwater_flux + url = JRA55_multiple_year_url * "landIce/day" + elseif m.name == :river_freshwater_flux + url = JRA55_multiple_year_url * "land/day" + elseif m.name ∈ multiple_year_time_displaced_variables + url = JRA55_multiple_year_url * "atmos/3hr" else - return "https://esgf-data2.llnl.gov/thredds/fileServer/user_pub_work/input4MIPs/CMIP6/OMIP/MRI/MRI-JRA55-do-1-5-0/atmos/3hrPt" + url = JRA55_multiple_year_url * "atmos/3hrPt" end -end -metadata_url(prefix, m::Metadata{<:Any, <:JRA55MultipleYears}) = url(metadata) * "/" * short_name(m) * "/gr/v20200916/" * metadata_filename(m) + return url * "/" * short_name(m) * "/gr/v20200916/" * metadata_filename(m) +end function download_dataset(metadata::JRA55Metadata) From 65ca9ba519aa75436f45fdc830f040fc339af04a Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Sat, 15 Mar 2025 11:04:40 +0100 Subject: [PATCH 046/203] this works --- src/DataWrangling/JRA55/JRA55_metadata.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 44187881e..7a861f055 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -40,9 +40,11 @@ end function all_dates(::JRA55MultipleYears, name) if name == :river_freshwater_flux || name == :iceberg_freshwater_flux - return DateTime(1958, 1, 1) : Day(1) : DateTime(2021, 1, 1) + return DateTime(1958, 1, 1) : Day(1) : DateTime(2021, 12, 31) + elseif name ∈ multiple_year_time_displaced_variables + return DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30) else - return DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 1, 1) + return DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21) end end From 18504c514e6044135bed55daf08b59fd8c7ab4b7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Sat, 15 Mar 2025 12:03:11 +0100 Subject: [PATCH 047/203] this should work --- .../JRA55/JRA55_field_time_series.jl | 22 +++++++++---------- src/DataWrangling/metadata.jl | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 4698b3c80..d93e6f983 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -103,9 +103,12 @@ function set!(fts::JRA55NetCDFFTS) backend = fts.backend metadata = backend.metadata - filepath = metadata_path(metadata) - - for path in filepath + filename = metadata_filename(metadata) + filename = unique(filename) + + for name in filename + + path = joinpath(metadata.dir, name) ds = Dataset(path) # Note that each file should have the variables @@ -347,16 +350,13 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl path = filepath, name = shortname) - # Fill the data in a GPU-friendly manner - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) - + set!(fts) return fts else - native_fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - time_indexing, - backend, - boundary_conditions) + fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + time_indexing, + backend, + boundary_conditions) # Fill the data in a GPU-friendly manner copyto!(interior(native_fts, :, :, 1, :), data) diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 0de805f35..3a60b4df4 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -169,10 +169,10 @@ function compute_native_date_range(native_dates, start_date, end_date) end start_idx = findfirst(x -> x ≥ start_date, native_dates) - end_idx = findfirst(x -> x ≥ end_date, native_dates) + end_idx = findfirst(x -> x ≥ end_date, native_dates) start_idx = start_idx > 1 ? start_idx - 1 : start_idx - end_idx = isnothing(end_idx) ? length(native_dates) : end_idx + end_idx = isnothing(end_idx) ? length(native_dates) : end_idx return native_dates[start_idx:end_idx] end From f35345c01ae1bf680980cbef258b74c8d8962ae2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Sat, 15 Mar 2025 12:05:07 +0100 Subject: [PATCH 048/203] done --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index d93e6f983..69174aea9 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -95,10 +95,12 @@ JRA55NetCDFBackend(length, metadata) = JRA55NetCDFBackend(1, length, metadata) Base.length(backend::JRA55NetCDFBackend) = backend.length Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") -const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} +const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} +const JRA55NetCDFFTSRepeatYear = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:JRA55RepeatYear}} +const JRA55NetCDFFTSMultipleYears = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:JRA55NetCDFFTSMultipleYears}} # TODO: This will need to change when we add a method for JRA55MultipleYears -function set!(fts::JRA55NetCDFFTS) +function set!(fts::JRA55NetCDFFTSMultipleYears) backend = fts.backend metadata = backend.metadata From 182cbfb6eae1504803dc67009efe28a065afdf3e Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sun, 16 Mar 2025 13:41:57 +1100 Subject: [PATCH 049/203] use directory over folder; fix some docstrings --- src/DataWrangling/ECCO/ECCO_metadata.jl | 22 +++++----- src/DataWrangling/JRA55/JRA55_metadata.jl | 20 ++++----- src/DataWrangling/metadata.jl | 51 +++++++++++------------ 3 files changed, 46 insertions(+), 47 deletions(-) diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index f7d22dbd7..127e7239f 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -9,7 +9,7 @@ using Downloads import Oceananigans.Fields: set!, location import Base -import ClimaOcean.DataWrangling: all_dates, metadata_filename, default_download_folder +import ClimaOcean.DataWrangling: all_dates, metadata_filename, default_download_directory struct ECCO2Monthly end struct ECCO2Daily end @@ -18,7 +18,7 @@ struct ECCO4Monthly end const ECCOMetadata{D} = Metadata{D, <:Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}} where {D} const ECCOMetadatum = ECCOMetadata{<:AnyDateTime} -default_download_folder(::Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}) = download_ECCO_cache +default_download_directory(::Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}) = download_ECCO_cache datasetstr(md::ECCOMetadata) = string(md.dataset) @@ -41,7 +41,7 @@ all_dates(::ECCO4Monthly, name) = DateTime(1992, 1, 1) : Month(1) : DateTime(202 all_dates(::ECCO2Monthly, name) = DateTime(1992, 1, 1) : Month(1) : DateTime(2023, 12, 1) all_dates(::ECCO2Daily, name) = DateTime(1992, 1, 4) : Day(1) : DateTime(2023, 12, 31) -# Fallback, actually, we do not really need the name for ECCO since all +# Fallback, actually, we do not really need the name for ECCO since all # variables have the same frequency and the same time-range, differently from JRA55 all_dates(dataset::Union{<:ECCO4Monthly, <:ECCO2Monthly, <:ECCO2Daily}) = all_dates(dataset, :temperature) @@ -59,7 +59,7 @@ function metadata_filename(metadata::Metadata{<:AnyDateTime, <:Union{ECCO2Daily, monthstr = string(Dates.month(metadata.dates), pad=2) postfix = variable_is_three_dimensional(metadata) ? ".1440x720x50." : ".1440x720." - if metadata.dataset isa ECCO2Monthly + if metadata.dataset isa ECCO2Monthly return shortname * postfix * yearstr * monthstr * ".nc" elseif metadata.dataset isa ECCO2Daily daystr = string(Dates.day(metadata.dates), pad=2) @@ -75,8 +75,8 @@ short_name(data::Metadata{<:Any, <:ECCO4Monthly}) = ECCO4_short_names[data.name] location(data::ECCOMetadata) = ECCO_location[data.name] variable_is_three_dimensional(data::ECCOMetadata) = - data.name == :temperature || - data.name == :salinity || + data.name == :temperature || + data.name == :salinity || data.name == :u_velocity || data.name == :v_velocity @@ -128,13 +128,13 @@ end """ download_dataset(metadata::ECCOMetadata; url = urls(metadata)) -Download the dataset specified by `ECCOMetadata`. If `ECCOMetadata.dates` is a single date, -the dataset is downloaded directly. If `ECCOMetadata.dates` is a vector of dates, each date +Download the dataset specified by the `metadata::ECCOMetadata`. If `metadata.dates` is a single date, +the dataset is downloaded directly. If `metadata.dates` is a vector of dates, each date is downloaded individually. The data download requires a username and password to be provided in the `ECCO_USERNAME` and -`ECCO_PASSWORD` environment variables. This can be done by exporting the environment variables -in the shell before running the script, or by launching julia with +`ECCO_PASSWORD` environment variables respectively. This can be done by exporting the +environment variables in the shell before running the script, or by launching julia with ``` ECCO_USERNAME=myusername ECCO_PASSWORD=mypassword julia @@ -170,7 +170,7 @@ function download_dataset(metadata::ECCOMetadata) asyncmap(metadata; ntasks) do metadatum # Distribute the download among tasks - fileurl = metadata_url(metadatum) + fileurl = metadata_url(metadatum) filepath = metadata_path(metadatum) if !isfile(filepath) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 038d4e0d1..ab17c094b 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -12,7 +12,7 @@ import Oceananigans.Fields: set! import Base import Oceananigans.Fields: set!, location -import ClimaOcean.DataWrangling: all_dates, metadata_filename, default_download_folder +import ClimaOcean.DataWrangling: all_dates, metadata_filename, default_download_directory struct JRA55MultipleYears end struct JRA55RepeatYear end @@ -20,14 +20,14 @@ struct JRA55RepeatYear end const JRA55Metadata{D} = Metadata{D, <:Union{<:JRA55MultipleYears, <:JRA55RepeatYear}} where {D} const JRA55Metadatum = JRA55Metadata{<:AnyDateTime} -default_download_folder(::Union{<:JRA55MultipleYears, <:JRA55RepeatYear}) = download_JRA55_cache +default_download_directory(::Union{<:JRA55MultipleYears, <:JRA55RepeatYear}) = download_JRA55_cache Base.size(data::JRA55Metadata) = (640, 320, length(data.dates)) Base.size(::JRA55Metadatum) = (640, 320, 1) # The whole range of dates in the different dataset datasets # NOTE! rivers and icebergs have a different frequency! (typical JRA55 data is three-hourly while rivers and icebergs are daily) -function all_dates(::JRA55RepeatYear, name) +function all_dates(::JRA55RepeatYear, name) if name == :river_freshwater_flux || name == :iceberg_freshwater_flux return DateTime(1990, 1, 1) : Day(1) : DateTime(1990, 12, 31) else @@ -43,13 +43,13 @@ function all_dates(::JRA55MultipleYears, name) end end -# Fallback, if we not provide the name, take the highest frequency +# Fallback, if we not provide the name, take the highest frequency all_dates(dataset::Union{<:JRA55MultipleYears, <:JRA55RepeatYear}) = all_dates(dataset, :temperature) function JRA55_time_indices(dataset, dates, name) all_JRA55_dates = all_dates(dataset, name) indices = Int[] - + for date in dates index = findfirst(x -> x == date, all_JRA55_dates) !isnothing(index) && push!(indices, index) @@ -59,7 +59,7 @@ function JRA55_time_indices(dataset, dates, name) end # File name generation specific to each Dataset dataset -function metadata_filename(metadata::Metadata{<:Any, <:JRA55RepeatYear}) # No difference +function metadata_filename(metadata::Metadata{<:Any, <:JRA55RepeatYear}) # No difference shortname = short_name(metadata) return "RYF." * shortname * ".1990_1991.nc" end @@ -111,7 +111,7 @@ JRA55_repeat_year_urls = Dict( :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", - :river_freshwater_flux => "https://www.dropbox.com/scl/fi/21ggl4p74k4zvbf04nb67/" * + :river_freshwater_flux => "https://www.dropbox.com/scl/fi/21ggl4p74k4zvbf04nb67/" * "RYF.friver.1990_1991.nc?rlkey=ny2qcjkk1cfijmwyqxsfm68fz&dl=0", :rain_freshwater_flux => "https://www.dropbox.com/scl/fi/5icl1gbd7f5hvyn656kjq/" * @@ -150,15 +150,15 @@ JRA55_repeat_year_urls = Dict( variable_is_three_dimensional(data::JRA55Metadata) = false -metadata_url(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] -# TODO: +metadata_url(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] +# TODO: # metadata_url(metadata::Metadata{<:Any, <:JRA55MultipleYears}) = ... function download_dataset(metadata::JRA55Metadata) @root for metadatum in metadata - fileurl = metadata_url(metadatum) + fileurl = metadata_url(metadatum) filepath = metadata_path(metadatum) if !isfile(filepath) diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 0de805f35..60837f4ad 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -2,7 +2,7 @@ using CFTime using Dates using Base: @propagate_inbounds -struct Metadata{D, V} +struct Metadata{D, V} name :: Symbol dates :: D dataset :: V @@ -13,26 +13,27 @@ end Metadata(variable_name; dataset, dates = all_dates(dataset, variable_name), - dir = default_download_folder(dataset)) + dir = default_download_directory(dataset)) Metadata holding a specific dataset information. Arguments ========= -- `variable_name`: a symbol representing the name of the variable (for example :temperature, :salinity, :u_velocity, etc...) +- `variable_name`: a symbol representing the name of the variable (for example, `:temperature`, + `:salinity`, `:u_velocity`, etc) Keyword Arguments ================= -- `dates`: The dates of the dataset, in a `AbstractCFDateTime` format.. Note this can either be a range or a vector of dates, - representing a time-series. For a single date, use the [`Metadatum`](@ref) constructor . -- `dataset`: The dataset of the dataset. Supported datasets are `ECCO2Monthly()`, `ECCO2Daily()`, `ECCO4Monthly()`, - `JRA55RepeatYear()`, or `JRA55MultipleYears()`. +- `dataset`: The dataset of the dataset. Supported datasets are `ECCO2Monthly()`, `ECCO2Daily()`, + `ECCO4Monthly()`, `JRA55RepeatYear()`, or `JRA55MultipleYears()`. +- `dates`: The dates of the dataset, in a `AbstractCFDateTime` format. Note this can either be a range + or a vector of dates, representing a time-series. For a single date, use [`Metadatum`](@ref). - `dir`: The directory where the dataset is stored. """ function Metadata(variable_name; dataset, dates=all_dates(dataset, variable_name)[1:1], - dir=default_download_folder(dataset)) + dir=default_download_directory(dataset)) return Metadata(variable_name, dates, dataset, dir) end @@ -42,23 +43,25 @@ const Metadatum = Metadata{<:AnyDateTime} """ Metadatum(variable_name; - dataset, - date=first_date(dataset, variable_name), - dir=default_download_folder(dataset)) + dataset, + date=first_date(dataset, variable_name), + dir=default_download_directory(dataset)) -Specific constructor for a `Metadata` object with a single date, representative of a snapshot in time. +A specialized constructor for a [`Metadata`](@ref) object with a single date, representative of a snapshot in time. """ function Metadatum(variable_name; dataset, date=first_date(dataset, variable_name), - dir=default_download_folder(dataset)) + dir=default_download_directory(dataset)) + + # TODO: validate that `date` is actually a single date? return Metadata(variable_name, date, dataset, dir) end -default_download_folder(dataset) = "./" +default_download_directory(dataset) = "./" -Base.show(io::IO, metadata::Metadata) = +Base.show(io::IO, metadata::Metadata) = print(io, "ECCOMetadata:", '\n', "├── name: $(metadata.name)", '\n', "├── dates: $(metadata.dates)", '\n', @@ -94,19 +97,15 @@ Base.iterate(::Metadatum, ::Any) = nothing metadata_path(metadata) = joinpath(metadata.dir, metadata_filename(metadata)) """ - native_times(metadata; start_time = first(metadata).dates) + native_times(metadata; start_time=first(metadata).dates) -Extract the time values from the given metadata and calculates the time difference -from the start time. +Extract the time values from the given `metadata` and calculate the time difference +from the `start_time` and return as an array of time differences in seconds. Arguments ========= - `metadata`: The metadata containing the date information. - `start_time`: The start time for calculating the time difference. Defaults to the first date in the metadata. - -Returns -======= -An array of time differences in seconds. """ function native_times(metadata; start_time=first(metadata).dates) times = zeros(length(metadata)) @@ -127,8 +126,8 @@ end """ all_dates(metadata) -Extracts all the dates of the given metadata formatted using the `DateTime` type. -Needs to be extended by any new dataset dataset. +Extract all the dates of the given `metadata` formatted using the `DateTime` type. +Note: This methods needs to be extended for any new dataset. """ all_dates(metadata) = all_dates(metadata.dataset, metadata.name) @@ -149,7 +148,7 @@ last_date(dataset, variable_name) = last(all_dates(dataset, variable_name)) """ metadata_filename(metadata) -File names of metadata containing multiple dates. The specific version for a `Metadatum` object is +File names of metadata containing multiple dates. The specific version for a `Metadatum` object is extended in the data specific modules. """ metadata_filename(metadata) = [metadata_filename(metadatum) for metadatum in metadata] @@ -170,7 +169,7 @@ function compute_native_date_range(native_dates, start_date, end_date) start_idx = findfirst(x -> x ≥ start_date, native_dates) end_idx = findfirst(x -> x ≥ end_date, native_dates) - + start_idx = start_idx > 1 ? start_idx - 1 : start_idx end_idx = isnothing(end_idx) ? length(native_dates) : end_idx From f42a18780f4e91534ca8bf651fe9289f065d69a1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 17 Mar 2025 22:17:28 +0100 Subject: [PATCH 050/203] add an ECCOMetadatum --- examples/generate_surface_fluxes.jl | 4 ++-- examples/mediterranean_simulation_with_ecco_restoring.jl | 4 ++-- examples/near_global_ocean_simulation.jl | 7 +++---- examples/single_column_os_papa_simulation.jl | 4 ++-- src/ClimaOcean.jl | 1 + src/DataWrangling/DataWrangling.jl | 2 +- src/DataWrangling/ECCO/ECCO.jl | 2 +- src/DataWrangling/ECCO/ECCO_metadata.jl | 8 ++++++++ 8 files changed, 20 insertions(+), 12 deletions(-) diff --git a/examples/generate_surface_fluxes.jl b/examples/generate_surface_fluxes.jl index 7ef0087c4..9b6d8b960 100644 --- a/examples/generate_surface_fluxes.jl +++ b/examples/generate_surface_fluxes.jl @@ -52,8 +52,8 @@ ocean = ocean_simulation(grid, closure=nothing) # Now that we have an atmosphere and ocean, we `set!` the ocean temperature and salinity # to the ECCO2 data by first creating T, S metadata objects, -T_metadata = Metadatum(:temperature; date=DateTime(1993, 1, 1), dataset=ECCO4Monthly()) -S_metadata = Metadatum(:salinity; date=DateTime(1993, 1, 1), dataset=ECCO4Monthly()) +T_metadata = ECCOMetadatum(:temperature; date=DateTime(1993, 1, 1)) +S_metadata = ECCOMetadatum(:salinity; date=DateTime(1993, 1, 1)) # Note that if a date is not provided to `Metadata`, then the default Jan 1st, 1992 is used. # To copy the ECCO state into `ocean.model`, we use `set!`, diff --git a/examples/mediterranean_simulation_with_ecco_restoring.jl b/examples/mediterranean_simulation_with_ecco_restoring.jl index 665675402..c82209b40 100644 --- a/examples/mediterranean_simulation_with_ecco_restoring.jl +++ b/examples/mediterranean_simulation_with_ecco_restoring.jl @@ -90,8 +90,8 @@ ocean = ocean_simulation(grid; forcing = (T = FT, S = FS)) # In this case, our ECCO dataset has access to a temperature and a salinity # field, so we initialize temperature T and salinity S from ECCO. -set!(ocean.model, T = Metadatum(:temperature; date=start_date), - S = Metadatum(:salinity; date=start_date)) +set!(ocean.model, T = ECCOMetadatum(:temperature; date=start_date), + S = ECCOMetadatum(:salinity; date=start_date)) fig = Figure() ax = Axis(fig[1, 1]) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index ec45a3144..3a3e8144a 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -81,11 +81,10 @@ ocean = ocean_simulation(grid) ocean.model -# We initialize the ocean model with ECCO2 temperature and salinity for January 1, 1993. +# We initialize the ocean model with ECCO4 temperature and salinity for January 1, 1992. -date = DateTimeProlepticGregorian(1993, 1, 1) -set!(ocean.model, T=Metadatum(:temperature; date, dataset=ECCO4Monthly()), - S=Metadatum(:salinity; date, dataset=ECCO4Monthly())) +set!(ocean.model, T=ECCOMetadatum(:temperature), + S=ECCOMetadatum(:salinity)) # ### Prescribed atmosphere and radiation # diff --git a/examples/single_column_os_papa_simulation.jl b/examples/single_column_os_papa_simulation.jl index dc19b52fe..70b029009 100644 --- a/examples/single_column_os_papa_simulation.jl +++ b/examples/single_column_os_papa_simulation.jl @@ -51,8 +51,8 @@ ocean.model # We set initial conditions from ECCO: -set!(ocean.model, T=Metadatum(:temperature), - S=Metadatum(:salinity)) +set!(ocean.model, T=ECCOMetadatum(:temperature), + S=ECCOMetadatum(:salinity)) # # A prescribed atmosphere based on JRA55 re-analysis # diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 7de4a473b..a86f1b093 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -26,6 +26,7 @@ export exponential_z_faces, Metadata, Metadatum, + ECCOMetadatum, first_date, last_date, all_dates, diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index d7024ae4f..dd66b2878 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -1,6 +1,6 @@ module DataWrangling -export Metadata, Metadatum, all_dates, first_date, last_date +export Metadata, Metadatum, ECCOMetadatum, all_dates, first_date, last_date using Oceananigans using Downloads diff --git a/src/DataWrangling/ECCO/ECCO.jl b/src/DataWrangling/ECCO/ECCO.jl index 9437a54ed..2e15720aa 100644 --- a/src/DataWrangling/ECCO/ECCO.jl +++ b/src/DataWrangling/ECCO/ECCO.jl @@ -1,6 +1,6 @@ module ECCO -export ECCOMetadata, ECCO_field, ECCO_mask, ECCO_immersed_grid, adjusted_ECCO_tracers, initialize! +export ECCOMetadatum, ECCO_field, ECCO_mask, ECCO_immersed_grid, adjusted_ECCO_tracers, initialize! export ECCO2Monthly, ECCO4Monthly, ECCO2Daily export ECCOFieldTimeSeries, ECCORestoring, LinearlyTaperedPolarMask diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index 3e3583b78..a59b2df6d 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -18,6 +18,14 @@ struct ECCO4Monthly end const ECCOMetadata{D} = Metadata{D, <:Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}} where {D} const ECCOMetadatum = ECCOMetadata{<:AnyDateTime} +# Alias for ECCOMetadatum +function ECCOMetadatum(name; + date=first_date(ECCO4Monthly(), variable_name), + dir=download_ECCO_cache) + + return ECCOMetadatum(name, dates, dir, ECCO2Monthly()) +end + default_download_folder(::Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}) = download_ECCO_cache datasetstr(md::ECCOMetadata) = string(md.dataset) From 790b5e69488ae1a3761dc3bc30a51e7e0ac21a08 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 17 Mar 2025 22:18:30 +0100 Subject: [PATCH 051/203] spacing --- src/DataWrangling/metadata.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 60837f4ad..f8b7f7161 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -55,7 +55,6 @@ function Metadatum(variable_name; dir=default_download_directory(dataset)) # TODO: validate that `date` is actually a single date? - return Metadata(variable_name, date, dataset, dir) end From 16493538f4c70d2f5540c8b26d6e79dc5cb87a03 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 17 Mar 2025 22:19:42 +0100 Subject: [PATCH 052/203] add a top level constant --- src/DataWrangling/ECCO/ECCO_metadata.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index 127e7239f..c61a4203c 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -18,6 +18,9 @@ struct ECCO4Monthly end const ECCOMetadata{D} = Metadata{D, <:Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}} where {D} const ECCOMetadatum = ECCOMetadata{<:AnyDateTime} +const ECCO2_url = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/" +const ECCO4_url = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" + default_download_directory(::Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}) = download_ECCO_cache datasetstr(md::ECCOMetadata) = string(md.dataset) @@ -113,16 +116,13 @@ ECCO_location = Dict( :v_velocity => (Center, Face, Center), ) -const ECCO2_url = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/" - # URLs for the ECCO datasets specific to each dataset metadata_url(m::Metadata{<:Any, <:ECCO2Daily}) = ECCO2_url * "monthly/" * short_name(m) * "/" * metadata_filename(m) metadata_url(m::Metadata{<:Any, <:ECCO2Monthly}) = ECCO2_url * "daily/" * short_name(m) * "/" * metadata_filename(m) function metadata_url(m::Metadata{<:Any, <:ECCO4Monthly}) year = string(Dates.year(m.dates)) - prefix = "https://ecco.jpl.nasa.gov/drive/files/Version4/Release4/interp_monthly/" - return prefix * short_name(m) * "/" * year * "/" * metadata_filename(m) + return ECCO4_url * short_name(m) * "/" * year * "/" * metadata_filename(m) end """ @@ -174,7 +174,6 @@ function download_dataset(metadata::ECCOMetadata) filepath = metadata_path(metadatum) if !isfile(filepath) - missing_files = true instructions_msg = "\n See ClimaOcean.jl/src/DataWrangling/ECCO/README.md for instructions." if isnothing(username) msg = "Could not find the ECCO_PASSWORD environment variable. \ From 739bc46a6d0d59ac1fbcb9899509e7c89e08c1a6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 17 Mar 2025 22:24:07 +0100 Subject: [PATCH 053/203] correct directory --- src/DataWrangling/ECCO/ECCO_metadata.jl | 2 +- src/DataWrangling/JRA55/JRA55.jl | 6 ++++++ src/DataWrangling/JRA55/JRA55_field_time_series.jl | 6 ------ src/DataWrangling/JRA55/JRA55_metadata.jl | 2 +- src/DataWrangling/metadata.jl | 3 ++- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index c61a4203c..e7479ae33 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -9,7 +9,7 @@ using Downloads import Oceananigans.Fields: set!, location import Base -import ClimaOcean.DataWrangling: all_dates, metadata_filename, default_download_directory +import ClimaOcean.DataWrangling: all_dates, metadata_filename, download_dataset, default_download_directory struct ECCO2Monthly end struct ECCO2Daily end diff --git a/src/DataWrangling/JRA55/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl index b88d8e0bc..48a3d365a 100644 --- a/src/DataWrangling/JRA55/JRA55.jl +++ b/src/DataWrangling/JRA55/JRA55.jl @@ -30,6 +30,12 @@ import Oceananigans.Fields: set! import Oceananigans.OutputReaders: new_backend, update_field_time_series! using Downloads: download +download_JRA55_cache::String = "" + +function __init__() + global download_JRA55_cache = @get_scratch!("JRA55") +end + include("JRA55_metadata.jl") include("JRA55_field_time_series.jl") include("JRA55_prescribed_atmosphere.jl") diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 8c9287742..e1b4654b7 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -3,12 +3,6 @@ using ClimaOcean.DataWrangling: compute_native_date_range using Oceananigans.Grids: AbstractGrid using Oceananigans.OutputReaders: PartlyInMemory -download_JRA55_cache::String = "" - -function __init__() - global download_JRA55_cache = @get_scratch!("JRA55") -end - compute_bounding_nodes(::Nothing, ::Nothing, LH, hnodes) = nothing compute_bounding_nodes(bounds, ::Nothing, LH, hnodes) = bounds diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index ab17c094b..f381bc942 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -12,7 +12,7 @@ import Oceananigans.Fields: set! import Base import Oceananigans.Fields: set!, location -import ClimaOcean.DataWrangling: all_dates, metadata_filename, default_download_directory +import ClimaOcean.DataWrangling: all_dates, metadata_filename, download_dataset, default_download_directory struct JRA55MultipleYears end struct JRA55RepeatYear end diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index f8b7f7161..fc2298f0e 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -58,7 +58,8 @@ function Metadatum(variable_name; return Metadata(variable_name, date, dataset, dir) end -default_download_directory(dataset) = "./" +# Just the current directory +default_download_directory(dataset) = pwd() Base.show(io::IO, metadata::Metadata) = print(io, "ECCOMetadata:", '\n', From 6ef9d7c58e3721dae6bc9ef71b1782c93ac34e39 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 17 Mar 2025 22:25:18 +0100 Subject: [PATCH 054/203] add a default dowbload --- src/DataWrangling/metadata.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index fc2298f0e..8be319dd0 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -61,6 +61,9 @@ end # Just the current directory default_download_directory(dataset) = pwd() +# Default download function for a metadata object, to be extended by each dataset +download_dataset(metadata) = nothing + Base.show(io::IO, metadata::Metadata) = print(io, "ECCOMetadata:", '\n', "├── name: $(metadata.name)", '\n', From 4e53f825514903bf12a255ea3ee1ea1e61da6d37 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 17 Mar 2025 22:38:21 +0100 Subject: [PATCH 055/203] almost there --- src/DataWrangling/JRA55/JRA55_metadata.jl | 66 ++++++++++++++--------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 194dc841d..3c5a368b3 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -38,19 +38,12 @@ function all_dates(::JRA55RepeatYear, name) end end -function all_dates(::JRA55MultipleYears, name) - if name == :river_freshwater_flux || name == :iceberg_freshwater_flux - return DateTime(1958, 1, 1) : Day(1) : DateTime(2021, 12, 31) - elseif name ∈ multiple_year_time_displaced_variables - return DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30) - else - return DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21) - end -end +all_dates(::JRA55MultipleYears, name) = JRA55_multiple_years_dates[name] # Fallback, if we not provide the name, take the highest frequency all_dates(dataset::Union{<:JRA55MultipleYears, <:JRA55RepeatYear}) = all_dates(dataset, :temperature) +# Valid for all JRA55 datasets function JRA55_time_indices(dataset, dates, name) all_JRA55_dates = all_dates(dataset, name) indices = Int[] @@ -79,10 +72,13 @@ function metadata_filename(metadata::Metadatum{<:Any, <:JRA55MultipleYears}) shortname = short_name(metadata) year = Dates.year(metadata.dates) suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" - + if metadata.name ∈ [:river_freshwater_flux, :iceberg_freshwater_flux] dates = "$(year)0101-$(year)1231" - elseif metadata.name ∈ multiple_year_time_displaced_variables + elseif metadata.name ∈ [:rain_freshwater_flux, + :snow_freshwater_flux, + :downwelling_shortwave_radiation, + :downwelling_longwave_radiation] dates = "$(year)01010130-$(year)12312230" else dates = "$(year)01010000-$(year)12312100" @@ -93,7 +89,7 @@ end # Convenience functions short_name(data::JRA55Metadata) = JRA55_short_names[data.name] -location(::JRA55Metadata) = (Center, Center, Center) +location(::JRA55Metadata) = (Center, Center, Center) # A list of all variables provided in the JRA55 dataset: JRA55_variable_names = (:river_freshwater_flux, @@ -122,6 +118,36 @@ JRA55_short_names = Dict( :northward_velocity => "vas", # Northward near-surface wind ) +JRA55_multiple_year_url = "https://esgf-data2.llnl.gov/thredds/fileServer/user_pub_work/input4MIPs/CMIP6/OMIP/MRI/MRI-JRA55-do-1-5-0/" + +JRA55_multiple_year_prefix = Dict( + :river_freshwater_flux => "land/day", + :rain_freshwater_flux => "atmos/3hr", + :snow_freshwater_flux => "atmos/3hr", + :iceberg_freshwater_flux => "landIce/day", + :specific_humidity => "atmos/3hrPt", + :sea_level_pressure => "atmos/3hrPt", + :downwelling_longwave_radiation => "atmos/3hr", + :downwelling_shortwave_radiation => "atmos/3hr", + :temperature => "atmos/3hrPt", + :eastward_velocity => "atmos/3hrPt", + :northward_velocity => "atmos/3hrPt", +) + +JRA55_multiple_year_dates = Dict( + :river_freshwater_flux => DateTime(1958, 1, 1) : Day(1) : DateTime(2021, 12, 31), + :rain_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30) + :snow_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30) + :iceberg_freshwater_flux => DateTime(1958, 1, 1) : Day(1) : DateTime(2021, 12, 31), + :specific_humidity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), + :sea_level_pressure => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), + :downwelling_longwave_radiation => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30), + :downwelling_shortwave_radiation => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30), + :temperature => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), + :eastward_velocity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), + :northward_velocity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21) +) + JRA55_repeat_year_urls = Dict( :shortwave_radiation => "https://www.dropbox.com/scl/fi/z6fkvmd9oe3ycmaxta131/" * "RYF.rsds.1990_1991.nc?rlkey=r7q6zcbj6a4fxsq0f8th7c4tc&dl=0", @@ -162,21 +188,9 @@ JRA55_repeat_year_urls = Dict( metadata_url(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] -const JRA55_multiple_year_url = "https://esgf-data2.llnl.gov/thredds/fileServer/user_pub_work/input4MIPs/CMIP6/OMIP/MRI/MRI-JRA55-do-1-5-0/" - function metadata_url(m::Metadata{<:Any, <:JRA55MultipleYears}) - - if m.name == :iceberg_freshwater_flux - url = JRA55_multiple_year_url * "landIce/day" - elseif m.name == :river_freshwater_flux - url = JRA55_multiple_year_url * "land/day" - elseif m.name ∈ multiple_year_time_displaced_variables - url = JRA55_multiple_year_url * "atmos/3hr" - else - url = JRA55_multiple_year_url * "atmos/3hrPt" - end - - return url * "/" * short_name(m) * "/gr/v20200916/" * metadata_filename(m) + prefix = JRA55_multiple_year_prefix[m.name] + return url * prefix * "/" * short_name(m) * "/gr/v20200916/" * metadata_filename(m) end function download_dataset(metadata::JRA55Metadata) From 418fa995782c4b1926c4529df6fc97db53b04631 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 21 Mar 2025 18:30:35 +0100 Subject: [PATCH 056/203] revert test ecco --- test/test_ecco.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/test_ecco.jl b/test/test_ecco.jl index 6ff76364f..6096cbc27 100644 --- a/test/test_ecco.jl +++ b/test/test_ecco.jl @@ -59,7 +59,7 @@ end @testset "Inpainting algorithm" begin for arch in test_architectures - T_metadatum = Metadatum(:temperature; date=start_date, dataset=ECCO4Monthly()) + T_metadatum = ECCOMetadatum(:temperature; date=start_date) grid = LatitudeLongitudeGrid(arch, size = (100, 100, 10), @@ -131,8 +131,8 @@ end field = CenterField(grid) @test begin - set!(field, Metadatum(:temperature, date=start_date, dataset=ECCO4Monthly())) - set!(field, Metadatum(:salinity, date=start_date, dataset=ECCO4Monthly())) + set!(field, ECCOMetadatum(:temperature, date=start_date)) + set!(field, ECCOMetadatum(:salinity, date=start_date)) true end end @@ -151,8 +151,8 @@ end field = CenterField(grid) @test begin - set!(field, Metadatum(:temperature, date=start_date, dataset=ECCO4Monthly())) - set!(field, Metadatum(:salinity, date=start_date, dataset=ECCO4Monthly())) + set!(field, ECCOMetadatum(:temperature, date=start_date)) + set!(field, ECCOMetadatum(:salinity, date=start_date)) true end @@ -179,8 +179,8 @@ end ocean = ocean_simulation(grid) date = DateTime(1993, 1, 1) - set!(ocean.model, T=Metadatum(:temperature; date=start_date, dataset=ECCO4Monthly()), - S=Metadatum(:salinity; date=start_date, dataset=ECCO4Monthly())) + set!(ocean.model, T=ECCOMetadatum(:temperature; date=start_date), + S=ECCOMetadatum(:salinity; date=start_date)) end end From 93c6b6f4b1b8ff86eec8af03b4b55e1b5ab17eb3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 21 Mar 2025 19:24:23 +0100 Subject: [PATCH 057/203] bugfix --- src/DataWrangling/JRA55/JRA55_metadata.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 3c5a368b3..f13a70104 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -136,8 +136,8 @@ JRA55_multiple_year_prefix = Dict( JRA55_multiple_year_dates = Dict( :river_freshwater_flux => DateTime(1958, 1, 1) : Day(1) : DateTime(2021, 12, 31), - :rain_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30) - :snow_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30) + :rain_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30), + :snow_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30), :iceberg_freshwater_flux => DateTime(1958, 1, 1) : Day(1) : DateTime(2021, 12, 31), :specific_humidity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), :sea_level_pressure => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), From ce7cbd32d95115e2b609ebc7662463a63493d1bc Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 31 Mar 2025 14:09:10 +0200 Subject: [PATCH 058/203] start changes --- .../JRA55/JRA55_field_time_series.jl | 67 ++++++++++++++++--- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 277fb160e..9bb1df742 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -92,7 +92,64 @@ const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JR const JRA55NetCDFFTSRepeatYear = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:JRA55RepeatYear}} const JRA55NetCDFFTSMultipleYears = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:JRA55NetCDFFTSMultipleYears}} -# TODO: This will need to change when we add a method for JRA55MultipleYears +# Note that each file should have the variables +# - ds["time"]: time coordinate +# - ds["lon"]: longitude at the location of the variable +# - ds["lat"]: latitude at the location of the variable +# - ds["lon_bnds"]: bounding longitudes between which variables are averaged +# - ds["lat_bnds"]: bounding latitudes between which variables are averaged +# - ds[shortname]: the variable data +@inline function load_JRA55_data(ds, fts) + λc = ds["lon"][:] + φc = ds["lat"][:] + LX, LY, LZ = location(fts) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) + + nn = time_indices(fts) + nn = collect(nn) + + if issorted(nn) + data = ds[name][i₁:i₂, j₁:j₂, nn] + else + # The time indices may be cycling past 1; eg ti = [6, 7, 8, 1]. + # However, DiskArrays does not seem to support loading data with unsorted + # indices. So to handle this, we load the data in chunks, where each chunk's + # indices are sorted, and then glue the data together. + m = findfirst(n -> n == 1, nn) + n1 = nn[1:m-1] + n2 = nn[m:end] + + data1 = ds[name][i₁:i₂, j₁:j₂, n1] + data2 = ds[name][i₁:i₂, j₁:j₂, n2] + data = cat(data1, data2, dims=3) + end + + return data +end + +# Simple case, only one file per variable, no need to deal with multiple files +function set!(fts::JRA55NetCDFFTSRepeatYear) + + backend = fts.backend + metadata = backend.metadata + + filename = metadata_filename(metadata) + path = joinpath(metadata.dir, filename) + ds = Dataset(path) + + # Nodes at the variable location + data = load_JRA55_data(ds, fts) + + close(ds) + + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) + + return nothing +end + +# Tricky case: multiple files per variable -- one file per year -- +# we need to infer the file name from the metadata and split the data loading function set!(fts::JRA55NetCDFFTSMultipleYears) backend = fts.backend @@ -106,14 +163,6 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) path = joinpath(metadata.dir, name) ds = Dataset(path) - # Note that each file should have the variables - # - ds["time"]: time coordinate - # - ds["lon"]: longitude at the location of the variable - # - ds["lat"]: latitude at the location of the variable - # - ds["lon_bnds"]: bounding longitudes between which variables are averaged - # - ds["lat_bnds"]: bounding latitudes between which variables are averaged - # - ds[shortname]: the variable data - # Nodes at the variable location λc = ds["lon"][:] φc = ds["lat"][:] From fbfe5cee8cd97af127a21298c2fcde5cd56aff2a Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 31 Mar 2025 14:19:39 +0200 Subject: [PATCH 059/203] this should work --- .../JRA55/JRA55_field_time_series.jl | 75 +++++++++++-------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 9bb1df742..24f8626d2 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -99,14 +99,27 @@ const JRA55NetCDFFTSMultipleYears = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JR # - ds["lon_bnds"]: bounding longitudes between which variables are averaged # - ds["lat_bnds"]: bounding latitudes between which variables are averaged # - ds[shortname]: the variable data -@inline function load_JRA55_data(ds, fts) + +# Simple case, only one file per variable, no need to deal with multiple files +function set!(fts::JRA55NetCDFFTSRepeatYear) + + backend = fts.backend + metadata = backend.metadata + + filename = metadata_filename(metadata) + path = joinpath(metadata.dir, filename) + ds = Dataset(path) + + # Nodes at the variable location + λc = ds["lon"][:] φc = ds["lat"][:] LX, LY, LZ = location(fts) i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) - nn = time_indices(fts) - nn = collect(nn) + nn = time_indices(fts) + nn = collect(nn) + name = short_name(fts.backend.metadata) if issorted(nn) data = ds[name][i₁:i₂, j₁:j₂, nn] @@ -124,22 +137,6 @@ const JRA55NetCDFFTSMultipleYears = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JR data = cat(data1, data2, dims=3) end - return data -end - -# Simple case, only one file per variable, no need to deal with multiple files -function set!(fts::JRA55NetCDFFTSRepeatYear) - - backend = fts.backend - metadata = backend.metadata - - filename = metadata_filename(metadata) - path = joinpath(metadata.dir, filename) - ds = Dataset(path) - - # Nodes at the variable location - data = load_JRA55_data(ds, fts) - close(ds) copyto!(interior(fts, :, :, 1, :), data) @@ -155,23 +152,38 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) backend = fts.backend metadata = backend.metadata - filename = metadata_filename(metadata) - filename = unique(filename) + filename = metadata_filename(metadata) + filename = unique(filename) + name = short_name(metadata) + start_date = first_date(metadata, name) - for name in filename + for file in filename - path = joinpath(metadata.dir, name) + path = joinpath(metadata.dir, file) ds = Dataset(path) + # This can be simplified once we start supporting a + # datetime `Clock` in Oceananigans + file_dates = ds["times"][:] + file_times = zeros(length(file_dates)) + for (t, date) in enumerate(file_dates) + delta = date - start_date + delta = Second(delta).value + file_times[t] = delta + end + + ftsn = time_indices(fts) + ftsn = collect(ftsn) + + # Intersect the time indices with the file times + nn = findall(n -> fts.times[n] ∈ file_times, ftsn) + # Nodes at the variable location λc = ds["lon"][:] φc = ds["lat"][:] LX, LY, LZ = location(fts) i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) - nn = time_indices(fts) - nn = collect(nn) - if issorted(nn) data = ds[name][i₁:i₂, j₁:j₂, nn] else @@ -189,11 +201,14 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) end close(ds) - - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) + for n in 1:length(ftsn) + # We need to set the time index for each file + copyto!(interior(fts, :, :, 1, n), data[:, :, n]) + end end - + + fill_halo_regions!(fts) + return nothing end From 46940e7b9a70be0450baf77d6741f79e961ca6ee Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 31 Mar 2025 14:30:37 +0200 Subject: [PATCH 060/203] bugfix --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 24f8626d2..4650b8da8 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -90,7 +90,7 @@ Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backen const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} const JRA55NetCDFFTSRepeatYear = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:JRA55RepeatYear}} -const JRA55NetCDFFTSMultipleYears = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:JRA55NetCDFFTSMultipleYears}} +const JRA55NetCDFFTSMultipleYears = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:JRA55MultipleYears}} # Note that each file should have the variables # - ds["time"]: time coordinate From 473dbd7bb065e42e42c9f2cfae9c9c64c3255ebb Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 31 Mar 2025 14:36:10 +0200 Subject: [PATCH 061/203] some bugfixing --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 3 ++- src/DataWrangling/JRA55/JRA55_metadata.jl | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 4650b8da8..4b175f900 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -201,8 +201,9 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) end close(ds) + + # We need to set the time index for each file for n in 1:length(ftsn) - # We need to set the time index for each file copyto!(interior(fts, :, :, 1, n), data[:, :, n]) end end diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index f13a70104..17746109a 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -38,7 +38,7 @@ function all_dates(::JRA55RepeatYear, name) end end -all_dates(::JRA55MultipleYears, name) = JRA55_multiple_years_dates[name] +all_dates(::JRA55MultipleYears, name) = JRA55_multiple_year_dates[name] # Fallback, if we not provide the name, take the highest frequency all_dates(dataset::Union{<:JRA55MultipleYears, <:JRA55RepeatYear}) = all_dates(dataset, :temperature) @@ -190,7 +190,7 @@ metadata_url(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_u function metadata_url(m::Metadata{<:Any, <:JRA55MultipleYears}) prefix = JRA55_multiple_year_prefix[m.name] - return url * prefix * "/" * short_name(m) * "/gr/v20200916/" * metadata_filename(m) + return JRA55_multiple_year_url * prefix * "/" * short_name(m) * "/gr/v20200916/" * metadata_filename(m) end function download_dataset(metadata::JRA55Metadata) From 3ccc9f7ce07f7da3175da624c407c1ea80298a86 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 31 Mar 2025 15:29:44 +0200 Subject: [PATCH 062/203] this works --- src/DataWrangling/ECCO/ECCO_metadata.jl | 30 +++---- .../JRA55/JRA55_field_time_series.jl | 82 ++++++++++--------- src/DataWrangling/JRA55/JRA55_metadata.jl | 10 +-- src/DataWrangling/metadata.jl | 7 +- 4 files changed, 67 insertions(+), 62 deletions(-) diff --git a/src/DataWrangling/ECCO/ECCO_metadata.jl b/src/DataWrangling/ECCO/ECCO_metadata.jl index 0edae311f..1bc63b564 100644 --- a/src/DataWrangling/ECCO/ECCO_metadata.jl +++ b/src/DataWrangling/ECCO/ECCO_metadata.jl @@ -15,7 +15,7 @@ struct ECCO2Monthly end struct ECCO2Daily end struct ECCO4Monthly end -const ECCOMetadata{D} = Metadata{D, <:Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}} where {D} +const ECCOMetadata{D} = Metadata{<:Union{<:ECCO2Monthly, <:ECCO2Daily, <:ECCO4Monthly}, D} where {D} const ECCOMetadatum = ECCOMetadata{<:AnyDateTime} const ECCO2_url = "https://ecco.jpl.nasa.gov/drive/files/ECCO2/cube92_latlon_quart_90S90N/" @@ -45,13 +45,13 @@ datestr(md::ECCOMetadatum) = string(md.dates) Base.summary(md::ECCOMetadata) = string("ECCOMetadata{", datasetstr(md), "} of ", md.name, " for ", datestr(md)) -Base.size(data::Metadata{<:Any, <:ECCO2Daily}) = (1440, 720, 50, length(data.dates)) -Base.size(data::Metadata{<:Any, <:ECCO2Monthly}) = (1440, 720, 50, length(data.dates)) -Base.size(data::Metadata{<:Any, <:ECCO4Monthly}) = (720, 360, 50, length(data.dates)) +Base.size(data::Metadata{<:ECCO2Daily}) = (1440, 720, 50, length(data.dates)) +Base.size(data::Metadata{<:ECCO2Monthly}) = (1440, 720, 50, length(data.dates)) +Base.size(data::Metadata{<:ECCO4Monthly}) = (720, 360, 50, length(data.dates)) -Base.size(::Metadata{<:AnyDateTime, <:ECCO2Daily}) = (1440, 720, 50, 1) -Base.size(::Metadata{<:AnyDateTime, <:ECCO2Monthly}) = (1440, 720, 50, 1) -Base.size(::Metadata{<:AnyDateTime, <:ECCO4Monthly}) = (720, 360, 50, 1) +Base.size(::Metadatum{<:ECCO2Daily}) = (1440, 720, 50, 1) +Base.size(::Metadatum{<:ECCO2Monthly}) = (1440, 720, 50, 1) +Base.size(::Metadatum{<:ECCO4Monthly}) = (720, 360, 50, 1) # The whole range of dates in the different dataset datasets all_dates(::ECCO4Monthly, name) = DateTime(1992, 1, 1) : Month(1) : DateTime(2023, 12, 1) @@ -63,14 +63,14 @@ all_dates(::ECCO2Daily, name) = DateTime(1992, 1, 4) : Day(1) : DateTime(202 all_dates(dataset::Union{<:ECCO4Monthly, <:ECCO2Monthly, <:ECCO2Daily}) = all_dates(dataset, :temperature) # File name generation specific to each Dataset dataset -function metadata_filename(metadata::Metadata{<:AnyDateTime, <:ECCO4Monthly}) +function metadata_filename(metadata::Metadatum{<:ECCO4Monthly}) shortname = short_name(metadata) yearstr = string(Dates.year(metadata.dates)) monthstr = string(Dates.month(metadata.dates), pad=2) return shortname * "_" * yearstr * "_" * monthstr * ".nc" end -function metadata_filename(metadata::Metadata{<:AnyDateTime, <:Union{ECCO2Daily, ECCO2Monthly}}) +function metadata_filename(metadata::Metadatum{<:Union{ECCO2Daily, ECCO2Monthly}}) shortname = short_name(metadata) yearstr = string(Dates.year(metadata.dates)) monthstr = string(Dates.month(metadata.dates), pad=2) @@ -85,9 +85,9 @@ function metadata_filename(metadata::Metadata{<:AnyDateTime, <:Union{ECCO2Daily, end # Convenience functions -short_name(data::Metadata{<:Any, <:ECCO2Daily}) = ECCO2_short_names[data.name] -short_name(data::Metadata{<:Any, <:ECCO2Monthly}) = ECCO2_short_names[data.name] -short_name(data::Metadata{<:Any, <:ECCO4Monthly}) = ECCO4_short_names[data.name] +short_name(data::Metadata{<:ECCO2Daily}) = ECCO2_short_names[data.name] +short_name(data::Metadata{<:ECCO2Monthly}) = ECCO2_short_names[data.name] +short_name(data::Metadata{<:ECCO4Monthly}) = ECCO4_short_names[data.name] location(data::ECCOMetadata) = ECCO_location[data.name] @@ -131,10 +131,10 @@ ECCO_location = Dict( ) # URLs for the ECCO datasets specific to each dataset -metadata_url(m::Metadata{<:Any, <:ECCO2Daily}) = ECCO2_url * "monthly/" * short_name(m) * "/" * metadata_filename(m) -metadata_url(m::Metadata{<:Any, <:ECCO2Monthly}) = ECCO2_url * "daily/" * short_name(m) * "/" * metadata_filename(m) +metadata_url(m::Metadata{<:ECCO2Daily}) = ECCO2_url * "monthly/" * short_name(m) * "/" * metadata_filename(m) +metadata_url(m::Metadata{<:ECCO2Monthly}) = ECCO2_url * "daily/" * short_name(m) * "/" * metadata_filename(m) -function metadata_url(m::Metadata{<:Any, <:ECCO4Monthly}) +function metadata_url(m::Metadata{<:ECCO4Monthly}) year = string(Dates.year(m.dates)) return ECCO4_url * short_name(m) * "/" * year * "/" * metadata_filename(m) end diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 4b175f900..5667cf77c 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -73,7 +73,7 @@ end struct JRA55NetCDFBackend{M} <: AbstractInMemoryBackend{Int} start :: Int length :: Int - metadata :: M + metadata :: Metadata{M} end Adapt.adapt_structure(to, b::JRA55NetCDFBackend) = JRA55NetCDFBackend(b.start, b.length, nothing) @@ -155,7 +155,7 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) filename = metadata_filename(metadata) filename = unique(filename) name = short_name(metadata) - start_date = first_date(metadata, name) + start_date = first_date(metadata.dataset, metadata.name) for file in filename @@ -164,7 +164,8 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) # This can be simplified once we start supporting a # datetime `Clock` in Oceananigans - file_dates = ds["times"][:] + file_dates = ds["time"][:] + file_indices = 1:length(file_dates) file_times = zeros(length(file_dates)) for (t, date) in enumerate(file_dates) delta = date - start_date @@ -176,35 +177,37 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) ftsn = collect(ftsn) # Intersect the time indices with the file times - nn = findall(n -> fts.times[n] ∈ file_times, ftsn) - - # Nodes at the variable location - λc = ds["lon"][:] - φc = ds["lat"][:] - LX, LY, LZ = location(fts) - i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) - - if issorted(nn) - data = ds[name][i₁:i₂, j₁:j₂, nn] - else - # The time indices may be cycling past 1; eg ti = [6, 7, 8, 1]. - # However, DiskArrays does not seem to support loading data with unsorted - # indices. So to handle this, we load the data in chunks, where each chunk's - # indices are sorted, and then glue the data together. - m = findfirst(n -> n == 1, nn) - n1 = nn[1:m-1] - n2 = nn[m:end] - - data1 = ds[name][i₁:i₂, j₁:j₂, n1] - data2 = ds[name][i₁:i₂, j₁:j₂, n2] - data = cat(data1, data2, dims=3) - end - - close(ds) - - # We need to set the time index for each file - for n in 1:length(ftsn) - copyto!(interior(fts, :, :, 1, n), data[:, :, n]) + nn = findall(n -> file_times[n] ∈ fts.times[ftsn], file_indices) + + if !isempty(nn) + # Nodes at the variable location + λc = ds["lon"][:] + φc = ds["lat"][:] + LX, LY, LZ = location(fts) + i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) + + if issorted(nn) + data = ds[name][i₁:i₂, j₁:j₂, nn] + else + # The time indices may be cycling past 1; eg ti = [6, 7, 8, 1]. + # However, DiskArrays does not seem to support loading data with unsorted + # indices. So to handle this, we load the data in chunks, where each chunk's + # indices are sorted, and then glue the data together. + m = findfirst(n -> n == 1, nn) + n1 = nn[1:m-1] + n2 = nn[m:end] + + data1 = ds[name][i₁:i₂, j₁:j₂, n1] + data2 = ds[name][i₁:i₂, j₁:j₂, n2] + data = cat(data1, data2, dims=3) + end + + close(ds) + + # We need to set the time index for each file + for n in 1:length(ftsn) + copyto!(interior(fts, :, :, 1, n), data[:, :, n]) + end end end @@ -292,7 +295,7 @@ end function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Float32; latitude = nothing, longitude = nothing, - backend = InMemory(), + backend = JRA55NetCDFBackend(10, metadata), time_indexing = Cyclical()) # First thing: we download the dataset! @@ -369,20 +372,20 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl φc = ds["lat"][:] # Interfaces for the "native" JRA55 grid - λn = ds["lon_bnds"][1, :] - φn = ds["lat_bnds"][1, :] + λn = Array(ds["lon_bnds"][1, :]) + φn = Array(ds["lat_bnds"][1, :]) # The .nc coordinates lon_bnds and lat_bnds do not include # the last interface, so we push them here. - push!(φn, 90) + push!(φn, 90.0) push!(λn, λn[1] + 360) i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, nothing, Center, Center, λc, φc) - data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] λr = λn[i₁:i₂+1] φr = φn[j₁:j₂+1] - Nrx, Nry, Nt = size(data) + Nrx = length(λr) - 1 + Nry = length(φr) - 1 close(ds) N = (Nrx, Nry) @@ -396,7 +399,8 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl topology = (TX, Bounded, Flat)) boundary_conditions = FieldBoundaryConditions(JRA55_native_grid, (Center, Center, Nothing)) - times = native_times(metadata) + start_time = first_date(metadata.dataset, metadata.name) + times = native_times(metadata; start_time) if backend isa JRA55NetCDFBackend fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 17746109a..54d366d63 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -17,7 +17,7 @@ import ClimaOcean.DataWrangling: all_dates, metadata_filename, download_dataset, struct JRA55MultipleYears end struct JRA55RepeatYear end -const JRA55Metadata{D} = Metadata{D, <:Union{<:JRA55MultipleYears, <:JRA55RepeatYear}} where {D} +const JRA55Metadata{D} = Metadata{<:Union{<:JRA55MultipleYears, <:JRA55RepeatYear}, D} where {D} const JRA55Metadatum = JRA55Metadata{<:AnyDateTime} default_download_directory(::Union{<:JRA55MultipleYears, <:JRA55RepeatYear}) = download_JRA55_cache @@ -57,7 +57,7 @@ function JRA55_time_indices(dataset, dates, name) end # File name generation specific to each Dataset dataset -function metadata_filename(metadata::Metadatum{<:Any, <:JRA55RepeatYear}) # No difference +function metadata_filename(metadata::Metadatum{<:JRA55RepeatYear}) # No difference shortname = short_name(metadata) return "RYF." * shortname * ".1990_1991.nc" end @@ -67,7 +67,7 @@ multiple_year_time_displaced_variables = [:rain_freshwater_flux, :downwelling_shortwave_radiation, :downwelling_longwave_radiation] -function metadata_filename(metadata::Metadatum{<:Any, <:JRA55MultipleYears}) +function metadata_filename(metadata::Metadatum{<:JRA55MultipleYears}) # fix the filename shortname = short_name(metadata) year = Dates.year(metadata.dates) @@ -186,9 +186,9 @@ JRA55_repeat_year_urls = Dict( "RYF.vas.1990_1991.nc?rlkey=f9y3e57kx8xrb40gbstarf0x6&dl=0", ) -metadata_url(metadata::Metadata{<:Any, <:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] +metadata_url(metadata::Metadata{<:JRA55RepeatYear}) = JRA55_repeat_year_urls[metadata.name] -function metadata_url(m::Metadata{<:Any, <:JRA55MultipleYears}) +function metadata_url(m::Metadata{<:JRA55MultipleYears}) prefix = JRA55_multiple_year_prefix[m.name] return JRA55_multiple_year_url * prefix * "/" * short_name(m) * "/gr/v20200916/" * metadata_filename(m) end diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index 3d715b7fb..c45540766 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -2,7 +2,7 @@ using CFTime using Dates using Base: @propagate_inbounds -struct Metadata{D, V} +struct Metadata{V, D} name :: Symbol dates :: D dataset :: V @@ -39,7 +39,7 @@ function Metadata(variable_name; end const AnyDateTime = Union{AbstractCFDateTime, Dates.AbstractDateTime} -const Metadatum = Metadata{<:AnyDateTime} +const Metadatum = Metadata{<:Any, <:AnyDateTime} """ Metadatum(variable_name; @@ -97,7 +97,8 @@ Base.last(metadata::Metadatum) = metadata Base.iterate(metadata::Metadatum) = (metadata, nothing) Base.iterate(::Metadatum, ::Any) = nothing -metadata_path(metadata) = joinpath(metadata.dir, metadata_filename(metadata)) +metadata_path(metadata::Metadatum) = joinpath(metadata.dir, metadata_filename(metadata)) +metadata_path(metadata) = [metadata_path(metadatum) for metadatum in metadata] """ native_times(metadata; start_time=first(metadata).dates) From a35bf048a3212985c19cd50bc9fb8596d7dea7f3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 31 Mar 2025 16:00:17 +0200 Subject: [PATCH 063/203] this works! --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 5667cf77c..92ee550f4 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -177,7 +177,8 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) ftsn = collect(ftsn) # Intersect the time indices with the file times - nn = findall(n -> file_times[n] ∈ fts.times[ftsn], file_indices) + nn = findall(n -> file_times[n] ∈ fts.times[ftsn], file_indices) + ftsn = findall(n -> fts.times[n] ∈ file_times[nn], ftsn) if !isempty(nn) # Nodes at the variable location @@ -186,6 +187,7 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) LX, LY, LZ = location(fts) i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) + if issorted(nn) data = ds[name][i₁:i₂, j₁:j₂, nn] else @@ -205,8 +207,9 @@ function set!(fts::JRA55NetCDFFTSMultipleYears) close(ds) # We need to set the time index for each file - for n in 1:length(ftsn) - copyto!(interior(fts, :, :, 1, n), data[:, :, n]) + # Find start index corresponding to the underlying data + for n in 1:length(nn) + copyto!(interior(fts, :, :, 1, ftsn[n]), data[:, :, n]) end end end From 68b3ff325bc8233943b1b4d912aec7b907a5868b Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 31 Mar 2025 16:04:51 +0200 Subject: [PATCH 064/203] add regularization --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 92ee550f4..0a97e4a6d 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -73,7 +73,7 @@ end struct JRA55NetCDFBackend{M} <: AbstractInMemoryBackend{Int} start :: Int length :: Int - metadata :: Metadata{M} + metadata :: M end Adapt.adapt_structure(to, b::JRA55NetCDFBackend) = JRA55NetCDFBackend(b.start, b.length, nothing) @@ -85,12 +85,15 @@ Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. """ JRA55NetCDFBackend(length, metadata) = JRA55NetCDFBackend(1, length, metadata) +# Metadata - agnostic constructor +JRA55NetCDFBackend(length) = JRA55NetCDFBackend(length, nothing) + Base.length(backend::JRA55NetCDFBackend) = backend.length Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") const JRA55NetCDFFTS = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend} -const JRA55NetCDFFTSRepeatYear = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:JRA55RepeatYear}} -const JRA55NetCDFFTSMultipleYears = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:JRA55MultipleYears}} +const JRA55NetCDFFTSRepeatYear = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:Metadata{<:JRA55RepeatYear}}} +const JRA55NetCDFFTSMultipleYears = FlavorOfFTS{<:Any, <:Any, <:Any, <:Any, <:JRA55NetCDFBackend{<:Metadata{<:JRA55MultipleYears}}} # Note that each file should have the variables # - ds["time"]: time coordinate @@ -304,6 +307,11 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl # First thing: we download the dataset! download_dataset(metadata) + # Regularize the backend in case of `JRA55NetCDFBackend` + if backend isa JRA55NetCDFBackend && backend.metadata isa Nothing + backend = JRA55NetCDFBackend(backend.length, metadata) + end + # Unpack metadata details dataset = metadata.dataset name = metadata.name From 5f532198c7ba361f37e1e93e931ec96f631877bd Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 31 Mar 2025 16:18:34 +0200 Subject: [PATCH 065/203] bugfix --- src/DataWrangling/JRA55/JRA55_metadata.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 54d366d63..51d88ec15 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -57,7 +57,9 @@ function JRA55_time_indices(dataset, dates, name) end # File name generation specific to each Dataset dataset -function metadata_filename(metadata::Metadatum{<:JRA55RepeatYear}) # No difference +# Note that `JRA55RepeatYear` has only one file associated, so we can define +# the filename directly for the whole `Metadata` object, independent of the `dates` +function metadata_filename(metadata::Metadata{<:JRA55RepeatYear}) # No difference shortname = short_name(metadata) return "RYF." * shortname * ".1990_1991.nc" end From 9209bbf561d0051f2ffbed5bb57a7fe60ab33033 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 1 Apr 2025 09:10:46 +0200 Subject: [PATCH 066/203] add sea-ice ocean stress --- .../assemble_net_fluxes.jl | 26 ++++---- .../component_interfaces.jl | 6 +- .../sea_ice_ocean_fluxes.jl | 59 ++++++++++++++----- 3 files changed, 63 insertions(+), 28 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index 20d3c5d32..aa045fb5d 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -76,8 +76,10 @@ end i, j = @index(Global, NTuple) kᴺ = size(grid, 3) time = Time(clock.time) - ρτx = atmos_ocean_fluxes.x_momentum # zonal momentum flux - ρτy = atmos_ocean_fluxes.y_momentum # meridional momentum flux + ρτxao = atmos_ocean_fluxes.x_momentum # atmosphere - ocean zonal momentum flux + ρτyao = atmos_ocean_fluxes.y_momentum # atmosphere - ocean meridional momentum flux + ρτxio = sea_ice_ocean_fluxes.x_momentum # sea_ice - ocean zonal momentum flux + ρτyio = sea_ice_ocean_fluxes.y_momentum # sea_ice - ocean meridional momentum flux @inbounds begin Sₒ = ocean_salinity[i, j, kᴺ] @@ -121,20 +123,22 @@ end ρₒ⁻¹ = 1 / ocean_properties.reference_density cₒ = ocean_properties.heat_capacity - τxao = ℑxᶠᵃᵃ(i, j, 1, grid, τᶜᶜᶜ, ρₒ⁻¹, ℵ, ρτx) - τyao = ℑyᵃᶠᵃ(i, j, 1, grid, τᶜᶜᶜ, ρₒ⁻¹, ℵ, ρτy) - Jᵀao = ΣQao * ρₒ⁻¹ / cₒ - Jˢao = - Sₒ * ΣFao - - ρₒ⁻¹ = 1 / ocean_properties.reference_density - cₒ = ocean_properties.heat_capacity - @inbounds begin ℵᵢ = ℵ[i, j, 1] Qio = sea_ice_ocean_fluxes.interface_heat[i, j, 1] - Jˢio = sea_ice_ocean_fluxes.salt[i, j, 1] + + Jᵀao = ΣQao * ρₒ⁻¹ / cₒ + Jˢao = - Sₒ * ΣFao Jᵀio = Qio * ρₒ⁻¹ / cₒ + Jˢio = sea_ice_ocean_fluxes.salt[i, j, 1] + + τxao = ℑxᶠᵃᵃ(i, j, 1, grid, τᶜᶜᶜ, ρₒ⁻¹, ℵ, ρτxao) + τyao = ℑyᵃᶠᵃ(i, j, 1, grid, τᶜᶜᶜ, ρₒ⁻¹, ℵ, ρτyao) + τxio = ρτxio[i, j, 1] * ρₒ⁻¹ * ℑxᶠᵃᵃ(i, j, 1, grid, ℵ) + τyio = ρτyio[i, j, 1] * ρₒ⁻¹ * ℑyᵃᶠᵃ(i, j, 1, grid, ℵ) + τx[i, j, 1] = τxao + τxio + τy[i, j, 1] = τyao + τyio τx[i, j, 1] = τxao τy[i, j, 1] = τyao Jᵀ[i, j, 1] = (1 - ℵᵢ) * Jᵀao + Jᵀio diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index ce4ae92f5..e80977842 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -247,6 +247,8 @@ function sea_ice_ocean_interface(sea_ice::SeaIceSimulation, ocean; io_bottom_heat_flux = Field{Center, Center, Nothing}(ocean.model.grid) io_frazil_heat_flux = Field{Center, Center, Nothing}(ocean.model.grid) io_salt_flux = Field{Center, Center, Nothing}(ocean.model.grid) + x_momentum = Field{Face, Center, Nothing}(ocean.model.grid) + y_momentum = Field{Center, Face, Nothing}(ocean.model.grid) @assert io_frazil_heat_flux isa Field{Center, Center, Nothing} @assert io_bottom_heat_flux isa Field{Center, Center, Nothing} @@ -254,7 +256,9 @@ function sea_ice_ocean_interface(sea_ice::SeaIceSimulation, ocean; io_fluxes = (interface_heat=io_bottom_heat_flux, frazil_heat=io_frazil_heat_flux, - salt=io_salt_flux) + salt=io_salt_flux, + x_momentum=x_momentum, + y_momentum=y_momentum) io_properties = (; characteristic_melting_speed) diff --git a/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl index 0ef926c9c..98d156079 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl @@ -1,5 +1,6 @@ using Oceananigans.Operators: Δzᶜᶜᶜ using ClimaSeaIce.SeaIceThermodynamics: melting_temperature +using ClimaSeaIce.SeaIceMomentumEquations: x_momentum_stress, y_momentum_stress function compute_sea_ice_ocean_fluxes!(coupled_model) ocean = coupled_model.ocean @@ -21,43 +22,61 @@ function compute_sea_ice_ocean_fluxes!(coupled_model) grid = ocean.model.grid arch = architecture(grid) + uᵢ, vᵢ = sea_ice.model.velocities + dynamics = sea_ice.model.dynamics + + τs = if isnothing(dynamics) + nothing + else + dynamics.external_momentum_stresses.bottom + end + # What about the latent heat removed from the ocean when ice forms? # Is it immediately removed from the ocean? Or is it stored in the ice? - launch!(arch, grid, :xy, _compute_sea_ice_ocean_latent_heat_flux!, - sea_ice_ocean_fluxes, grid, hᵢ, h⁻, ℵᵢ, Sᵢ, Tₒ, Sₒ, liquidus, ocean_properties, interface_properties, Δt) + launch!(arch, grid, :xy, _compute_sea_ice_ocean_fluxes!, + sea_ice_ocean_fluxes, grid, clock, hᵢ, h⁻, ℵᵢ, Sᵢ, Tₒ, Sₒ, uᵢ, vᵢ, + τs, liquidus, ocean_properties, interface_properties, Δt) return nothing end -@kernel function _compute_sea_ice_ocean_latent_heat_flux!(sea_ice_ocean_fluxes, - grid, - ice_thickness, - previous_ice_thickness, - ice_concentration, - ice_salinity, - ocean_temperature, - ocean_salinity, - liquidus, - ocean_properties, - interface_properties, - Δt) - +@kernel function _compute_sea_ice_ocean_fluxes!(sea_ice_ocean_fluxes, + grid, + clock, + ice_thickness, + previous_ice_thickness, + ice_concentration, + ice_salinity, + ocean_temperature, + ocean_salinity, + sea_ice_u_velocity, + sea_ice_v_velocity, + sea_ice_ocean_stresses, + liquidus, + ocean_properties, + interface_properties, + Δt) + i, j = @index(Global, NTuple) Nz = size(grid, 3) Qᶠₒ = sea_ice_ocean_fluxes.frazil_heat Qᵢₒ = sea_ice_ocean_fluxes.interface_heat Jˢ = sea_ice_ocean_fluxes.salt + τx = sea_ice_ocean_fluxes.x_momentum + τy = sea_ice_ocean_fluxes.y_momentum + uᵢ = sea_ice_u_velocity + vᵢ = sea_ice_v_velocity Tₒ = ocean_temperature Sₒ = ocean_salinity Sᵢ = ice_salinity hᵢ = ice_thickness + ℵᵢ = ice_concentration h⁻ = previous_ice_thickness ρₒ = ocean_properties.reference_density cₒ = ocean_properties.heat_capacity uₘ★ = interface_properties.characteristic_melting_speed - ℵ = @inbounds ice_concentration[i, j, 1] δQ_frazil = zero(grid) for k = Nz:-1:1 @@ -94,6 +113,7 @@ end @inbounds begin Tᴺ = Tₒ[i, j, Nz] Sᴺ = Sₒ[i, j, Nz] + ℵ = ℵᵢ[i, j, 1] end # Compute total heat associated with temperature adjustment @@ -111,6 +131,9 @@ end @inbounds Qᶠₒ[i, j, 1] = δQ_frazil @inbounds Qᵢₒ[i, j, 1] = δQ_melting * ℵ # Melting depends on concentration + sea_ice_fields = (; u = uᵢ, v = vᵢ, h = hᵢ, ℵ = ℵᵢ) + τₒᵢ = sea_ice_ocean_stresses + @inbounds begin # Change in thickness Δh = hᵢ[i, j, 1] - h⁻[i, j, 1] @@ -122,5 +145,9 @@ end # Update previous ice thickness h⁻[i, j, 1] = hᵢ[i, j, 1] + + # Momentum stresses + τx[i, j, 1] = x_momentum_stress(i, j, 1, grid, τₒᵢ, clock, sea_ice_fields) + τy[i, j, 1] = y_momentum_stress(i, j, 1, grid, τₒᵢ, clock, sea_ice_fields) end end \ No newline at end of file From 4d963eaa1a324d5c0ba7f2cddb854fbc3e7fd909 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 1 Apr 2025 13:49:24 +0200 Subject: [PATCH 067/203] fix tests --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 2 +- src/DataWrangling/metadata.jl | 2 +- test/test_jra55.jl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 0a97e4a6d..1cc569489 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -86,7 +86,7 @@ Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. JRA55NetCDFBackend(length, metadata) = JRA55NetCDFBackend(1, length, metadata) # Metadata - agnostic constructor -JRA55NetCDFBackend(length) = JRA55NetCDFBackend(length, nothing) +JRA55NetCDFBackend(length) = JRA55NetCDFBackend(1, length, nothing) Base.length(backend::JRA55NetCDFBackend) = backend.length Base.summary(backend::JRA55NetCDFBackend) = string("JRA55NetCDFBackend(", backend.start, ", ", backend.length, ")") diff --git a/src/DataWrangling/metadata.jl b/src/DataWrangling/metadata.jl index c45540766..8789d4f8a 100644 --- a/src/DataWrangling/metadata.jl +++ b/src/DataWrangling/metadata.jl @@ -65,7 +65,7 @@ default_download_directory(dataset) = pwd() download_dataset(metadata) = nothing Base.show(io::IO, metadata::Metadata) = - print(io, "ECCOMetadata:", '\n', + print(io, "Metadata:", '\n', "├── name: $(metadata.name)", '\n', "├── dates: $(metadata.dates)", '\n', "├── dataset: $(metadata.dataset)", '\n', diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 4b160f762..b4ad73152 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -47,7 +47,7 @@ using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere f₁ = view(parent(netcdf_JRA55_fts), :, :, 1, 1) f₁ = Array(f₁) - netcdf_JRA55_fts.backend = JRA55NetCDFBackend(Nt-2, Nb) + netcdf_JRA55_fts.backend = Oceananigans.OutputReaders.new_backend(netcdf_JRA55_fts.backend, Nt-2, Nb) @test Oceananigans.OutputReaders.time_indices(netcdf_JRA55_fts) == (Nt-2, Nt-1, Nt, 1) set!(netcdf_JRA55_fts) From 1ee41afc95302fcb5226a189671e2e439744dbe7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 1 Apr 2025 13:57:10 +0200 Subject: [PATCH 068/203] bugfix --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index bd2178227..68486db06 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -430,9 +430,9 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl boundary_conditions) # Fill the data in a GPU-friendly manner - copyto!(interior(native_fts, :, :, 1, :), data) - fill_halo_regions!(native_fts) + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) - return native_fts + return fts end end From 1d58772675b43606cdad9dc328e995e737582e8c Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 1 Apr 2025 14:05:20 +0200 Subject: [PATCH 069/203] Update JRA55_field_time_series.jl --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 68486db06..a302cc79b 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -83,7 +83,8 @@ Adapt.adapt_structure(to, b::JRA55NetCDFBackend) = JRA55NetCDFBackend(b.start, b Represents a JRA55 FieldTimeSeries backed by JRA55 native .nc files. """ -JRA55NetCDFBackend(length, metadata) = JRA55NetCDFBackend(1, length, metadata) +JRA55NetCDFBackend(length, metadata::Metadata) = JRA55NetCDFBackend(1, length, metadata) +JRA55NetCDFBackend(start::Integer, length::Integer) = JRA55NetCDFBackend(start, length, nothing) # Metadata - agnostic constructor JRA55NetCDFBackend(length) = JRA55NetCDFBackend(1, length, nothing) From 0c020d0601f5fc83fea4c0563c4510cdaf115225 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 1 Apr 2025 14:06:39 +0200 Subject: [PATCH 070/203] Update JRA55_field_time_series.jl --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index a302cc79b..585568a55 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -389,7 +389,7 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl # The .nc coordinates lon_bnds and lat_bnds do not include # the last interface, so we push them here. - push!(φn, 90.0) + push!(φn, 90) push!(λn, λn[1] + 360) i₁, i₂, j₁, j₂, TX = compute_bounding_indices(longitude, latitude, nothing, Center, Center, λc, φc) From bafe3c7e2fc758426dd41ccd55775201a6f981ca Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 1 Apr 2025 14:08:45 +0200 Subject: [PATCH 071/203] simplify --- .../JRA55/JRA55_field_time_series.jl | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 585568a55..1b24caeaf 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -414,26 +414,14 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl start_time = first_date(metadata.dataset, metadata.name) times = native_times(metadata; start_time) - if backend isa JRA55NetCDFBackend - fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - backend, - time_indexing, - boundary_conditions, - path = filepath, - name = shortname) - - set!(fts) - return fts - else - fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - time_indexing, - backend, - boundary_conditions) + fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = filepath, + name = shortname) - # Fill the data in a GPU-friendly manner - copyto!(interior(fts, :, :, 1, :), data) - fill_halo_regions!(fts) + set!(fts) - return fts - end + return fts end From 350b6577b762b00149ecd1ea0a5101b38634f510 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 1 Apr 2025 14:11:39 +0200 Subject: [PATCH 072/203] add the inmemory stuff --- .../JRA55/JRA55_field_time_series.jl | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 1b24caeaf..e36e946f5 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -414,14 +414,30 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl start_time = first_date(metadata.dataset, metadata.name) times = native_times(metadata; start_time) - fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; - backend, - time_indexing, - boundary_conditions, - path = filepath, - name = shortname) - - set!(fts) + if backend isa JRA55NetCDFBackend + fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + backend, + time_indexing, + boundary_conditions, + path = filepath, + name = shortname) + + set!(fts) + return fts + else + fts = FieldTimeSeries{Center, Center, Nothing}(JRA55_native_grid, times; + time_indexing, + backend, + boundary_conditions) + + # Fill the data in a GPU-friendly manner + ds = Dataset(filepath) + data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] + close(ds) + + copyto!(interior(fts, :, :, 1, :), data) + fill_halo_regions!(fts) - return fts + return fts + end end From 4a49b40934525986cc26cb72db4e1bbe6bb4e51b Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 09:44:59 +0200 Subject: [PATCH 073/203] start with this --- experiments/omip_prototype/download_data.jl | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 experiments/omip_prototype/download_data.jl diff --git a/experiments/omip_prototype/download_data.jl b/experiments/omip_prototype/download_data.jl new file mode 100644 index 000000000..b188c2853 --- /dev/null +++ b/experiments/omip_prototype/download_data.jl @@ -0,0 +1,7 @@ +using ClimaOcean +using ClimaOcean.JRA55 +using ClimaOcean.DataWrangling: download_dataset + +dir = "forcing_data/" + +atmosphere = JRA55PrescribedAtmosphere(; dataset=JRA55MultipleYears(), dir, include_rivers_and_icebergs=true) \ No newline at end of file From fea185454d5d9cbd2f612a638f6d6ac7f748cf3d Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 09:46:36 +0200 Subject: [PATCH 074/203] default to inmemory --- src/DataWrangling/JRA55/JRA55_field_time_series.jl | 2 +- src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index e36e946f5..23baf51af 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -302,7 +302,7 @@ end function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Float32; latitude = nothing, longitude = nothing, - backend = JRA55NetCDFBackend(10, metadata), + backend = InMemory(), time_indexing = Cyclical()) # First thing: we download the dataset! diff --git a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl index eb763832e..714eace69 100644 --- a/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl +++ b/src/DataWrangling/JRA55/JRA55_prescribed_atmosphere.jl @@ -23,7 +23,7 @@ function JRA55PrescribedAtmosphere(architecture = CPU(), FT = Float32; dataset = JRA55RepeatYear(), start_date = first_date(dataset, :temperature), end_date = last_date(dataset, :temperature), - backend = JRA55NetCDFBackend(10), + backend = InMemory(), time_indexing = Cyclical(), surface_layer_height = 10, # meters include_rivers_and_icebergs = false, From 7c4aa61b2772bdad1b310cfc9f28bc6ad6cc203a Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 09:48:08 +0200 Subject: [PATCH 075/203] go! --- experiments/omip_prototype/download_data.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/experiments/omip_prototype/download_data.jl b/experiments/omip_prototype/download_data.jl index b188c2853..2881bcd71 100644 --- a/experiments/omip_prototype/download_data.jl +++ b/experiments/omip_prototype/download_data.jl @@ -2,6 +2,7 @@ using ClimaOcean using ClimaOcean.JRA55 using ClimaOcean.DataWrangling: download_dataset -dir = "forcing_data/" - -atmosphere = JRA55PrescribedAtmosphere(; dataset=JRA55MultipleYears(), dir, include_rivers_and_icebergs=true) \ No newline at end of file +atmosphere = JRA55PrescribedAtmosphere(; dir="forcing_data/", + dataset=JRA55MultipleYears(), + backend=JRA55NetCDFBackend(10), + include_rivers_and_icebergs=true) \ No newline at end of file From 24f7d93357df522828594d4417e2d465376a7598 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 10:11:42 +0200 Subject: [PATCH 076/203] add a failsafe + a test --- src/DataWrangling/JRA55/JRA55.jl | 2 +- .../JRA55/JRA55_field_time_series.jl | 7 +++++++ test/test_jra55.jl | 19 ++++++++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl index 48a3d365a..dc66003ba 100644 --- a/src/DataWrangling/JRA55/JRA55.jl +++ b/src/DataWrangling/JRA55/JRA55.jl @@ -1,6 +1,6 @@ module JRA55 -export JRA55FieldTimeSeries, JRA55PrescribedAtmosphere, JRA55RepeatYear +export JRA55FieldTimeSeries, JRA55PrescribedAtmosphere, JRA55RepeatYear, JRA55MultipleYears using Oceananigans using Oceananigans.Units diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 23baf51af..416ece3f8 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -305,6 +305,13 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl backend = InMemory(), time_indexing = Cyclical()) + + # Cannot use `TotallyInMemory` backend with JRA55MultipleYear dataset + if metadata.dataset isa JRA55MultipleYears && backend isa TotallyInMemory + msg = string("The `InMemory` backend is not supported for the JRA55MultipleYears dataset.") + throw(ArgumentError(msg)) + end + # First thing: we download the dataset! download_dataset(metadata) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index b4ad73152..78f6fde61 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -1,6 +1,6 @@ include("runtests_setup.jl") -using ClimaOcean.JRA55: download_JRA55_cache +using ClimaOcean.JRA55: download_JRA55_cache, JRA55MultipleYears using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere @testset "JRA55 and data wrangling utilities" begin @@ -129,5 +129,22 @@ using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere @test rivers_times != pressure_times @test length(rivers_times) != length(pressure_times) @test rivers_times[2] - rivers_times[1] == 86400 + + @info "Testing multi year JRA55 data on $A..." + dataset = JRA55MultipleYears() + dates = ClimaOcean.DataWrangling.all_dates(JRA55MultipleYears(), :temperature) + + # These dates correspond to a metadata that crosses between year 1958 and 1959. + # Therefore, this will download two files for the two years and concatenate them + # when reading the data. + start_date = dates[2800] + end_date = dates[3600] + backend = JRA55NetCDFBackend(10) + Ta = JRA55FieldTimeSeries(:temperature; dataset=JRA55MultipleYears(), start_date, end_date, backend) + + # Test we can access all the data + for t in Ta.times + @test Ta[t] isa Field + end end end From d231995c7226fcb7887e79f72f49a9bb4f6aad92 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 10:18:51 +0200 Subject: [PATCH 077/203] some cleanup --- src/DataWrangling/JRA55/JRA55_metadata.jl | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 69c2827f9..ea952252f 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -64,23 +64,18 @@ function metadata_filename(metadata::Metadata{<:JRA55RepeatYear}) # No differenc return "RYF." * shortname * ".1990_1991.nc" end -multiple_year_time_displaced_variables = [:rain_freshwater_flux, - :snow_freshwater_flux, - :downwelling_shortwave_radiation, - :downwelling_longwave_radiation] - function metadata_filename(metadata::Metadatum{<:JRA55MultipleYears}) # fix the filename shortname = short_name(metadata) year = Dates.year(metadata.dates) suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" - if metadata.name ∈ [:river_freshwater_flux, :iceberg_freshwater_flux] + end_date = JRA55_multiple_year_dates[metadata.name][end] + end_hour = Hour(end_date) + + if end_hour == Hour(0) dates = "$(year)0101-$(year)1231" - elseif metadata.name ∈ [:rain_freshwater_flux, - :snow_freshwater_flux, - :downwelling_shortwave_radiation, - :downwelling_longwave_radiation] + elseif end_hour == Hour(22) dates = "$(year)01010130-$(year)12312230" else dates = "$(year)01010000-$(year)12312100" From ca1980c66d9995dfe167b199b59ad266ae526d47 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 10:22:01 +0200 Subject: [PATCH 078/203] better to write last --- src/DataWrangling/JRA55/JRA55_metadata.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index ea952252f..514462314 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -70,7 +70,7 @@ function metadata_filename(metadata::Metadatum{<:JRA55MultipleYears}) year = Dates.year(metadata.dates) suffix = "_input4MIPs_atmosphericState_OMIP_MRI-JRA55-do-1-5-0_gr_" - end_date = JRA55_multiple_year_dates[metadata.name][end] + end_date = last(JRA55_multiple_year_dates[metadata.name]) end_hour = Hour(end_date) if end_hour == Hour(0) From aeedd2f8a0b1370f203853ab28a0c55c1ba22829 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 10:32:57 +0200 Subject: [PATCH 079/203] last index --- .../InterfaceComputations/sea_ice_ocean_fluxes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl index 98d156079..236eba75c 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl @@ -147,7 +147,7 @@ end h⁻[i, j, 1] = hᵢ[i, j, 1] # Momentum stresses - τx[i, j, 1] = x_momentum_stress(i, j, 1, grid, τₒᵢ, clock, sea_ice_fields) - τy[i, j, 1] = y_momentum_stress(i, j, 1, grid, τₒᵢ, clock, sea_ice_fields) + τx[i, j, 1] = x_momentum_stress(i, j, Nz, grid, τₒᵢ, clock, sea_ice_fields) + τy[i, j, 1] = y_momentum_stress(i, j, Nz, grid, τₒᵢ, clock, sea_ice_fields) end end \ No newline at end of file From ddee7f06e1fb6fe5ecd86cda8c5502b9fbb3cc99 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 10:34:18 +0200 Subject: [PATCH 080/203] add this --- .../InterfaceComputations/assemble_net_fluxes.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index aa045fb5d..5ff12337d 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -4,7 +4,11 @@ using Oceananigans.Operators: ℑxᶠᵃᵃ, ℑyᵃᶠᵃ using ClimaOcean.OceanSeaIceModels: sea_ice_concentration @inline computed_sea_ice_ocean_fluxes(interface) = interface.fluxes -@inline computed_sea_ice_ocean_fluxes(::Nothing) = (interface_heat = ZeroField(), frazil_heat = ZeroField(), salt = ZeroField()) +@inline computed_sea_ice_ocean_fluxes(::Nothing) = (interface_heat = ZeroField(), + frazil_heat = ZeroField(), + salt = ZeroField(), + x_momentum = ZeroField(), + y_momentum = ZeroField()) function compute_net_ocean_fluxes!(coupled_model) ocean = coupled_model.ocean From daeb12f2b67a463848b9af5582adff2e643dc87c Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 10:38:19 +0200 Subject: [PATCH 081/203] add a clock --- .../InterfaceComputations/sea_ice_ocean_fluxes.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl index 236eba75c..ab87e08d7 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl @@ -19,8 +19,9 @@ function compute_sea_ice_ocean_fluxes!(coupled_model) ocean_properties = coupled_model.interfaces.ocean_properties liquidus = sea_ice.model.ice_thermodynamics.phase_transitions.liquidus - grid = ocean.model.grid - arch = architecture(grid) + grid = ocean.model.grid + clock = ocean.model.clock + arch = architecture(grid) uᵢ, vᵢ = sea_ice.model.velocities dynamics = sea_ice.model.dynamics From 629d582c8e3712bd0a34698612e841fee7976dd5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 10:50:41 +0200 Subject: [PATCH 082/203] add the arctic --- experiments/arctic_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/arctic_simulation.jl b/experiments/arctic_simulation.jl index 8cfe5cd64..d87a7fb3e 100644 --- a/experiments/arctic_simulation.jl +++ b/experiments/arctic_simulation.jl @@ -63,7 +63,7 @@ using ClimaSeaIce.SeaIceMomentumEquations using ClimaSeaIce.Rheologies # Remember to pass the SSS as a bottom bc to the sea ice! -SSS = view(ocean.model.tracers.S, :, :, grid.Nz) +SSS = view(ocean.model.tracers.S.data, :, :, grid.Nz) bottom_heat_boundary_condition = IceWaterThermalEquilibrium(SSS) SSU = view(ocean.model.velocities.u, :, :, grid.Nz) @@ -77,7 +77,7 @@ dynamics = SeaIceMomentumEquation(grid; coriolis = ocean.model.coriolis, top_momentum_stress = (u=τua, v=τva), bottom_momentum_stress = τo, - ocean_velocities = (u=SSU, v=SSV), + ocean_velocities = (u=0.1*SSU, v=0.1*SSV), rheology = ElastoViscoPlasticRheology(), solver = SplitExplicitSolver(120)) From 35fe01dced1f5f977cca73248a8bad1f5f6d280e Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 11:57:40 +0200 Subject: [PATCH 083/203] try it out --- .../omip_prototype/quarter_degree_omip.jl | 123 ++++++++++++++++++ src/SeaIceSimulations.jl | 20 +++ 2 files changed, 143 insertions(+) create mode 100644 experiments/omip_prototype/quarter_degree_omip.jl diff --git a/experiments/omip_prototype/quarter_degree_omip.jl b/experiments/omip_prototype/quarter_degree_omip.jl new file mode 100644 index 000000000..8d8feec1f --- /dev/null +++ b/experiments/omip_prototype/quarter_degree_omip.jl @@ -0,0 +1,123 @@ +using ClimaOcean +using ClimaSeaIce +using Oceananigans +using Oceananigans.Grids +using Oceananigans.Units +using Oceananigans.OrthogonalSphericalShellGrids +using ClimaOcean.OceanSimulations +using ClimaOcean.ECCO +using ClimaOcean.DataWrangling +using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using Printf + +using CUDA +CUDA.device!(1) +arch = GPU() + +r_faces = ClimaOcean.exponential_z_faces(; Nz=100, h=30, depth=6200) +z_faces = MutableVerticalDiscretization(r_faces) + +Nx = 1440 # longitudinal direction +Ny = 700 # meridional direction +Nz = length(r_faces) - 1 + +grid = TripolarGrid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + halo = (7, 7, 7)) + +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +##### +##### A Propgnostic Ocean model +##### + +# A very diffusive ocean +momentum_advection = WENOVectorInvariant() +tracer_advection = WENO(order=7) + +free_surface = SplitExplicitFreeSurface(grid; substeps=70) +closure = ClimaOcean.OceanSimulations.default_ocean_closure() + +ocean = ocean_simulation(grid; + momentum_advection, + tracer_advection, + free_surface, + closure) + +dataset = ECCO4Monthly() + +set!(ocean.model, T=Metadatum(:temperature; dataset), + S=Metadatum(:salinity; dataset)) + +##### +##### A Prognostic Sea-ice model +##### + +# Remember to pass the SSS as a bottom bc to the sea ice! +SSS = view(ocean.model.tracers.S.data, :, :, grid.Nz) +bottom_heat_boundary_condition = IceWaterThermalEquilibrium(SSS) + +# Default dynamics +dynamics = ClimaOcean.SeaIceSimulations.default_sea_ice_dynamics(grid; ocean) + +sea_ice = sea_ice_simulation(grid; bottom_heat_boundary_condition, dynamics, advection=WENO(order=7)) + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), + ℵ=Metadatum(:sea_ice_concentration; dataset)) + +##### +##### A Prescribed Atmosphere model +##### + +atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(40)) +radiation = Radiation() + +##### +##### Arctic coupled model +##### + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +omip = Simulation(arctic, Δt=1minutes, stop_time=30days) + +# Figure out the outputs.... + +wall_time = Ref(time_ns()) + +using Statistics + +function progress(sim) + sea_ice = sim.model.sea_ice + hmax = maximum(sea_ice.model.ice_thickness) + ℵmax = maximum(sea_ice.model.ice_concentration) + hmean = mean(sea_ice.model.ice_thickness) + ℵmean = mean(sea_ice.model.ice_concentration) + Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) + Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) + + step_time = 1e-9 * (time_ns() - wall_time[]) + + msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) + msg2 = @sprintf("max(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) + msg3 = @sprintf("mean(h): %.2e m, mean(ℵ): %.2e ", hmean, ℵmean) + msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) + msg5 = @sprintf("wall time: %s \n", prettytime(step_time)) + + @info msg1 * msg2 * msg3 * msg4 * msg5 + + wall_time[] = time_ns() + + return nothing +end + +# And add it as a callback to the simulation. +add_callback!(omip, progress, IterationInterval(10)) + +run!(omip) + +# The full OMIP cycle! +omip.stop_time = 60*365days +omip.Δt = 600 + +run!(omip) \ No newline at end of file diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index 2b7dc17b8..ec58108a5 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -17,6 +17,8 @@ using Oceananigans.Operators using ClimaSeaIce using ClimaSeaIce: SeaIceModel, SlabSeaIceThermodynamics, PhaseTransitions, ConductiveFlux using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using ClimaSeaIce.SeaIceMomentumEquations +using ClimaSeaIce.Rheologies using ClimaOcean.OceanSimulations: Default @@ -73,4 +75,22 @@ function sea_ice_simulation(grid; return sea_ice end +function default_sea_ice_dynamics(grid; ocean) + + SSU = view(ocean.model.velocities.u, :, :, grid.Nz) + SSV = view(ocean.model.velocities.u, :, :, grid.Nz) + + τo = SemiImplicitStress(uₑ=SSU, vₑ=SSV) + τua = Field{Face, Center, Nothing}(grid) + τva = Field{Center, Face, Nothing}(grid) + + return SeaIceMomentumEquation(grid; + coriolis = ocean.model.coriolis, + top_momentum_stress = (u=τua, v=τva), + bottom_momentum_stress = τo, + ocean_velocities = (u=0.1*SSU, v=0.1*SSV), + rheology = ElastoViscoPlasticRheology(), + solver = SplitExplicitSolver(120)) +end + end \ No newline at end of file From 5548a99f48f850c216b20117b0300bb8397361a2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 3 Apr 2025 12:20:18 +0200 Subject: [PATCH 084/203] correct dates --- src/DataWrangling/JRA55/JRA55_metadata.jl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_metadata.jl b/src/DataWrangling/JRA55/JRA55_metadata.jl index 514462314..7a80670cd 100644 --- a/src/DataWrangling/JRA55/JRA55_metadata.jl +++ b/src/DataWrangling/JRA55/JRA55_metadata.jl @@ -132,17 +132,17 @@ JRA55_multiple_year_prefix = Dict( ) JRA55_multiple_year_dates = Dict( - :river_freshwater_flux => DateTime(1958, 1, 1) : Day(1) : DateTime(2021, 12, 31), - :rain_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30), - :snow_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30), - :iceberg_freshwater_flux => DateTime(1958, 1, 1) : Day(1) : DateTime(2021, 12, 31), - :specific_humidity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), - :sea_level_pressure => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), - :downwelling_longwave_radiation => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30), - :downwelling_shortwave_radiation => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2021, 12, 31, 22, 30), - :temperature => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), - :eastward_velocity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21), - :northward_velocity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2021, 12, 31, 21) + :river_freshwater_flux => DateTime(1958, 1, 1) : Day(1) : DateTime(2019, 12, 31), + :rain_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2019, 12, 31, 22, 30), + :snow_freshwater_flux => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2019, 12, 31, 22, 30), + :iceberg_freshwater_flux => DateTime(1958, 1, 1) : Day(1) : DateTime(2019, 12, 31), + :specific_humidity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2019, 12, 31, 21), + :sea_level_pressure => DateTime(1958, 1, 1) : Hour(3) : DateTime(2019, 12, 31, 21), + :downwelling_longwave_radiation => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2019, 12, 31, 22, 30), + :downwelling_shortwave_radiation => DateTime(1958, 1, 1, 1, 30) : Hour(3) : DateTime(2019, 12, 31, 22, 30), + :temperature => DateTime(1958, 1, 1) : Hour(3) : DateTime(2019, 12, 31, 21), + :eastward_velocity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2019, 12, 31, 21), + :northward_velocity => DateTime(1958, 1, 1) : Hour(3) : DateTime(2019, 12, 31, 21) ) JRA55_repeat_year_urls = Dict( From dfb8590e47604f291de2909c4293ace8c3db6619 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 4 Apr 2025 08:49:35 +0200 Subject: [PATCH 085/203] Update experiments/omip_prototype/quarter_degree_omip.jl Co-authored-by: Navid C. Constantinou --- experiments/omip_prototype/quarter_degree_omip.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/experiments/omip_prototype/quarter_degree_omip.jl b/experiments/omip_prototype/quarter_degree_omip.jl index 8d8feec1f..bc3242123 100644 --- a/experiments/omip_prototype/quarter_degree_omip.jl +++ b/experiments/omip_prototype/quarter_degree_omip.jl @@ -59,10 +59,12 @@ set!(ocean.model, T=Metadatum(:temperature; dataset), SSS = view(ocean.model.tracers.S.data, :, :, grid.Nz) bottom_heat_boundary_condition = IceWaterThermalEquilibrium(SSS) -# Default dynamics -dynamics = ClimaOcean.SeaIceSimulations.default_sea_ice_dynamics(grid; ocean) +# Default sea-ice dynamics +sea_ice_dynamics = ClimaOcean.SeaIceSimulations.default_sea_ice_dynamics(grid; ocean) -sea_ice = sea_ice_simulation(grid; bottom_heat_boundary_condition, dynamics, advection=WENO(order=7)) +sea_ice = sea_ice_simulation(grid; bottom_heat_boundary_condition, + dynamics = sea_ice_dynamics, + advection=WENO(order=7)) set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), ℵ=Metadatum(:sea_ice_concentration; dataset)) From a049dc1d255866d84463097fd4fa3d0505bc69ca Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 4 Apr 2025 08:49:45 +0200 Subject: [PATCH 086/203] Update experiments/omip_prototype/quarter_degree_omip.jl Co-authored-by: Navid C. Constantinou --- experiments/omip_prototype/quarter_degree_omip.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/omip_prototype/quarter_degree_omip.jl b/experiments/omip_prototype/quarter_degree_omip.jl index bc3242123..29a5102c0 100644 --- a/experiments/omip_prototype/quarter_degree_omip.jl +++ b/experiments/omip_prototype/quarter_degree_omip.jl @@ -77,7 +77,7 @@ atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(40)) radiation = Radiation() ##### -##### Arctic coupled model +##### An ocean-sea ice coupled model ##### omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) From d1e6fafbbe03133185ca01e08a936403a83d6c70 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 4 Apr 2025 18:36:31 +0200 Subject: [PATCH 087/203] add stuff --- experiments/omip_prototype/quarter_degree_omip.jl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/experiments/omip_prototype/quarter_degree_omip.jl b/experiments/omip_prototype/quarter_degree_omip.jl index 29a5102c0..65f81f4cb 100644 --- a/experiments/omip_prototype/quarter_degree_omip.jl +++ b/experiments/omip_prototype/quarter_degree_omip.jl @@ -73,7 +73,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), ##### A Prescribed Atmosphere model ##### -atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(40)) +atmosphere = JRA55PrescribedAtmosphere(arch; dataset=JRA55MultipleYears(), backend=JRA55NetCDFBackend(40), include_rivers_and_icebergs=true) radiation = Radiation() ##### @@ -85,6 +85,17 @@ omip = Simulation(arctic, Δt=1minutes, stop_time=30days) # Figure out the outputs.... +ocean.output_writer[:checkpointer] = Checkpointer(ocean.model, + schedule = IterationInterval(10000), + prefix = "ocean_checkpoint", + overwrite_existing = true) + + +sea_ice.output_writer[:checkpointer] = Checkpointer(sea_ice.model, + schedule = IterationInterval(10000), + prefix = "sea_ice_checkpoint", + overwrite_existing = true) + wall_time = Ref(time_ns()) using Statistics From a6d758d729d80dd849a5794e9997eea3a90106de Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 10 Apr 2025 05:25:45 -0400 Subject: [PATCH 088/203] going sixth degree --- ...er_degree_omip.jl => sixth_degree_omip.jl} | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) rename experiments/omip_prototype/{quarter_degree_omip.jl => sixth_degree_omip.jl} (76%) diff --git a/experiments/omip_prototype/quarter_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl similarity index 76% rename from experiments/omip_prototype/quarter_degree_omip.jl rename to experiments/omip_prototype/sixth_degree_omip.jl index 65f81f4cb..81cda71e4 100644 --- a/experiments/omip_prototype/quarter_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -6,19 +6,18 @@ using Oceananigans.Units using Oceananigans.OrthogonalSphericalShellGrids using ClimaOcean.OceanSimulations using ClimaOcean.ECCO +using ClimaOcean.JRA55: JRA55MultipleYears using ClimaOcean.DataWrangling using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium using Printf - using CUDA -CUDA.device!(1) -arch = GPU() -r_faces = ClimaOcean.exponential_z_faces(; Nz=100, h=30, depth=6200) +arch = GPU() +r_faces = ClimaOcean.exponential_z_faces(; Nz=60, depth=6200) z_faces = MutableVerticalDiscretization(r_faces) -Nx = 1440 # longitudinal direction -Ny = 700 # meridional direction +Nx = 2160 # longitudinal direction +Ny = 1080 # meridional direction Nz = length(r_faces) - 1 grid = TripolarGrid(arch; @@ -35,12 +34,12 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_ # A very diffusive ocean momentum_advection = WENOVectorInvariant() -tracer_advection = WENO(order=7) +tracer_advection = FluxFormAdvection(WENO(order=7), WENO(order=7), Centered()) free_surface = SplitExplicitFreeSurface(grid; substeps=70) closure = ClimaOcean.OceanSimulations.default_ocean_closure() -ocean = ocean_simulation(grid; +ocean = ocean_simulation(grid; Δt=1minutes, momentum_advection, tracer_advection, free_surface, @@ -73,7 +72,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), ##### A Prescribed Atmosphere model ##### -atmosphere = JRA55PrescribedAtmosphere(arch; dataset=JRA55MultipleYears(), backend=JRA55NetCDFBackend(40), include_rivers_and_icebergs=true) +atmosphere = JRA55PrescribedAtmosphere(arch; dir="./forcing_data", dataset=JRA55MultipleYears(), backend=JRA55NetCDFBackend(40), include_rivers_and_icebergs=true) radiation = Radiation() ##### @@ -81,21 +80,15 @@ radiation = Radiation() ##### omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(arctic, Δt=1minutes, stop_time=30days) +omip = Simulation(omip, Δt=20, stop_time=30days) # Figure out the outputs.... -ocean.output_writer[:checkpointer] = Checkpointer(ocean.model, +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, schedule = IterationInterval(10000), prefix = "ocean_checkpoint", overwrite_existing = true) - -sea_ice.output_writer[:checkpointer] = Checkpointer(sea_ice.model, - schedule = IterationInterval(10000), - prefix = "sea_ice_checkpoint", - overwrite_existing = true) - wall_time = Ref(time_ns()) using Statistics @@ -104,8 +97,6 @@ function progress(sim) sea_ice = sim.model.sea_ice hmax = maximum(sea_ice.model.ice_thickness) ℵmax = maximum(sea_ice.model.ice_concentration) - hmean = mean(sea_ice.model.ice_thickness) - ℵmean = mean(sea_ice.model.ice_concentration) Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) @@ -113,11 +104,10 @@ function progress(sim) msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) msg2 = @sprintf("max(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) - msg3 = @sprintf("mean(h): %.2e m, mean(ℵ): %.2e ", hmean, ℵmean) msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) msg5 = @sprintf("wall time: %s \n", prettytime(step_time)) - @info msg1 * msg2 * msg3 * msg4 * msg5 + @info msg1 * msg2 * msg4 * msg5 wall_time[] = time_ns() @@ -133,4 +123,4 @@ run!(omip) omip.stop_time = 60*365days omip.Δt = 600 -run!(omip) \ No newline at end of file +run!(omip) From f18a772e3d6dbe08228ca52f56bff8a2672de6f4 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 10 Apr 2025 11:36:56 +0200 Subject: [PATCH 089/203] some changes --- Project.toml | 2 +- .../omip_prototype/sixth_degree_omip.jl | 50 +++++++++++-------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Project.toml b/Project.toml index 9b43e5a5f..bc4f4f720 100644 --- a/Project.toml +++ b/Project.toml @@ -39,7 +39,7 @@ ClimaOceanReactantExt = "Reactant" Adapt = "4" CFTime = "0.1" CUDA = "4, 5" -ClimaSeaIce = "0.2.4" +ClimaSeaIce = "0.2.6" CubicSplines = "0.2" DataDeps = "0.7" Downloads = "1.6" diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl index 81cda71e4..7a3ddd05a 100644 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -6,7 +6,7 @@ using Oceananigans.Units using Oceananigans.OrthogonalSphericalShellGrids using ClimaOcean.OceanSimulations using ClimaOcean.ECCO -using ClimaOcean.JRA55: JRA55MultipleYears +using ClimaOcean.JRA55 using ClimaOcean.DataWrangling using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium using Printf @@ -34,10 +34,11 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_ # A very diffusive ocean momentum_advection = WENOVectorInvariant() -tracer_advection = FluxFormAdvection(WENO(order=7), WENO(order=7), Centered()) +tracer_advection = WENO(order=7) free_surface = SplitExplicitFreeSurface(grid; substeps=70) -closure = ClimaOcean.OceanSimulations.default_ocean_closure() +closure = (ClimaOcean.OceanSimulations.default_ocean_closure(), + VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) ocean = ocean_simulation(grid; Δt=1minutes, momentum_advection, @@ -45,10 +46,8 @@ ocean = ocean_simulation(grid; Δt=1minutes, free_surface, closure) -dataset = ECCO4Monthly() - -set!(ocean.model, T=Metadatum(:temperature; dataset), - S=Metadatum(:salinity; dataset)) +restart_file = "ocean_checkpoint_iteration130000.jld2" +set!(ocean.model, restart_file) ##### ##### A Prognostic Sea-ice model @@ -65,14 +64,21 @@ sea_ice = sea_ice_simulation(grid; bottom_heat_boundary_condition, dynamics = sea_ice_dynamics, advection=WENO(order=7)) -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), - ℵ=Metadatum(:sea_ice_concentration; dataset)) +dataset = ECCO4Monthly() +date = DateTime(1992, 2, 1) # 1st Feb 1992 + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; date, dataset), + ℵ=Metadatum(:sea_ice_concentration; date, dataset)) ##### ##### A Prescribed Atmosphere model ##### -atmosphere = JRA55PrescribedAtmosphere(arch; dir="./forcing_data", dataset=JRA55MultipleYears(), backend=JRA55NetCDFBackend(40), include_rivers_and_icebergs=true) +dir = "./forcing_data" +dataset = MultiyearJRA55() +backend = JRA55NetCDFBackend(40) + +atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) radiation = Radiation() ##### @@ -80,7 +86,7 @@ radiation = Radiation() ##### omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=20, stop_time=30days) +omip = Simulation(omip, Δt=10minutes, stop_time=60*365days) # Figure out the outputs.... @@ -89,25 +95,35 @@ ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, prefix = "ocean_checkpoint", overwrite_existing = true) +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = IterationInterval(10000), + prefix = "sea_ice_checkpoint", + overwrite_existing = true) + wall_time = Ref(time_ns()) using Statistics function progress(sim) sea_ice = sim.model.sea_ice + ocean = sim.model.ocean hmax = maximum(sea_ice.model.ice_thickness) ℵmax = maximum(sea_ice.model.ice_concentration) Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) + umax = maximum(ocean.model.velocities.u) + vmax = maximum(ocean.model.velocities.v) + wmax = maximum(ocean.model.velocities.w) step_time = 1e-9 * (time_ns() - wall_time[]) msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) msg2 = @sprintf("max(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) - msg5 = @sprintf("wall time: %s \n", prettytime(step_time)) + msg5 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) + msg6 = @sprintf("wall time: %s \n", prettytime(step_time)) - @info msg1 * msg2 * msg4 * msg5 + @info msg1 * msg2 * msg4 * msg5 * msg6 wall_time[] = time_ns() @@ -115,12 +131,6 @@ function progress(sim) end # And add it as a callback to the simulation. -add_callback!(omip, progress, IterationInterval(10)) - -run!(omip) - -# The full OMIP cycle! -omip.stop_time = 60*365days -omip.Δt = 600 +add_callback!(omip, progress, IterationInterval(50)) run!(omip) From 6679bbd73d8c730dd7a95859b5ee5ced80e98fba Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 10 Apr 2025 12:14:35 +0200 Subject: [PATCH 090/203] synchronize the clocks for the moment --- experiments/omip_prototype/sixth_degree_omip.jl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl index 7a3ddd05a..4da8f4ce3 100644 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -12,6 +12,15 @@ using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium using Printf using CUDA +function synch!(clock1::Clock, clock2) + # Synchronize the clocks + clock1.time = clock2.time + clock1.iteration = clock2.iteration + clock1.last_Δt = clock2.last_Δt +end + +synch!(model1, model2) = synch!(model1.clock, model2.clock) + arch = GPU() r_faces = ClimaOcean.exponential_z_faces(; Nz=60, depth=6200) z_faces = MutableVerticalDiscretization(r_faces) @@ -88,6 +97,12 @@ radiation = Radiation() omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) omip = Simulation(omip, Δt=10minutes, stop_time=60*365days) +synch!(atmosphere, ocean.model) +synch!(sea_ice.model, ocean.model) +synch!(omip.model, atmosphere) + +@show omip.model.clock + # Figure out the outputs.... ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, From 7975dd4494482f368989026e7f87ab083b8d899e Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 10 Apr 2025 13:57:29 +0200 Subject: [PATCH 091/203] Update test_jra55.jl --- test/test_jra55.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 77e7e1584..929529c08 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -1,6 +1,7 @@ include("runtests_setup.jl") -using ClimaOcean.JRA55: download_JRA55_cache, JRA55MultipleYears +using ClimaOcean.JRA55 +using ClimaOcean.JRA55: download_JRA55_cache using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere @testset "JRA55 and data wrangling utilities" begin From 77e440b2264c315bf6601693e24d0ba854482bc8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 10 Apr 2025 14:09:41 +0200 Subject: [PATCH 092/203] bugfix --- src/SeaIceSimulations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index ec58108a5..f51830ee0 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -78,7 +78,7 @@ end function default_sea_ice_dynamics(grid; ocean) SSU = view(ocean.model.velocities.u, :, :, grid.Nz) - SSV = view(ocean.model.velocities.u, :, :, grid.Nz) + SSV = view(ocean.model.velocities.v, :, :, grid.Nz) τo = SemiImplicitStress(uₑ=SSU, vₑ=SSV) τua = Field{Face, Center, Nothing}(grid) From b05fb8393635e8ba793e76c5e2d59921c3e3eefb Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 10 Apr 2025 14:20:36 +0200 Subject: [PATCH 093/203] improve it quickly for now --- src/SeaIceSimulations.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index f51830ee0..b7d905a86 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -75,12 +75,16 @@ function sea_ice_simulation(grid; return sea_ice end -function default_sea_ice_dynamics(grid; ocean) +function default_sea_ice_dynamics(grid; + ocean, # Cannot do it without an ocean + sea_ice_ocean_drag_coefficient = 5.5e-3, + rheology = ElastoViscoPlasticRheology(), + solver = SplitExplicitSolver(120)) SSU = view(ocean.model.velocities.u, :, :, grid.Nz) SSV = view(ocean.model.velocities.v, :, :, grid.Nz) - τo = SemiImplicitStress(uₑ=SSU, vₑ=SSV) + τo = SemiImplicitStress(uₑ=SSU, vₑ=SSV, Cᴰ=sea_ice_ocean_drag_coefficient) τua = Field{Face, Center, Nothing}(grid) τva = Field{Center, Face, Nothing}(grid) @@ -89,8 +93,8 @@ function default_sea_ice_dynamics(grid; ocean) top_momentum_stress = (u=τua, v=τva), bottom_momentum_stress = τo, ocean_velocities = (u=0.1*SSU, v=0.1*SSV), - rheology = ElastoViscoPlasticRheology(), - solver = SplitExplicitSolver(120)) + rheology, + solver) end end \ No newline at end of file From 501b3fa6880365fb020153a6068c2c0ef55686d3 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 10 Apr 2025 11:26:26 -0400 Subject: [PATCH 094/203] continue --- .../omip_prototype/sixth_degree_omip.jl | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl index 4da8f4ce3..9d66a6ac2 100644 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -10,6 +10,7 @@ using ClimaOcean.JRA55 using ClimaOcean.DataWrangling using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium using Printf +using Dates using CUDA function synch!(clock1::Clock, clock2) @@ -55,8 +56,10 @@ ocean = ocean_simulation(grid; Δt=1minutes, free_surface, closure) -restart_file = "ocean_checkpoint_iteration130000.jld2" -set!(ocean.model, restart_file) +dataset = ECCO4Monthly() + +set!(ocean.model, T=Metadatum(:temperature; dataset), + S=Metadatum(:salinity; dataset)) ##### ##### A Prognostic Sea-ice model @@ -73,18 +76,15 @@ sea_ice = sea_ice_simulation(grid; bottom_heat_boundary_condition, dynamics = sea_ice_dynamics, advection=WENO(order=7)) -dataset = ECCO4Monthly() -date = DateTime(1992, 2, 1) # 1st Feb 1992 - -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; date, dataset), - ℵ=Metadatum(:sea_ice_concentration; date, dataset)) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), + ℵ=Metadatum(:sea_ice_concentration; dataset)) ##### ##### A Prescribed Atmosphere model ##### dir = "./forcing_data" -dataset = MultiyearJRA55() +dataset = MultiYearJRA55() backend = JRA55NetCDFBackend(40) atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) @@ -95,13 +95,7 @@ radiation = Radiation() ##### omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=10minutes, stop_time=60*365days) - -synch!(atmosphere, ocean.model) -synch!(sea_ice.model, ocean.model) -synch!(omip.model, atmosphere) - -@show omip.model.clock +omip = Simulation(omip, Δt=20, stop_time=30days) # Figure out the outputs.... @@ -149,3 +143,8 @@ end add_callback!(omip, progress, IterationInterval(50)) run!(omip) + +omip.Δt = 10minutes +omip.stop_time = 58 * 365days + +run!(omip) From 5751899fd655cd6b632d93099a2e121f23a8d7c3 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 14 Apr 2025 03:20:58 -0400 Subject: [PATCH 095/203] another try... --- .../omip_prototype/sixth_degree_omip.jl | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl index 9d66a6ac2..6a482bb02 100644 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -13,6 +13,8 @@ using Printf using Dates using CUDA +import Oceananigans.OutputWriters: checkpointer_address + function synch!(clock1::Clock, clock2) # Synchronize the clocks clock1.time = clock2.time @@ -42,13 +44,19 @@ grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_ ##### A Propgnostic Ocean model ##### -# A very diffusive ocean +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation + momentum_advection = WENOVectorInvariant() tracer_advection = WENO(order=7) free_surface = SplitExplicitFreeSurface(grid; substeps=70) -closure = (ClimaOcean.OceanSimulations.default_ocean_closure(), - VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) + +mixing_length = CATKEMixingLength(Cᵇ=0.01) +turbulent_kinetic_energy_equation = CATKEEquation(Cᵂϵ=1.0) + +catke_closure = CATKEVerticalDiffusivity(ExplicitTimeDiscretization(); mixing_length, turbulent_kinetic_energy_equation) +closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) ocean = ocean_simulation(grid; Δt=1minutes, momentum_advection, @@ -93,12 +101,14 @@ radiation = Radiation() ##### ##### An ocean-sea ice coupled model ##### - + omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=20, stop_time=30days) +omip = Simulation(omip, Δt=20, stop_time=60days) # Figure out the outputs.... +checkpointer_address(::SeaIceModel) = "SeaIceModel" + ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, schedule = IterationInterval(10000), prefix = "ocean_checkpoint", From af67adc8c2d66a4b977e6352e344c80ee09d00c7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 24 Apr 2025 16:14:53 +0200 Subject: [PATCH 096/203] bugfix for the salt flux --- .../InterfaceComputations/assemble_net_fluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index c53e3613f..d6380f692 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -134,7 +134,7 @@ end Jᵀao = ΣQao * ρₒ⁻¹ / cₒ Jˢao = - Sₒ * ΣFao Jᵀio = Qio * ρₒ⁻¹ / cₒ - Jˢio = sea_ice_ocean_fluxes.salt[i, j, 1] + Jˢio = sea_ice_ocean_fluxes.salt[i, j, 1] * ℵᵢ τxao = ℑxᶠᵃᵃ(i, j, 1, grid, τᶜᶜᶜ, ρₒ⁻¹, ℵ, ρτxao) τyao = ℑyᵃᶠᵃ(i, j, 1, grid, τᶜᶜᶜ, ρₒ⁻¹, ℵ, ρτyao) From 83f97e98230076bbedb8e3e5d7ca6bcc585870fb Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 30 Apr 2025 15:02:38 +0200 Subject: [PATCH 097/203] try it out --- .../InterfaceComputations/assemble_net_fluxes.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index cb2327c44..8b9cc392d 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -183,6 +183,7 @@ function compute_net_sea_ice_fluxes!(coupled_model) kernel_parameters = interface_kernel_parameters(grid) sea_ice_surface_temperature = coupled_model.interfaces.atmosphere_sea_ice_interface.temperature + ice_concentration = sea_ice_concentration(sea_ice) launch!(arch, grid, kernel_parameters, _assemble_net_sea_ice_fluxes!, @@ -192,6 +193,7 @@ function compute_net_sea_ice_fluxes!(coupled_model) clock, atmosphere_sea_ice_fluxes, sea_ice_ocean_fluxes, + ice_concentration, freshwater_flux, sea_ice_surface_temperature, downwelling_radiation, @@ -207,6 +209,7 @@ end clock, atmosphere_sea_ice_fluxes, sea_ice_ocean_fluxes, + ice_concentration, freshwater_flux, # Where do we add this one? surface_temperature, downwelling_radiation, @@ -220,6 +223,7 @@ end @inbounds begin Ts = surface_temperature[i, j, kᴺ] Ts = convert_to_kelvin(sea_ice_properties.temperature_units, Ts) + ℵi = ice_concentration[i, j, kᴺ] Qs = downwelling_radiation.Qs[i, j, 1] Qℓ = downwelling_radiation.Qℓ[i, j, 1] @@ -239,7 +243,7 @@ end Qu = upwelling_radiation(Ts, σ, ϵ) Qd = net_downwelling_radiation(i, j, grid, time, α, ϵ, Qs, Qℓ) - ΣQt = Qd + Qu + Qc + Qv + ΣQt = (Qd + Qu + Qc + Qv) * ℵi ΣQb = Qf + Qi # Mask fluxes over land for convenience From 03e7f19fed6cbdb50ab09d5327d2267fdfe9cd20 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 30 Apr 2025 15:03:52 +0200 Subject: [PATCH 098/203] correction --- .../InterfaceComputations/assemble_net_fluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index 8b9cc392d..22381a4fd 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -243,7 +243,7 @@ end Qu = upwelling_radiation(Ts, σ, ϵ) Qd = net_downwelling_radiation(i, j, grid, time, α, ϵ, Qs, Qℓ) - ΣQt = (Qd + Qu + Qc + Qv) * ℵi + ΣQt = (Qd + Qu + Qc + Qv) * ℵi # If ℵi == 0 there is no heat flux from the top! ΣQb = Qf + Qi # Mask fluxes over land for convenience From 1eedc44f89280b49f0bfc1de0398cb933ff05eec Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 14 May 2025 18:12:05 +0200 Subject: [PATCH 099/203] correct --- .../InterfaceComputations/assemble_net_fluxes.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index 918873d21..dff50271b 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -231,7 +231,6 @@ function compute_net_sea_ice_fluxes!(coupled_model) clock, atmosphere_sea_ice_fluxes, sea_ice_ocean_fluxes, - ice_concentration, freshwater_flux, ice_concentration, sea_ice_surface_temperature, @@ -248,7 +247,6 @@ end clock, atmosphere_sea_ice_fluxes, sea_ice_ocean_fluxes, - ice_concentration, freshwater_flux, # Where do we add this one? ice_concentration, surface_temperature, From 202212c2f7f3231d8e5b9ec1971e2d0265ab1fb2 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 22 May 2025 04:11:01 -0400 Subject: [PATCH 100/203] update --- src/SeaIceSimulations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index 9222a2383..18d979f0f 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -97,4 +97,4 @@ function default_sea_ice_dynamics(grid; solver) end -end \ No newline at end of file +end From 0c8d8b17d5b5aaae4596b60d9239071011151a64 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 22 May 2025 10:36:22 +0200 Subject: [PATCH 101/203] go for it --- src/SeaIceSimulations.jl | 44 +++++++++++++++++++++++++++----- test/test_ocean_sea_ice_model.jl | 12 +-------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index 58766da0c..d204bd895 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -20,7 +20,7 @@ using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium using ClimaOcean.OceanSimulations: Default -function sea_ice_simulation(grid; +function sea_ice_simulation(grid, ocean=nothing; Δt = 5minutes, ice_salinity = 0, # psu advection = nothing, # for the moment @@ -28,8 +28,8 @@ function sea_ice_simulation(grid; ice_heat_capacity = 2100, # J kg⁻¹ K⁻¹ ice_consolidation_thickness = 0.05, # m ice_density = 900, # kg m⁻³ - dynamics = nothing, - bottom_heat_boundary_condition = IceWaterThermalEquilibrium(), + dynamics = default_sea_ice_dynamics(grid, ocean), + bottom_heat_boundary_condition = nothing, phase_transitions = PhaseTransitions(; ice_heat_capacity, ice_density), conductivity = 2, # kg m s⁻³ K⁻¹ internal_heat_flux = ConductiveFlux(; conductivity)) @@ -41,6 +41,15 @@ function sea_ice_simulation(grid; top_surface_temperature = Field{Center, Center, Nothing}(grid) top_heat_boundary_condition = PrescribedTemperature(top_surface_temperature) + if isnothing(bottom_heat_boundary_condition) + if isnothing(ocean) + surface_ocean_salinity = 0 + else + surface_ocean_salinity = view(ocean.model.tracers.S, :, :, size(ocean.model.grid, 3)) + end + bottom_heat_boundary_condition = IceWaterThermalEquilibrium(surface_ocean_salinity) + end + ice_thermodynamics = SlabSeaIceThermodynamics(grid; internal_heat_flux, phase_transitions, @@ -50,16 +59,12 @@ function sea_ice_simulation(grid; bottom_heat_flux = Field{Center, Center, Nothing}(grid) top_heat_flux = Field{Center, Center, Nothing}(grid) - # top_momentum_stress = (u = Field{Face, Center, Nothing}(grid), - # v = Field{Center, Face, Nothing}(grid)) - # Build the sea ice model sea_ice_model = SeaIceModel(grid; ice_salinity, advection, tracers, ice_consolidation_thickness, - # top_momentum_stress, ice_thermodynamics, dynamics, bottom_heat_flux, @@ -73,4 +78,29 @@ function sea_ice_simulation(grid; return sea_ice end +function default_sea_ice_dynamics(grid, ocean=nothing; # Cannot do it without an ocean + sea_ice_ocean_drag_coefficient = 5.5e-3, + rheology = ElastoViscoPlasticRheology(), + solver = SplitExplicitSolver(120)) + + if isnothing(ocean) + SSU = Oceananigans.Fields.ZeroField() + SSV = Oceananigans.Fields.ZeroField() + else + SSU = view(ocean.model.velocities.u, :, :, grid.Nz) + SSV = view(ocean.model.velocities.v, :, :, grid.Nz) + end + + τo = SemiImplicitStress(uₑ=SSU, vₑ=SSV, Cᴰ=sea_ice_ocean_drag_coefficient) + τua = Field{Face, Center, Nothing}(grid) + τva = Field{Center, Face, Nothing}(grid) + + return SeaIceMomentumEquation(grid; + coriolis = ocean.model.coriolis, + top_momentum_stress = (u=τua, v=τva), + bottom_momentum_stress = τo, + rheology, + solver) +end + end \ No newline at end of file diff --git a/test/test_ocean_sea_ice_model.jl b/test/test_ocean_sea_ice_model.jl index 71e9e416d..0d1b044c2 100644 --- a/test/test_ocean_sea_ice_model.jl +++ b/test/test_ocean_sea_ice_model.jl @@ -81,17 +81,7 @@ using ClimaSeaIce.Rheologies ##### Coupled ocean-sea ice and prescribed atmosphere ##### - # Adding a sea ice model to the coupled model - τua = Field{Face, Center, Nothing}(grid) - τva = Field{Center, Face, Nothing}(grid) - - dynamics = SeaIceMomentumEquation(grid; - coriolis = ocean.model.coriolis, - top_momentum_stress = (u=τua, v=τva), - rheology = ElastoViscoPlasticRheology(), - solver = SplitExplicitSolver(120)) - - sea_ice = sea_ice_simulation(grid; dynamics, advection=WENO(order=7)) + sea_ice = sea_ice_simulation(grid, ocean; advection=WENO(order=7)) liquidus = sea_ice.model.ice_thermodynamics.phase_transitions.liquidus # Set the ocean temperature and salinity From 0f04d0fdf55645472485b73dea9e3fa1f3fc78f8 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 22 May 2025 10:37:32 +0200 Subject: [PATCH 102/203] Update src/SeaIceSimulations.jl --- src/SeaIceSimulations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index d204bd895..9e1234716 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -103,4 +103,4 @@ function default_sea_ice_dynamics(grid, ocean=nothing; # Cannot do it without an solver) end -end \ No newline at end of file +end From e28b9a4b429b880b043b7bd0194c9be9b16b9aed Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 22 May 2025 11:35:25 +0200 Subject: [PATCH 103/203] Update SeaIceSimulations.jl --- src/SeaIceSimulations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index 9e1234716..47cdf32cc 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -78,7 +78,7 @@ function sea_ice_simulation(grid, ocean=nothing; return sea_ice end -function default_sea_ice_dynamics(grid, ocean=nothing; # Cannot do it without an ocean +function default_sea_ice_dynamics(grid, ocean=nothing; sea_ice_ocean_drag_coefficient = 5.5e-3, rheology = ElastoViscoPlasticRheology(), solver = SplitExplicitSolver(120)) From 2eeed4c1713128babf7c06a8f7659f798cb00a10 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 22 May 2025 06:11:37 -0400 Subject: [PATCH 104/203] some.. salinity --- src/SeaIceSimulations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index 943a7e720..f56dddf0f 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -25,7 +25,7 @@ using ClimaOcean.OceanSimulations: Default function sea_ice_simulation(grid, ocean=nothing; Δt = 5minutes, - ice_salinity = 0, # psu + ice_salinity = 4, # psu advection = nothing, # for the moment tracers = (), ice_heat_capacity = 2100, # J kg⁻¹ K⁻¹ From 702fe647e556d774bedfafdc1dc2c37b9d8a1cef Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 18 Jun 2025 10:42:28 +0200 Subject: [PATCH 105/203] update sea ice simulation --- src/SeaIceSimulations.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index d36505016..22dddc0bd 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -84,7 +84,7 @@ end function sea_ice_dynamics(grid, ocean=nothing; sea_ice_ocean_drag_coefficient = 5.5e-3, - rheology = ElastoViscoPlasticRheology(pressure_formulation = IceStrength()), + rheology = ElastoViscoPlasticRheology(), coriolis = nothing, free_drift = nothing, solver = SplitExplicitSolver(120)) @@ -115,6 +115,7 @@ function sea_ice_dynamics(grid, ocean=nothing; top_momentum_stress = (u=τua, v=τva), bottom_momentum_stress = τo, rheology, + free_drift, solver) end From 96645846c21e1b1e2b74a45f0fac896501613472 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 18 Jun 2025 10:43:07 +0200 Subject: [PATCH 106/203] try like this for the moment and let it go --- .../InterfaceComputations/roughness_lengths.jl | 12 +++++++----- .../similarity_theory_turbulent_fluxes.jl | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/roughness_lengths.jl b/src/OceanSeaIceModels/InterfaceComputations/roughness_lengths.jl index 62845744a..d7ca790a2 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/roughness_lengths.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/roughness_lengths.jl @@ -20,23 +20,25 @@ Base.show(io::IO, ::ScalarRoughnessLength{FT}) where FT = print(io, "ScalarRough struct WindDependentWaveFormulation{FT} Umax :: FT + αmin :: FT ℂ₁ :: FT ℂ₂ :: FT end """ WindDependentWaveFormulation(FT = Oceananigans.defaults.FloatType; - Umax = 19, ℂ₁ = 0.0017, ℂ₂ = -0.005) + Umax = 19, αmin = 0.011, ℂ₁ = 0.0017, ℂ₂ = -0.005) -A gravity wave parameter based on the wind speed `ΔU` with the formula `ℂ₁ * max(ΔU, Umax) + ℂ₂`. +A gravity wave parameter based on the wind speed `ΔU` with the formula `max(αmin, ℂ₁ * min(ΔU, Umax) + ℂ₂`). """ -WindDependentWaveFormulation(FT=Oceananigans.defaults.FloatType; Umax = 19, ℂ₁ = 0.0017, ℂ₂ = -0.005) = +WindDependentWaveFormulation(FT=Oceananigans.defaults.FloatType; Umax = 19, αmin = 0.011, ℂ₁ = 0.0017, ℂ₂ = -0.005) = WindDependentWaveFormulation(convert(FT, Umax), + convert(FT, αmin), convert(FT, ℂ₁), convert(FT, ℂ₂)) gravity_wave_parameter(α::Number, args...) = α -gravity_wave_parameter(α::WindDependentWaveFormulation, ΔU) = α.ℂ₁ * max(ΔU, α.Umax) + α.ℂ₂ +gravity_wave_parameter(α::WindDependentWaveFormulation, ΔU) = max(α.αmin, α.ℂ₁ * min(ΔU, α.Umax) + α.ℂ₂) """ ScalarRoughnessLength(FT = Float64; @@ -88,7 +90,7 @@ function MomentumRoughnessLength(FT=Oceananigans.defaults.FloatType; gravitational_acceleration = default_gravitational_acceleration, maximum_roughness_length = 1, air_kinematic_viscosity = 1.5e-5, - wave_formulation = 0.02, + wave_formulation = WindDependentWaveFormulation(FT), smooth_wall_parameter = 0.11) if wave_formulation isa Number diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index 8b8a61506..7c8cad4cf 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -87,7 +87,7 @@ Keyword Arguments function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; von_karman_constant = 0.4, turbulent_prandtl_number = 1, - gustiness_parameter = 1, + gustiness_parameter = 1.2, stability_functions = atmosphere_ocean_stability_functions(FT), momentum_roughness_length = MomentumRoughnessLength(FT), temperature_roughness_length = ScalarRoughnessLength(FT), @@ -195,7 +195,7 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, # Buoyancy flux characteristic scale for gustiness (Edson et al. 2013) h_bℓ = atmosphere_state.h_bℓ Jᵇ = - u★ * b★ - Uᴳ = β * cbrt(Jᵇ * h_bℓ) + Uᴳ = max(0.5, β * cbrt(Jᵇ * h_bℓ)) # New velocity difference accounting for gustiness Δu, Δv = velocity_difference(interface_properties.velocity_formulation, From d28b6111ea97e37d4ed80388c2363e1a55425230 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 14 Jul 2025 04:53:53 -0400 Subject: [PATCH 107/203] added project --- Project.toml | 2 +- .../sixth_degree_omip_nodynamics.jl | 233 ++++++++++++++++++ 2 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 experiments/omip_prototype/sixth_degree_omip_nodynamics.jl diff --git a/Project.toml b/Project.toml index f7fa87a1e..5f55c15ae 100644 --- a/Project.toml +++ b/Project.toml @@ -44,7 +44,7 @@ ClimaOceanReactantExt = "Reactant" Adapt = "4" CFTime = "0.1, 0.2" CUDA = "4, 5" -ClimaSeaIce = "0.3" +ClimaSeaIce = "0.3.1" CondaPkg = "0.2.28" CubicSplines = "0.2" DataDeps = "0.7" diff --git a/experiments/omip_prototype/sixth_degree_omip_nodynamics.jl b/experiments/omip_prototype/sixth_degree_omip_nodynamics.jl new file mode 100644 index 000000000..6e6aa7a56 --- /dev/null +++ b/experiments/omip_prototype/sixth_degree_omip_nodynamics.jl @@ -0,0 +1,233 @@ +using Pkg +Pkg.update() +using ClimaOcean +using ClimaSeaIce +using Oceananigans +using Oceananigans.Grids +using Oceananigans.Grids: AbstractGrid +using Oceananigans.Units +using Oceananigans.OrthogonalSphericalShellGrids +using ClimaOcean.OceanSimulations +using ClimaOcean.ECCO +using ClimaOcean.JRA55 +using ClimaOcean.DataWrangling +using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using Printf +using Dates +using CUDA +using Oceananigans.Fields: ConstantField +using Oceananigans.Operators + +import Oceananigans.OutputWriters: checkpointer_address +import Oceananigans.OutputWriters: saveproperty! + +saveproperty!(file, address, p::ConstantField) = file[address] = p + +checkpointer_address(::SeaIceModel) = "SeaIceModel" + +function synch!(clock1::Clock, clock2) + # Synchronize the clocks + clock1.time = clock2.time + clock1.iteration = clock2.iteration + clock1.last_Δt = clock2.last_Δt +end + +synch!(model1, model2) = synch!(model1.clock, model2.clock) + +arch = GPU() +r_faces = ClimaOcean.exponential_z_faces(; Nz=60, depth=6200) +z_faces = MutableVerticalDiscretization(r_faces) + +Nx = 2160 # longitudinal direction +Ny = 1080 # meridional direction +Nz = length(r_faces) - 1 + +grid = TripolarGrid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + halo = (7, 7, 7)) + +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=10) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +##### +##### A Propgnostic Ocean model +##### + +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation + +momentum_advection = WENOVectorInvariant() +tracer_advection = WENO(order=7) + +free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt=20minutes) + +# closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) +# closure = (ClimaOcean.OceanSimulations.default_ocean_closure(), VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) + +closure = RiBasedVerticalDiffusivity() + +ocean = ocean_simulation(grid; Δt=1minutes, + momentum_advection, + tracer_advection, + timestepper = :SplitRungeKutta3, + free_surface, + closure) + +dataset = ECCO4Monthly() + +set!(ocean.model, T=Metadatum(:temperature; dataset), + S=Metadatum(:salinity; dataset)) + +##### +##### A Prognostic Sea-ice model +##### + +sea_ice = sea_ice_simulation(grid, ocean; dynamics = nothing) #advection=WENO(order=7)) + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), + ℵ=Metadatum(:sea_ice_concentration; dataset)) + +# using JLD2 +# file = jldopen("sea_ice_checkpoint_iteration10000.jld2") +# parent(sea_ice.model.ice_thickness) .= CuArray(file["SeaIceModel/h/data"]) +# parent(sea_ice.model.ice_concentration) .= CuArray(file["SeaIceModel/ℵ/data"]) +# parent(sea_ice.model.velocities.u) .= CuArray(file["SeaIceModel/u/data"]) +# parent(sea_ice.model.velocities.v) .= CuArray(file["SeaIceModel/v/data"]) + +##### +##### A Prescribed Atmosphere model +##### + +dir = "./forcing_data" +dataset = MultiYearJRA55() +backend = JRA55NetCDFBackend(40) + +atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) +radiation = Radiation(sea_ice_albedo=0.7) + +##### +##### An ocean-sea ice coupled model +##### + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +omip = Simulation(omip, Δt=10, stop_time=Inf) + +synch!(sea_ice.model, ocean.model) +synch!(omip.model, ocean.model) + +# Figure out the outputs.... +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, + schedule = IterationInterval(10000), + prefix = "ocean_checkpoint", + overwrite_existing = true) + +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = IterationInterval(10000), + prefix = "sea_ice_checkpoint", + overwrite_existing = true) + +uo = ocean.model.velocities.u +vo = ocean.model.velocities.v +wo = ocean.model.velocities.w +T, S = ocean.model.tracers +η = ocean.model.free_surface.η + +ui = sea_ice.model.velocities.u +vi = sea_ice.model.velocities.v +h = sea_ice.model.ice_thickness +ℵ = sea_ice.model.ice_concentration + +omip.output_writers[:ocean_free_surface] = JLD2Writer(ocean.model, (; η), + schedule = TimeInterval(1days), + filename = "ocean_free_surface", + overwrite_existing = true) + +omip.output_writers[:ocean_surface_fields] = JLD2Writer(ocean.model, (; uo, vo, wo, T, S), + schedule = TimeInterval(1days), + filename = "ocean_surface_fields", + indices = (:, :, grid.Nz), + overwrite_existing = true) + +omip.output_writers[:sea_ice_surface_fields] = JLD2Writer(sea_ice.model, (; ui, vi, h, ℵ), + schedule = TimeInterval(1days), + filename = "sea_ice_surface_fields", + overwrite_existing = true) + +wall_time = Ref(time_ns()) + +using Statistics + +function progress(sim) + sea_ice = sim.model.sea_ice + ocean = sim.model.ocean + hmax = maximum(sea_ice.model.ice_thickness) + ℵmax = maximum(sea_ice.model.ice_concentration) + Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) + Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) + umax = maximum(abs, ocean.model.velocities.u) + vmax = maximum(abs, ocean.model.velocities.v) + uimax = maximum(abs, sea_ice.model.velocities.u) + vimax = maximum(abs, sea_ice.model.velocities.v) + wmax = maximum(ocean.model.velocities.w) + + step_time = 1e-9 * (time_ns() - wall_time[]) + + msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) + msg2 = @sprintf("max(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) + msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) + msg5 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) + msg6 = @sprintf("wall time: %s \n", prettytime(step_time)) + + @info msg1 * msg2 * msg4 * msg5 * msg6 + + wall_time[] = time_ns() + + return nothing +end + +# And add it as a callback to the simulation. +add_callback!(omip, progress, IterationInterval(50)) +wizard = TimeStepWizard(cfl=0.7, max_change=1.1, max_Δt=20minutes) + +function sea_ice_cell_advection_timescale(grid, velocities) + u, v = velocities + τ = KernelFunctionOperation{Center, Center, Center}(cell_advection_timescaleᶜᶜ, grid, u, v) + return minimum(τ) +end + +@inline _inverse_timescale(i, j, k, Δ⁻¹, U, topo) = @inbounds abs(U[i, j, k]) * Δ⁻¹ +@inline _inverse_timescale(i, j, k, Δ⁻¹, U, topo::Flat) = 0 + +@inline function cell_advection_timescaleᶜᶜ(i, j, k, grid::AbstractGrid{FT, TX, TY}, u, v) where {FT, TX, TY} + Δx⁻¹ = Δx⁻¹ᶠᶜᶜ(i, j, k, grid) + Δy⁻¹ = Δy⁻¹ᶜᶠᶜ(i, j, k, grid) + + inverse_timescale_x = _inverse_timescale(i, j, k, Δx⁻¹, u, TX()) + inverse_timescale_y = _inverse_timescale(i, j, k, Δy⁻¹, v, TY()) + + inverse_timescale = inverse_timescale_x + inverse_timescale_y + + return 1 / inverse_timescale +end + +function add_wizard!(sim) + wizard(sim.model.ocean) + sea_ice = sim.model.sea_ice + Δti = 0.15 * sea_ice_cell_advection_timescale(sea_ice.model.grid, sea_ice.model.velocities) + @info "Wizard says: ocean Δt: $(ocean.Δt), sea ice Δt: $(Δti)" + iter = sea_ice.model.clock.iteration + Δtw = min(ocean.Δt, Δti) + + if iter < 5000 + sim.Δt = 60 + else + sim.Δt = Δtw + end + + @info "Final Δt is $(sim.Δt)" +end + +omip.callbacks[:wizard] = Callback(add_wizard!, IterationInterval(10)) + +run!(omip) From c306b0f8d5436460117b182a43d4939a5e3a9b61 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 14 Jul 2025 10:57:39 +0200 Subject: [PATCH 108/203] retry like this --- experiments/omip_prototype/sixth_degree_omip.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl index 6a482bb02..86664769e 100644 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -93,7 +93,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), dir = "./forcing_data" dataset = MultiYearJRA55() -backend = JRA55NetCDFBackend(40) +backend = JRA55NetCDFBackend(100) atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) radiation = Radiation() @@ -154,7 +154,7 @@ add_callback!(omip, progress, IterationInterval(50)) run!(omip) -omip.Δt = 10minutes +omip.Δt = 6minutes omip.stop_time = 58 * 365days run!(omip) From 48576472cb6ca93e86f101145b6b4faed861f21d Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 14 Jul 2025 11:02:20 +0200 Subject: [PATCH 109/203] hmmm this was explicit --- experiments/omip_prototype/sixth_degree_omip.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl index 86664769e..de139f583 100644 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -55,7 +55,7 @@ free_surface = SplitExplicitFreeSurface(grid; substeps=70) mixing_length = CATKEMixingLength(Cᵇ=0.01) turbulent_kinetic_energy_equation = CATKEEquation(Cᵂϵ=1.0) -catke_closure = CATKEVerticalDiffusivity(ExplicitTimeDiscretization(); mixing_length, turbulent_kinetic_energy_equation) +catke_closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) ocean = ocean_simulation(grid; Δt=1minutes, From 668bc531ebed34259e15bcb6756b93332979934f Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 14 Jul 2025 11:30:58 +0200 Subject: [PATCH 110/203] use a fixed dt --- experiments/omip_prototype/sixth_degree_omip.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl index de139f583..df71b0f59 100644 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -50,7 +50,7 @@ using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVertic momentum_advection = WENOVectorInvariant() tracer_advection = WENO(order=7) -free_surface = SplitExplicitFreeSurface(grid; substeps=70) +free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt=10minutes) mixing_length = CATKEMixingLength(Cᵇ=0.01) turbulent_kinetic_energy_equation = CATKEEquation(Cᵂϵ=1.0) From dcce9e2a299a0058bccf91fd97bf227a273328b6 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 14 Jul 2025 11:35:16 +0200 Subject: [PATCH 111/203] update to new syntax --- experiments/omip_prototype/sixth_degree_omip.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl index df71b0f59..5dc82dc9e 100644 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -25,19 +25,20 @@ end synch!(model1, model2) = synch!(model1.clock, model2.clock) arch = GPU() -r_faces = ClimaOcean.exponential_z_faces(; Nz=60, depth=6200) -z_faces = MutableVerticalDiscretization(r_faces) Nx = 2160 # longitudinal direction Ny = 1080 # meridional direction -Nz = length(r_faces) - 1 +Nz = 60 + +r_faces = ClimaOcean.ExponentialCoordinate(Nz, -6000) +z_faces = MutableVerticalDiscretization(r_faces) grid = TripolarGrid(arch; size = (Nx, Ny, Nz), z = z_faces, halo = (7, 7, 7)) -bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1) +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=15) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) ##### From d5288c17cc7172adc5230a447a7f38c8c155ff8f Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 14 Jul 2025 12:13:25 +0200 Subject: [PATCH 112/203] go like this --- experiments/omip_prototype/sixth_degree_omip.jl | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl index 5dc82dc9e..c1339d82c 100644 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ b/experiments/omip_prototype/sixth_degree_omip.jl @@ -74,16 +74,8 @@ set!(ocean.model, T=Metadatum(:temperature; dataset), ##### A Prognostic Sea-ice model ##### -# Remember to pass the SSS as a bottom bc to the sea ice! -SSS = view(ocean.model.tracers.S.data, :, :, grid.Nz) -bottom_heat_boundary_condition = IceWaterThermalEquilibrium(SSS) - -# Default sea-ice dynamics -sea_ice_dynamics = ClimaOcean.SeaIceSimulations.default_sea_ice_dynamics(grid; ocean) - -sea_ice = sea_ice_simulation(grid; bottom_heat_boundary_condition, - dynamics = sea_ice_dynamics, - advection=WENO(order=7)) +# Default sea-ice dynamics and salinity coupling are included in the defaults +sea_ice = sea_ice_simulation(grid; advection=WENO(order=7)) set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), ℵ=Metadatum(:sea_ice_concentration; dataset)) From 13221489dbaae0856383b57aa170f2d0d5fd741f Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 14 Jul 2025 12:31:26 +0200 Subject: [PATCH 113/203] add a one-degree to test it out --- experiments/omip_prototype/one_degree_omip.jl | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 experiments/omip_prototype/one_degree_omip.jl diff --git a/experiments/omip_prototype/one_degree_omip.jl b/experiments/omip_prototype/one_degree_omip.jl new file mode 100644 index 000000000..038d49ca1 --- /dev/null +++ b/experiments/omip_prototype/one_degree_omip.jl @@ -0,0 +1,153 @@ +using ClimaOcean +using ClimaSeaIce +using Oceananigans +using Oceananigans.Grids +using Oceananigans.Units +using Oceananigans.OrthogonalSphericalShellGrids +using ClimaOcean.OceanSimulations +using ClimaOcean.ECCO +using ClimaOcean.JRA55 +using ClimaOcean.DataWrangling +using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using Printf +using Dates +using CUDA + +import Oceananigans.OutputWriters: checkpointer_address + +function synch!(clock1::Clock, clock2) + # Synchronize the clocks + clock1.time = clock2.time + clock1.iteration = clock2.iteration + clock1.last_Δt = clock2.last_Δt +end + +synch!(model1, model2) = synch!(model1.clock, model2.clock) + +arch = GPU() + +Nx = 360 # longitudinal direction +Ny = 180 # meridional direction +Nz = 60 + +r_faces = ClimaOcean.ExponentialCoordinate(Nz, -6000) +z_faces = MutableVerticalDiscretization(r_faces) + +grid = TripolarGrid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + halo = (7, 7, 7)) + +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=15) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +##### +##### A Propgnostic Ocean model +##### + +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation + +momentum_advection = WENOVectorInvariant(order=5) +tracer_advection = WENO(order=5) + +free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt=20minutes) + +mixing_length = CATKEMixingLength(Cᵇ=0.01) +turbulent_kinetic_energy_equation = CATKEEquation(Cᵂϵ=1.0) + +catke_closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) +closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) + +ocean = ocean_simulation(grid; Δt=1minutes, + momentum_advection, + tracer_advection, + free_surface, + closure) + +dataset = ECCO4Monthly() + +set!(ocean.model, T=Metadatum(:temperature; dataset), + S=Metadatum(:salinity; dataset)) + +##### +##### A Prognostic Sea-ice model +##### + +# Default sea-ice dynamics and salinity coupling are included in the defaults +sea_ice = sea_ice_simulation(grid; advection=WENO(order=7)) + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), + ℵ=Metadatum(:sea_ice_concentration; dataset)) + +##### +##### A Prescribed Atmosphere model +##### + +dir = "./forcing_data" +dataset = MultiYearJRA55() +backend = JRA55NetCDFBackend(100) + +atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) +radiation = Radiation() + +##### +##### An ocean-sea ice coupled model +##### + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +omip = Simulation(omip, Δt=30, stop_time=60days) + +# Figure out the outputs.... + +checkpointer_address(::SeaIceModel) = "SeaIceModel" + +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, + schedule = IterationInterval(10000), + prefix = "ocean_checkpoint_onedegree", + overwrite_existing = true) + +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = IterationInterval(10000), + prefix = "sea_ice_checkpoint_onedegree", + overwrite_existing = true) + +wall_time = Ref(time_ns()) + +using Statistics + +function progress(sim) + sea_ice = sim.model.sea_ice + ocean = sim.model.ocean + hmax = maximum(sea_ice.model.ice_thickness) + ℵmax = maximum(sea_ice.model.ice_concentration) + Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) + Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) + umax = maximum(ocean.model.velocities.u) + vmax = maximum(ocean.model.velocities.v) + wmax = maximum(ocean.model.velocities.w) + + step_time = 1e-9 * (time_ns() - wall_time[]) + + msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) + msg2 = @sprintf("max(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) + msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) + msg5 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) + msg6 = @sprintf("wall time: %s \n", prettytime(step_time)) + + @info msg1 * msg2 * msg4 * msg5 * msg6 + + wall_time[] = time_ns() + + return nothing +end + +# And add it as a callback to the simulation. +add_callback!(omip, progress, IterationInterval(50)) + +run!(omip) + +omip.Δt = 15minutes +omip.stop_time = 58 * 365days + +run!(omip) From 2490da24ee6b5c4c7b7deeed5970fbc250a74594 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 15 Jul 2025 10:43:04 +0200 Subject: [PATCH 114/203] Update one_degree_simulation.jl --- examples/one_degree_simulation.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index 65e3acf6f..2d30ae6bb 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -26,7 +26,8 @@ Ny = 180 Nz = 40 depth = 4000meters -z = ExponentialCoordinate(Nz, -depth; scale = 0.85*depth) +r = ExponentialCoordinate(Nz, -depth; scale = 0.85*depth) +z = Oceananigans.Grids.MutableVerticalDiscretization(r) underlying_grid = TripolarGrid(arch; size = (Nx, Ny, Nz), halo = (5, 5, 4), z) # Next, we build bathymetry on this grid, using interpolation passes to smooth the bathymetry. From c411c7167224034bb9aa3be30b853dc9df8dc1a1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 15 Jul 2025 10:44:04 +0200 Subject: [PATCH 115/203] Update one_degree_simulation.jl --- examples/one_degree_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index 2d30ae6bb..bfc3d8512 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -26,8 +26,8 @@ Ny = 180 Nz = 40 depth = 4000meters -r = ExponentialCoordinate(Nz, -depth; scale = 0.85*depth) -z = Oceananigans.Grids.MutableVerticalDiscretization(r) +z = ExponentialCoordinate(Nz, -depth; scale = 0.85*depth) +z = Oceananigans.Grids.MutableVerticalDiscretization(z) underlying_grid = TripolarGrid(arch; size = (Nx, Ny, Nz), halo = (5, 5, 4), z) # Next, we build bathymetry on this grid, using interpolation passes to smooth the bathymetry. From f762205d4f574ba59c5cb0810f2f7e091c944fd7 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 11:30:16 +0200 Subject: [PATCH 116/203] try without implicit solver --- examples/one_degree_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index bfc3d8512..765bc4c9e 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -52,7 +52,7 @@ grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height); eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=2e3, κ_symmetric=2e3) horizontal_viscosity = HorizontalScalarDiffusivity(ν=4000) -vertical_mixing = Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivity(minimum_tke=1e-6) +vertical_mixing = Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivity(Oceananigans.TurbulenceClosures.ExplicitTimeDiscretization(), minimum_tke=1e-6) # ### Ocean simulation # Now we bring everything together to construct the ocean simulation. From 759c1ac31cf93d3658ad23b190887dc079f67f2d Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 11:57:58 +0200 Subject: [PATCH 117/203] Update Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index f31d23962..edc3c208f 100644 --- a/Project.toml +++ b/Project.toml @@ -55,7 +55,7 @@ JLD2 = "0.4, 0.5" KernelAbstractions = "0.9" MPI = "0.20" NCDatasets = "0.12, 0.13, 0.14" -Oceananigans = "0.96" +Oceananigans = "0.97" OffsetArrays = "1.14" PrecompileTools = "1" PythonCall = "0.9" From 01e9f05aea705bd0c3db79e415a43598bd1eaa53 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 11:58:10 +0200 Subject: [PATCH 118/203] Update near_global_ocean_simulation.jl --- examples/near_global_ocean_simulation.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index b50150239..f1426c04a 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -20,6 +20,7 @@ using CairoMakie using CFTime using Dates using Printf +using CUDA # ### Grid configuration # From e48a2b548b987424b5a4d0c6554a84b100553407 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 11:58:20 +0200 Subject: [PATCH 119/203] Update one_degree_simulation.jl --- examples/one_degree_simulation.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index 65e3acf6f..4cf4d92cc 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -15,6 +15,7 @@ using Oceananigans.Units using Dates using Printf using Statistics +using CUDA # ### Grid and Bathymetry From 0765874310053ea4218c96ba7c13a7da5c721822 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 12:01:04 +0200 Subject: [PATCH 120/203] changes --- .../distributed_perfect_one_degree_model_calibration.jl | 1 - .../one_degree_calibration/gm_one_degree_model_calibration.jl | 1 - .../perfect_one_degree_model_calibration.jl | 1 - src/DataWrangling/JRA55/JRA55.jl | 1 - 4 files changed, 4 deletions(-) diff --git a/experiments/one_degree_calibration/distributed_perfect_one_degree_model_calibration.jl b/experiments/one_degree_calibration/distributed_perfect_one_degree_model_calibration.jl index e0aa4f853..e23b6b532 100644 --- a/experiments/one_degree_calibration/distributed_perfect_one_degree_model_calibration.jl +++ b/experiments/one_degree_calibration/distributed_perfect_one_degree_model_calibration.jl @@ -1,5 +1,4 @@ using Oceananigans -using Oceananigans.Architectures: arch_array using Oceananigans.Units using Oceananigans.Utils: WallTimeInterval using Oceananigans.BuoyancyFormulations: buoyancy diff --git a/experiments/one_degree_calibration/gm_one_degree_model_calibration.jl b/experiments/one_degree_calibration/gm_one_degree_model_calibration.jl index 81a8592a4..1b5c5bb83 100644 --- a/experiments/one_degree_calibration/gm_one_degree_model_calibration.jl +++ b/experiments/one_degree_calibration/gm_one_degree_model_calibration.jl @@ -1,5 +1,4 @@ using Oceananigans -using Oceananigans.Architectures: arch_array using Oceananigans.Units using Oceananigans.Grids: on_architecture using Oceananigans.Utils: WallTimeInterval diff --git a/experiments/one_degree_calibration/perfect_one_degree_model_calibration.jl b/experiments/one_degree_calibration/perfect_one_degree_model_calibration.jl index 665e9e3f4..a258714fb 100644 --- a/experiments/one_degree_calibration/perfect_one_degree_model_calibration.jl +++ b/experiments/one_degree_calibration/perfect_one_degree_model_calibration.jl @@ -1,5 +1,4 @@ using Oceananigans -using Oceananigans.Architectures: arch_array using Oceananigans.Units using Oceananigans.Utils: WallTimeInterval using Oceananigans.BuoyancyFormulations: buoyancy diff --git a/src/DataWrangling/JRA55/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl index 34dc0097d..a3e45fec7 100644 --- a/src/DataWrangling/JRA55/JRA55.jl +++ b/src/DataWrangling/JRA55/JRA55.jl @@ -5,7 +5,6 @@ export JRA55FieldTimeSeries, JRA55PrescribedAtmosphere, RepeatYearJRA55, MultiYe using Oceananigans using Oceananigans.Units -using Oceananigans.Architectures: arch_array using Oceananigans.DistributedComputations using Oceananigans.DistributedComputations: child_architecture using Oceananigans.BoundaryConditions: fill_halo_regions! From 808e6c9002822bf94694000871c7d68984a9e4a3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 12:26:57 +0200 Subject: [PATCH 121/203] try it in both --- examples/near_global_ocean_simulation.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index b50150239..1cef62776 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -36,6 +36,7 @@ Nz = 40 depth = 6000meters z = ExponentialCoordinate(Nz, -depth) +z = Oceananigans.Grids.MutableVerticalDiscretization(z) grid = LatitudeLongitudeGrid(arch; size = (Nx, Ny, Nz), From 7cacb1da895a74eebde30226e74762cd3ba6fefe Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 16:22:25 +0200 Subject: [PATCH 122/203] adding the correct zstar branch --- Manifest.toml | 1547 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1547 insertions(+) create mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 000000000..458282b5d --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,1547 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.10" +manifest_format = "2.0" +project_hash = "bb09aa984e1a9dbd83743fc29ea3d49437328c99" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + + [deps.AbstractFFTs.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] +git-tree-sha1 = "3b86719127f50670efe356bc11073d84b4ed7a5d" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.42" + + [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 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.3.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "f87e559f87a45bece9c9ed97458d3afe98b1ebb9" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.1.0" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra"] +git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.19.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = "CUDSS" + ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + 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" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "b5bb4dc6248fde467be2a863eb8452993e74d402" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "1.1.1" + + [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.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random"] +git-tree-sha1 = "3b642331600250f592719140c60cf12372b82d66" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.1" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BitTwiddlingConvenienceFunctions]] +deps = ["Static"] +git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" +uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" +version = "0.1.6" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "535c80f1c0847a4c967ea945fca21becc9de1522" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.7+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "937628bf8b377208ac359f57314fd85d3e0165d9" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.4" + +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] +git-tree-sha1 = "5a97e67919535d6841172016c9530fd69494e5ec" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.6" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] +git-tree-sha1 = "b8ae59258f3d96ce75a00f9229e719356eb929d6" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.8.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_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "18afa851ed10552e6df25dfaa7ef450104ae73d4" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.13.1+0" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "33576c7c1b2500f8e7e6baa082e04563203b3a45" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.3.5" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "b5c173a64f9f4224a82fdc26fda8614cb2ecfa27" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.17.1+0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "8166751d954fdaa2e9fe183ad1a24b01343d422f" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.3.1" + +[[deps.CloseOpenIntervals]] +deps = ["Static", "StaticArrayInterface"] +git-tree-sha1 = "05ba0d07cd4fd8b7a39541e31a7b0254704ea581" +uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" +version = "0.1.13" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "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" + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + + [deps.ColorTypes.weakdeps] + StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" + +[[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", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "358bf5a7d5c1387b995a43577673290c5d344758" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.8" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[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 = "3a3dfb30697e96a440e4149c8c51bf32f818c0f3" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.17.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.1+0" + +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.ConstructionBase]] +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.6.0" + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" + ConstructionBaseStaticArraysExt = "StaticArrays" + + [deps.ConstructionBase.weakdeps] + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.CpuId]] +deps = ["Markdown"] +git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" +uuid = "adafc99b-e345-5852-983c-f28acb93d879" +version = "0.3.1" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["TaylorSeries"] +git-tree-sha1 = "afe9e8c11bf816a6fee878ddfc661e0bd138b747" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.3.2" + +[[deps.CubicSplines]] +deps = ["Random", "Test"] +git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" +uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" +version = "0.2.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "fb61b4812c49343d7ef0b533ba982c46021938a6" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.7.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DiskArrays]] +deps = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] +git-tree-sha1 = "16d93ff95ecc421463eaefd694e6746bb1c0919e" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.4.14" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.12" + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + + [deps.Distances.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.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 = "4a8c0a9eebf807ac42f0f6de758e60a20be25ffb" +uuid = "21656369-7473-754a-2065-74616d696c43" +version = "1.1.3" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "797762812ed063b9b94f6cc7742bc8883bb5e69e" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.9.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.11+0" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "b66970a70db13f45b7e57fbda1736e1cf72174ea" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.17.0" +weakdeps = ["HTTP"] + + [deps.FileIO.extensions] + HTTPExt = "HTTP" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.0.1" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "Statistics"] +git-tree-sha1 = "be941842a40b6daac98496994ea69054ba4c5144" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "11.2.3" + +[[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 = "eb1e212e12cc058fa16712082d44be499d23638c" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "1.6.1" + +[[deps.GPUToolbox]] +git-tree-sha1 = "15d8b0f5a6dca9bf8c02eeaf6687660dafa638d0" +uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" +version = "0.2.0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "e94f84da9af7ce9c6be049e9067e511e17ff89ec" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.6+0" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "ed5e9c58612c4e081aecdb6e1a479e18462e041e" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.17" + +[[deps.HashArrayMappedTries]] +git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" +uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" +version = "0.2.0" + +[[deps.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] +git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.17" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.12.1+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 = "cffa21df12f00ca1a365eb8ed107614b40e8c6da" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.4.6" + +[[deps.Inflate]] +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.InlineStrings]] +git-tree-sha1 = "8594fac023c5ce1ef78260f24d1ad18b4327b420" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.4" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + ParsersExt = "Parsers" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "0f14a5456bdc6b9731a5682f439a672750a09e48" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2025.0.4+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[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 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.4" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] +git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.5.15" +weakdeps = ["UnPack"] + + [deps.JLD2.extensions] + UnPackExt = "UnPack" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.0" + +[[deps.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] +git-tree-sha1 = "38a03910123867c11af988e8718d12c98bf6a234" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.37" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + LinearAlgebraExt = "LinearAlgebra" + SparseArraysExt = "SparseArrays" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.Krylov]] +deps = ["LinearAlgebra", "Printf", "SparseArrays"] +git-tree-sha1 = "b94257a1a8737099ca40bc7271a8b374033473ed" +uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" +version = "0.10.1" + +[[deps.KrylovPreconditioners]] +deps = ["Adapt", "KernelAbstractions", "LightGraphs", "LinearAlgebra", "Metis", "SparseArrays"] +git-tree-sha1 = "52d302d5e950e242f037316b6dd6e1e080afea09" +uuid = "45d422c2-293f-44ce-8315-2cb988662dec" +version = "0.3.4" + + [deps.KrylovPreconditioners.extensions] + KrylovPreconditionersAMDGPUExt = "AMDGPU" + KrylovPreconditionersCUDAExt = "CUDA" + KrylovPreconditionersOneAPIExt = "oneAPI" + + [deps.KrylovPreconditioners.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] +git-tree-sha1 = "9c7c721cfd800d87d48c745d8bfb65144f0a91df" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "9.4.2" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "2ea068aac1e7f0337d381b0eae3110581e3f3216" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.37+2" + +[[deps.LLVMLoopInfo]] +git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" +uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" +version = "1.0.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" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.LibTracyClient_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d2bc4e1034b2d43076b50f0e34ea094c2cb0a717" +uuid = "ad6e5548-8b26-5c9f-8ef3-ef0ad883f3a5" +version = "0.9.1+6" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.LightGraphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "432428df5f360964040ed60418dd5601ecd240b6" +uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" +version = "1.3.5" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[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" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f02b56007b064fbfddb4c9cd60161b6dd0f40df3" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.1.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 = "e5afce7eaf5b5ca0d444bcb4dc4fd78c54cbbac0" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.172" + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + SpecialFunctionsExt = "SpecialFunctions" + + [deps.LoopVectorization.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "191686b1ac1ea9c89fc52e996ad15d1d241d1e33" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.10.1+0" + +[[deps.METIS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2eefa8baa858871ae7770c98c3c2a7e46daba5b4" +uuid = "d00139f3-1899-568f-a2f0-47f597d42d70" +version = "5.1.3+0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "5de60bc6cb3899cd318d80d627560fae2e2d99ae" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2025.0.1+1" + +[[deps.MPI]] +deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "892676019c58f34e38743bc989b0eca5bce5edc5" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.22" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.3.1+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.11" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.5.4+0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.Metis]] +deps = ["CEnum", "LinearAlgebra", "METIS_jll", "SparseArrays"] +git-tree-sha1 = "54aca4fd53d39dcd2c3f1bef367b6921e8178628" +uuid = "2679e427-3c69-5b7f-982b-ece356f1e94b" +version = "1.5.0" + + [deps.Metis.extensions] + MetisGraphs = "Graphs" + MetisLightGraphs = "LightGraphs" + MetisSimpleWeightedGraphs = ["SimpleWeightedGraphs", "Graphs"] + + [deps.Metis.weakdeps] + Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" + LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" + SimpleWeightedGraphs = "47aef6b3-ad0c-573a-a1e2-d07658019622" + +[[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" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.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 = "be1095e2b767c19529409ec670bcfb01b825d717" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.8" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "1a24c3430fa2ef3317c4c97fa7e431ef45793bd2" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "1.0.0" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "cd475b587ff77910789a18e68da789fc446a2a05" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.2.1+0" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML", "XML2_jll", "Zlib_jll", "Zstd_jll", "libaec_jll", "libzip_jll"] +git-tree-sha1 = "d574803b6055116af212434460adf654ce98e345" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "401.900.300+0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Oceananigans]] +deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "2b66db77b748719e83444423b3c1d5112dabb7e9" +repo-rev = "ss/fix-zstar-bc" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.97.0" + + [deps.Oceananigans.extensions] + OceananigansAMDGPUExt = "AMDGPU" + OceananigansCUDAExt = "CUDA" + OceananigansEnzymeExt = "Enzyme" + OceananigansMakieExt = ["MakieCore", "Makie"] + OceananigansMetalExt = "Metal" + OceananigansNCDatasetsExt = "NCDatasets" + OceananigansOneAPIExt = "oneAPI" + OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase"] + + [deps.Oceananigans.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" + Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" + 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.23+4" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.5+0" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] +git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.8+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "87510f7292a2b21aeff97912b0898f9553cc5c2c" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+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.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PolyesterWeave]] +deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] +git-tree-sha1 = "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 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.4.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.6" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Random123]] +deps = ["Random", "RandomNumbers"] +git-tree-sha1 = "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.ReactantCore]] +deps = ["ExpressionExplorer", "MacroTools"] +git-tree-sha1 = "120feaf6a97738e3a63902644a0afb3b69cc7b98" +uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" +version = "0.1.15" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.RootSolvers]] +deps = ["ForwardDiff", "Printf"] +git-tree-sha1 = "892b77767827af30868111d257930f567d5d78f8" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.4" + +[[deps.Roots]] +deps = ["Accessors", "CommonSolve", "Printf"] +git-tree-sha1 = "668e411c0616a70860249b4c96e5d35296631a1d" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.2.8" + + [deps.Roots.extensions] + RootsChainRulesCoreExt = "ChainRulesCore" + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + + [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" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.1" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SIMDTypes]] +git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" +uuid = "94e857df-77ce-4151-89e5-788b33177be4" +version = "0.1.0" + +[[deps.SLEEFPirates]] +deps = ["IfElse", "Static", "VectorizationBase"] +git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.43" + +[[deps.ScopedValues]] +deps = ["HashArrayMappedTries", "Logging"] +git-tree-sha1 = "7f44eef6b1d284465fafc66baf4d9bdcc239a15b" +uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" +version = "1.4.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 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.8" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.5.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "be1cf4eb0ac528d96f5115b4ed80c26a8d8ae621" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.2" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] +git-tree-sha1 = "f737d444cb0ad07e61b3c1bef8eb91203c321eff" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.2.0" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] +git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.8.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "cbea8a6bd7bed51b1619658dec70035e07b8502f" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.14" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.4.1" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "8ad2e38cbb812e29348719cc63580ec1dfeb9de4" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.7.1" +weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = ["GPUArraysCore", "KernelAbstractions"] + StructArraysLinearAlgebraExt = "LinearAlgebra" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "aee530bde85cd41374273568cb649e72d82921e7" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.12.0" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "ClimaParams" + + [deps.SurfaceFluxes.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "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 = "2c308aab2e14b399e4b8d6af7c486a241c8ca87a" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.19.1" + + [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" + +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "94f0e8e3135840568082e62fb69d31669539e627" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.14" + + [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 = "91dbaee0f50faa4357f7e9fc69442c7b6364dfe5" +uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" +version = "0.1.5" + + [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" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "b13c4edda90890e5b04ba24e20a310fbe6f249ff" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.3.0" +weakdeps = ["LLVM"] + + [deps.UnsafeAtomics.extensions] + UnsafeAtomicsLLVM = ["LLVM"] + +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "4ab62a49f1d8d9548a1c8d1a75e5f55cf196f64e" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.71" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "b8b243e47228b4a3877f1dd6aee0c5d56db7fcf4" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.13.6+1" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.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.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.demumble_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6498e3581023f8e530f34760d18f75a69e3a4ea8" +uuid = "1e29f10c-031c-5a83-9565-69cddfc27673" +version = "1.3.0+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f5733a5a9047722470b95a81e1b172383971105c" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.1.3+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.11.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.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2022.0.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" From 7cb8d6b2ea93a575933de92e99bf87c323313464 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 17:52:02 +0200 Subject: [PATCH 123/203] added CUDA --- .buildkite/examples_build.yml | 2 +- .buildkite/pipeline.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index 66d2197e3..60cece10e 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -18,7 +18,7 @@ steps: TMPDIR: "$TARTARUS_HOME/tmp" command: - "echo '--- Instantiate project'" - - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using Pkg; Pkg.instantiate(; verbose=true); Pkg.precompile(; strict=true)'" + - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using Pkg; Pkg.add("CUDA"); Pkg.instantiate(; verbose=true); Pkg.precompile(; strict=true)'" # force the initialization of the CUDA runtime as it is lazily loaded by default - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using CUDA; CUDA.precompile_runtime()'" agents: diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 136eefb90..0198227e7 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -17,7 +17,7 @@ steps: TEST_GROUP: "init" command: - "echo '--- Instantiate project'" - - "julia --project -e 'using Pkg; Pkg.instantiate(verbose=true)'" + - "julia --project -e 'using Pkg; pkg.add("CUDA"); Pkg.instantiate(verbose=true)'" - "echo '--- Precompile project'" - "julia --project -e 'using Pkg; Pkg.precompile(strict=true)'" From 469883ac9c3e436e3d54f2d9bd256aafad217253 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 17:53:00 +0200 Subject: [PATCH 124/203] Update pipeline.yml --- .buildkite/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 0198227e7..1175bdc42 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -17,7 +17,7 @@ steps: TEST_GROUP: "init" command: - "echo '--- Instantiate project'" - - "julia --project -e 'using Pkg; pkg.add("CUDA"); Pkg.instantiate(verbose=true)'" + - "julia --project -e 'using Pkg; Pkg.add("CUDA"); Pkg.instantiate(verbose=true)'" - "echo '--- Precompile project'" - "julia --project -e 'using Pkg; Pkg.precompile(strict=true)'" From 86d0bcee5986eab01a40e0062d38e44b35d0a0f2 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 17 Jul 2025 17:57:57 +0200 Subject: [PATCH 125/203] revert CUDA --- .buildkite/examples_build.yml | 2 +- .buildkite/pipeline.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index 60cece10e..66d2197e3 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -18,7 +18,7 @@ steps: TMPDIR: "$TARTARUS_HOME/tmp" command: - "echo '--- Instantiate project'" - - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using Pkg; Pkg.add("CUDA"); Pkg.instantiate(; verbose=true); Pkg.precompile(; strict=true)'" + - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using Pkg; Pkg.instantiate(; verbose=true); Pkg.precompile(; strict=true)'" # force the initialization of the CUDA runtime as it is lazily loaded by default - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using CUDA; CUDA.precompile_runtime()'" agents: diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 1175bdc42..136eefb90 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -17,7 +17,7 @@ steps: TEST_GROUP: "init" command: - "echo '--- Instantiate project'" - - "julia --project -e 'using Pkg; Pkg.add("CUDA"); Pkg.instantiate(verbose=true)'" + - "julia --project -e 'using Pkg; Pkg.instantiate(verbose=true)'" - "echo '--- Precompile project'" - "julia --project -e 'using Pkg; Pkg.precompile(strict=true)'" From 509d6b4dca42ac2c9047132c76630bf3299af2f2 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 04:50:04 +1000 Subject: [PATCH 126/203] enforce using a specific branch --- docs/Project.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/Project.toml b/docs/Project.toml index 6d6b0f999..6c8568237 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -16,3 +16,6 @@ Documenter = "1" DocumenterCitations = "1.3" Oceananigans = "0.96 - 0.99" SeawaterPolynomials = "0.3.5" + +[sources] +Oceananigans = {url = "https://github.com/CliMA/Oceananigans.jl", rev = "ss/fix-zstar-bc"} From 308c9e355b3e919036b864a6fa3fef282596797d Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 04:50:27 +1000 Subject: [PATCH 127/203] Delete Manifest.toml --- Manifest.toml | 1547 ------------------------------------------------- 1 file changed, 1547 deletions(-) delete mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index 458282b5d..000000000 --- a/Manifest.toml +++ /dev/null @@ -1,1547 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.10" -manifest_format = "2.0" -project_hash = "bb09aa984e1a9dbd83743fc29ea3d49437328c99" - -[[deps.AbstractFFTs]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.5.0" - - [deps.AbstractFFTs.extensions] - AbstractFFTsChainRulesCoreExt = "ChainRulesCore" - AbstractFFTsTestExt = "Test" - - [deps.AbstractFFTs.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "3b86719127f50670efe356bc11073d84b4ed7a5d" -uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.42" - - [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 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.3.0" -weakdeps = ["SparseArrays", "StaticArrays"] - - [deps.Adapt.extensions] - AdaptSparseArraysExt = "SparseArrays" - AdaptStaticArraysExt = "StaticArrays" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.ArnoldiMethod]] -deps = ["LinearAlgebra", "Random", "StaticArrays"] -git-tree-sha1 = "f87e559f87a45bece9c9ed97458d3afe98b1ebb9" -uuid = "ec485272-7323-5ecc-a04f-4719b315124d" -version = "0.1.0" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.19.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = "CUDSS" - ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceSparseArraysExt = "SparseArrays" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - 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" - -[[deps.Atomix]] -deps = ["UnsafeAtomics"] -git-tree-sha1 = "b5bb4dc6248fde467be2a863eb8452993e74d402" -uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" -version = "1.1.1" - - [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.BFloat16s]] -deps = ["LinearAlgebra", "Printf", "Random"] -git-tree-sha1 = "3b642331600250f592719140c60cf12372b82d66" -uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" -version = "0.5.1" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[deps.BitFlags]] -git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.9" - -[[deps.BitTwiddlingConvenienceFunctions]] -deps = ["Static"] -git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" -uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" -version = "0.1.6" - -[[deps.Blosc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "535c80f1c0847a4c967ea945fca21becc9de1522" -uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" -version = "1.21.7+0" - -[[deps.Bzip2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" -uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.9+0" - -[[deps.CEnum]] -git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" -uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.5.0" - -[[deps.CFTime]] -deps = ["Dates", "Printf"] -git-tree-sha1 = "937628bf8b377208ac359f57314fd85d3e0165d9" -uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.1.4" - -[[deps.CPUSummary]] -deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "5a97e67919535d6841172016c9530fd69494e5ec" -uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.6" - -[[deps.CUDA]] -deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] -git-tree-sha1 = "b8ae59258f3d96ce75a00f9229e719356eb929d6" -uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.8.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_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "18afa851ed10552e6df25dfaa7ef450104ae73d4" -uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.13.1+0" - -[[deps.CUDA_Runtime_Discovery]] -deps = ["Libdl"] -git-tree-sha1 = "33576c7c1b2500f8e7e6baa082e04563203b3a45" -uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.3.5" - -[[deps.CUDA_Runtime_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "b5c173a64f9f4224a82fdc26fda8614cb2ecfa27" -uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.17.1+0" - -[[deps.ClimaSeaIce]] -deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "8166751d954fdaa2e9fe183ad1a24b01343d422f" -uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.3.1" - -[[deps.CloseOpenIntervals]] -deps = ["Static", "StaticArrayInterface"] -git-tree-sha1 = "05ba0d07cd4fd8b7a39541e31a7b0254704ea581" -uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" -version = "0.1.13" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "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" - - [deps.ColorTypes.extensions] - StyledStringsExt = "StyledStrings" - - [deps.ColorTypes.weakdeps] - StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" - -[[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", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "358bf5a7d5c1387b995a43577673290c5d344758" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.8" - -[[deps.CommonSolve]] -git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" -uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.4" - -[[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 = "3a3dfb30697e96a440e4149c8c51bf32f818c0f3" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.17.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.1+0" - -[[deps.CompositionsBase]] -git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" -uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" -version = "0.1.2" -weakdeps = ["InverseFunctions"] - - [deps.CompositionsBase.extensions] - CompositionsBaseInverseFunctionsExt = "InverseFunctions" - -[[deps.ConcurrentUtilities]] -deps = ["Serialization", "Sockets"] -git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.5.0" - -[[deps.ConstructionBase]] -git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.6.0" - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseLinearAlgebraExt = "LinearAlgebra" - ConstructionBaseStaticArraysExt = "StaticArrays" - - [deps.ConstructionBase.weakdeps] - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.CpuId]] -deps = ["Markdown"] -git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" -uuid = "adafc99b-e345-5852-983c-f28acb93d879" -version = "0.3.1" - -[[deps.Crayons]] -git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" -uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" -version = "4.1.1" - -[[deps.CubedSphere]] -deps = ["TaylorSeries"] -git-tree-sha1 = "afe9e8c11bf816a6fee878ddfc661e0bd138b747" -uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.3.2" - -[[deps.CubicSplines]] -deps = ["Random", "Test"] -git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" -uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" -version = "0.2.1" - -[[deps.DataAPI]] -git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.16.0" - -[[deps.DataDeps]] -deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] -git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" -uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.13" - -[[deps.DataFrames]] -deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "fb61b4812c49343d7ef0b533ba982c46021938a6" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.7.0" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.22" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.DiffResults]] -deps = ["StaticArraysCore"] -git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "1.1.0" - -[[deps.DiffRules]] -deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.15.1" - -[[deps.DiskArrays]] -deps = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] -git-tree-sha1 = "16d93ff95ecc421463eaefd694e6746bb1c0919e" -uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.4.14" - -[[deps.Distances]] -deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.12" - - [deps.Distances.extensions] - DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesSparseArraysExt = "SparseArrays" - - [deps.Distances.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[deps.DocStringExtensions]] -git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.5" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.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 = "4a8c0a9eebf807ac42f0f6de758e60a20be25ffb" -uuid = "21656369-7473-754a-2065-74616d696c43" -version = "1.1.3" - -[[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "797762812ed063b9b94f6cc7742bc8883bb5e69e" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.9.0" - -[[deps.FFTW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" -uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.11+0" - -[[deps.FileIO]] -deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "b66970a70db13f45b7e57fbda1736e1cf72174ea" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.17.0" -weakdeps = ["HTTP"] - - [deps.FileIO.extensions] - HTTPExt = "HTTP" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.0.1" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[deps.GPUArrays]] -deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "Statistics"] -git-tree-sha1 = "be941842a40b6daac98496994ea69054ba4c5144" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "11.2.3" - -[[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 = "eb1e212e12cc058fa16712082d44be499d23638c" -uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "1.6.1" - -[[deps.GPUToolbox]] -git-tree-sha1 = "15d8b0f5a6dca9bf8c02eeaf6687660dafa638d0" -uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" -version = "0.2.0" - -[[deps.Glob]] -git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" -uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" -version = "1.3.1" - -[[deps.HDF5_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] -git-tree-sha1 = "e94f84da9af7ce9c6be049e9067e511e17ff89ec" -uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" -version = "1.14.6+0" - -[[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "ed5e9c58612c4e081aecdb6e1a479e18462e041e" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.17" - -[[deps.HashArrayMappedTries]] -git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" -uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" -version = "0.2.0" - -[[deps.HostCPUFeatures]] -deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] -git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" -uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.17" - -[[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.12.1+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 = "cffa21df12f00ca1a365eb8ed107614b40e8c6da" -uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" -version = "0.4.6" - -[[deps.Inflate]] -git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.5" - -[[deps.InlineStrings]] -git-tree-sha1 = "8594fac023c5ce1ef78260f24d1ad18b4327b420" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.4" - - [deps.InlineStrings.extensions] - ArrowTypesExt = "ArrowTypes" - ParsersExt = "Parsers" - - [deps.InlineStrings.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "0f14a5456bdc6b9731a5682f439a672750a09e48" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2025.0.4+0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[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 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.4" - -[[deps.IterativeSolvers]] -deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] -git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" -uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" -version = "0.9.4" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] -git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.5.15" -weakdeps = ["UnPack"] - - [deps.JLD2.extensions] - UnPackExt = "UnPack" - -[[deps.JLLWrappers]] -deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.7.0" - -[[deps.JuliaNVTXCallbacks_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" -uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" -version = "0.2.1+0" - -[[deps.KernelAbstractions]] -deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] -git-tree-sha1 = "38a03910123867c11af988e8718d12c98bf6a234" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.37" - - [deps.KernelAbstractions.extensions] - EnzymeExt = "EnzymeCore" - LinearAlgebraExt = "LinearAlgebra" - SparseArraysExt = "SparseArrays" - - [deps.KernelAbstractions.weakdeps] - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[deps.Krylov]] -deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "b94257a1a8737099ca40bc7271a8b374033473ed" -uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.10.1" - -[[deps.KrylovPreconditioners]] -deps = ["Adapt", "KernelAbstractions", "LightGraphs", "LinearAlgebra", "Metis", "SparseArrays"] -git-tree-sha1 = "52d302d5e950e242f037316b6dd6e1e080afea09" -uuid = "45d422c2-293f-44ce-8315-2cb988662dec" -version = "0.3.4" - - [deps.KrylovPreconditioners.extensions] - KrylovPreconditionersAMDGPUExt = "AMDGPU" - KrylovPreconditionersCUDAExt = "CUDA" - KrylovPreconditionersOneAPIExt = "oneAPI" - - [deps.KrylovPreconditioners.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" - -[[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] -git-tree-sha1 = "9c7c721cfd800d87d48c745d8bfb65144f0a91df" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "9.4.2" -weakdeps = ["BFloat16s"] - - [deps.LLVM.extensions] - BFloat16sExt = "BFloat16s" - -[[deps.LLVMExtra_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "2ea068aac1e7f0337d381b0eae3110581e3f3216" -uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.37+2" - -[[deps.LLVMLoopInfo]] -git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" -uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" -version = "1.0.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" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.4.0+0" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.6.4+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.LibTracyClient_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d2bc4e1034b2d43076b50f0e34ea094c2cb0a717" -uuid = "ad6e5548-8b26-5c9f-8ef3-ef0ad883f3a5" -version = "0.9.1+6" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.18.0+0" - -[[deps.LightGraphs]] -deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "432428df5f360964040ed60418dd5601ecd240b6" -uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" -version = "1.3.5" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[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" - -[[deps.LoggingExtras]] -deps = ["Dates", "Logging"] -git-tree-sha1 = "f02b56007b064fbfddb4c9cd60161b6dd0f40df3" -uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.1.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 = "e5afce7eaf5b5ca0d444bcb4dc4fd78c54cbbac0" -uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.172" - - [deps.LoopVectorization.extensions] - ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] - SpecialFunctionsExt = "SpecialFunctions" - - [deps.LoopVectorization.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.Lz4_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "191686b1ac1ea9c89fc52e996ad15d1d241d1e33" -uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" -version = "1.10.1+0" - -[[deps.METIS_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2eefa8baa858871ae7770c98c3c2a7e46daba5b4" -uuid = "d00139f3-1899-568f-a2f0-47f597d42d70" -version = "5.1.3+0" - -[[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] -git-tree-sha1 = "5de60bc6cb3899cd318d80d627560fae2e2d99ae" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2025.0.1+1" - -[[deps.MPI]] -deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] -git-tree-sha1 = "892676019c58f34e38743bc989b0eca5bce5edc5" -uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" -version = "0.20.22" - - [deps.MPI.extensions] - AMDGPUExt = "AMDGPU" - CUDAExt = "CUDA" - - [deps.MPI.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - -[[deps.MPICH_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.3.1+0" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.11" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.5.4+0" - -[[deps.MacroTools]] -git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.16" - -[[deps.ManualMemory]] -git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" -uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" -version = "0.1.8" - -[[deps.MappedArrays]] -git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.2" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.9" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+1" - -[[deps.Metis]] -deps = ["CEnum", "LinearAlgebra", "METIS_jll", "SparseArrays"] -git-tree-sha1 = "54aca4fd53d39dcd2c3f1bef367b6921e8178628" -uuid = "2679e427-3c69-5b7f-982b-ece356f1e94b" -version = "1.5.0" - - [deps.Metis.extensions] - MetisGraphs = "Graphs" - MetisLightGraphs = "LightGraphs" - MetisSimpleWeightedGraphs = ["SimpleWeightedGraphs", "Graphs"] - - [deps.Metis.weakdeps] - Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" - LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" - SimpleWeightedGraphs = "47aef6b3-ad0c-573a-a1e2-d07658019622" - -[[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" - -[[deps.MosaicViews]] -deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] -git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" -uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" -version = "0.3.4" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.1.10" - -[[deps.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 = "be1095e2b767c19529409ec670bcfb01b825d717" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.8" - -[[deps.NVTX]] -deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] -git-tree-sha1 = "1a24c3430fa2ef3317c4c97fa7e431ef45793bd2" -uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" -version = "1.0.0" - -[[deps.NVTX_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cd475b587ff77910789a18e68da789fc446a2a05" -uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" -version = "3.2.1+0" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.1.3" - -[[deps.NetCDF_jll]] -deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML", "XML2_jll", "Zlib_jll", "Zstd_jll", "libaec_jll", "libzip_jll"] -git-tree-sha1 = "d574803b6055116af212434460adf654ce98e345" -uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" -version = "401.900.300+0" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.Oceananigans]] -deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "2b66db77b748719e83444423b3c1d5112dabb7e9" -repo-rev = "ss/fix-zstar-bc" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" -uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.97.0" - - [deps.Oceananigans.extensions] - OceananigansAMDGPUExt = "AMDGPU" - OceananigansCUDAExt = "CUDA" - OceananigansEnzymeExt = "Enzyme" - OceananigansMakieExt = ["MakieCore", "Makie"] - OceananigansMetalExt = "Metal" - OceananigansNCDatasetsExt = "NCDatasets" - OceananigansOneAPIExt = "oneAPI" - OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase"] - - [deps.Oceananigans.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" - Metal = "dde4c033-4e86-420c-a63e-0dd931031962" - NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" - Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" - 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.23+4" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.5+0" - -[[deps.OpenMPI_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] -git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.8+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.5.0" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "87510f7292a2b21aeff97912b0898f9553cc5c2c" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.1+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.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.10.0" - -[[deps.PkgVersion]] -deps = ["Pkg"] -git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" -uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.3" - -[[deps.PolyesterWeave]] -deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] -git-tree-sha1 = "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 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.1" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.3" - -[[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34" -uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.4.0" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[deps.Quaternions]] -deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" -uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.6" - -[[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[deps.Random123]] -deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "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.ReactantCore]] -deps = ["ExpressionExplorer", "MacroTools"] -git-tree-sha1 = "120feaf6a97738e3a63902644a0afb3b69cc7b98" -uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" -version = "0.1.15" - -[[deps.RealDot]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" -uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" -version = "0.1.0" - -[[deps.RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.1" - -[[deps.RootSolvers]] -deps = ["ForwardDiff", "Printf"] -git-tree-sha1 = "892b77767827af30868111d257930f567d5d78f8" -uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" -version = "0.4.4" - -[[deps.Roots]] -deps = ["Accessors", "CommonSolve", "Printf"] -git-tree-sha1 = "668e411c0616a70860249b4c96e5d35296631a1d" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.2.8" - - [deps.Roots.extensions] - RootsChainRulesCoreExt = "ChainRulesCore" - RootsForwardDiffExt = "ForwardDiff" - RootsIntervalRootFindingExt = "IntervalRootFinding" - RootsSymPyExt = "SymPy" - RootsSymPyPythonCallExt = "SymPyPythonCall" - - [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" - -[[deps.Rotations]] -deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.1" -weakdeps = ["RecipesBase"] - - [deps.Rotations.extensions] - RotationsRecipesBaseExt = "RecipesBase" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.SIMDTypes]] -git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" -uuid = "94e857df-77ce-4151-89e5-788b33177be4" -version = "0.1.0" - -[[deps.SLEEFPirates]] -deps = ["IfElse", "Static", "VectorizationBase"] -git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" -uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" -version = "0.6.43" - -[[deps.ScopedValues]] -deps = ["HashArrayMappedTries", "Logging"] -git-tree-sha1 = "7f44eef6b1d284465fafc66baf4d9bdcc239a15b" -uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" -version = "1.4.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 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" -uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.8" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[deps.SimpleBufferStream]] -git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.2.0" - -[[deps.SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[deps.SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.10.0" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.5.1" - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - - [deps.SpecialFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "be1cf4eb0ac528d96f5115b4ed80c26a8d8ae621" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.2" - -[[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] -git-tree-sha1 = "f737d444cb0ad07e61b3c1bef8eb91203c321eff" -uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.2.0" - -[[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] -git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" -uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.8.0" -weakdeps = ["OffsetArrays", "StaticArrays"] - - [deps.StaticArrayInterface.extensions] - StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" - StaticArrayInterfaceStaticArraysExt = "StaticArrays" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "cbea8a6bd7bed51b1619658dec70035e07b8502f" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.14" - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - - [deps.StaticArrays.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.3" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.1" - -[[deps.StringManipulation]] -deps = ["PrecompileTools"] -git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023" -uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.4.1" - -[[deps.StructArrays]] -deps = ["ConstructionBase", "DataAPI", "Tables"] -git-tree-sha1 = "8ad2e38cbb812e29348719cc63580ec1dfeb9de4" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.7.1" -weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"] - - [deps.StructArrays.extensions] - StructArraysAdaptExt = "Adapt" - StructArraysGPUArraysCoreExt = ["GPUArraysCore", "KernelAbstractions"] - StructArraysLinearAlgebraExt = "LinearAlgebra" - StructArraysSparseArraysExt = "SparseArrays" - StructArraysStaticArraysExt = "StaticArrays" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" - -[[deps.SurfaceFluxes]] -deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "aee530bde85cd41374273568cb649e72d82921e7" -uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.12.0" - - [deps.SurfaceFluxes.extensions] - CreateParametersExt = "ClimaParams" - - [deps.SurfaceFluxes.weakdeps] - ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "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 = "2c308aab2e14b399e4b8d6af7c486a241c8ca87a" -uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.19.1" - - [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" - -[[deps.Thermodynamics]] -deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "94f0e8e3135840568082e62fb69d31669539e627" -uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.12.14" - - [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 = "91dbaee0f50faa4357f7e9fc69442c7b6364dfe5" -uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" -version = "0.1.5" - - [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" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[deps.UnsafeAtomics]] -git-tree-sha1 = "b13c4edda90890e5b04ba24e20a310fbe6f249ff" -uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" -version = "0.3.0" -weakdeps = ["LLVM"] - - [deps.UnsafeAtomics.extensions] - UnsafeAtomicsLLVM = ["LLVM"] - -[[deps.VectorizationBase]] -deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "4ab62a49f1d8d9548a1c8d1a75e5f55cf196f64e" -uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.71" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "b8b243e47228b4a3877f1dd6aee0c5d56db7fcf4" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.6+1" - -[[deps.XZ_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" -uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.8.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.2.13+1" - -[[deps.Zstd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.7+1" - -[[deps.demumble_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6498e3581023f8e530f34760d18f75a69e3a4ea8" -uuid = "1e29f10c-031c-5a83-9565-69cddfc27673" -version = "1.3.0+0" - -[[deps.libaec_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f5733a5a9047722470b95a81e1b172383971105c" -uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.1.3+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.11.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.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" - -[[deps.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2022.0.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" From 06d895c41981b49acc5432b07ae3b78e61b83db9 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 04:51:09 +1000 Subject: [PATCH 128/203] Update Project.toml --- docs/Project.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/Project.toml b/docs/Project.toml index 6c8568237..5ceb09282 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,7 +1,6 @@ [deps] CFTime = "179af706-886a-5703-950a-314cd64e0468" CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -ClimaOcean = "0376089a-ecfe-4b0e-a64f-9c555d74d754" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244" From 63970102eb3bd39a017d57d8131b7a4b427d7340 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 05:14:28 +1000 Subject: [PATCH 129/203] enforce using Oceananigans#ss/fix-zstar-bc --- docs/Project.toml | 3 --- docs/make.jl | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/Project.toml b/docs/Project.toml index 5ceb09282..6d7549798 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -15,6 +15,3 @@ Documenter = "1" DocumenterCitations = "1.3" Oceananigans = "0.96 - 0.99" SeawaterPolynomials = "0.3.5" - -[sources] -Oceananigans = {url = "https://github.com/CliMA/Oceananigans.jl", rev = "ss/fix-zstar-bc"} diff --git a/docs/make.jl b/docs/make.jl index 0806eed52..17f8e5144 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -4,6 +4,21 @@ using DocumenterCitations, Literate +using Pkg + +# Force Oceananigans to use a specific branch +Pkg.add(PackageSpec( + name = "Oceananigans", + url = "https://github.com/CliMA/Oceananigans.jl", + rev = "ss/fix-zstar-bc" +)) + +Pkg.resolve() # Optional: ensure consistent dependency resolution + +@show Pkg.status() + +asdf + ENV["DATADEPS_ALWAYS_ACCEPT"] = "true" bib_filepath = joinpath(dirname(@__FILE__), "climaocean.bib") From ea59ebb6ddec193039bbd449c18eed9da8de2046 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 05:37:14 +1000 Subject: [PATCH 130/203] drop geebrish --- docs/make.jl | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 17f8e5144..11954db19 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -4,21 +4,16 @@ using DocumenterCitations, Literate +# temporary to enforce Oceananigans to use a specific branch using Pkg - -# Force Oceananigans to use a specific branch Pkg.add(PackageSpec( name = "Oceananigans", url = "https://github.com/CliMA/Oceananigans.jl", rev = "ss/fix-zstar-bc" )) - -Pkg.resolve() # Optional: ensure consistent dependency resolution - +Pkg.resolve() @show Pkg.status() -asdf - ENV["DATADEPS_ALWAYS_ACCEPT"] = "true" bib_filepath = joinpath(dirname(@__FILE__), "climaocean.bib") From 352a3ef744f1cdf240bbf27fe9c11f78f34b197d Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 05:42:28 +1000 Subject: [PATCH 131/203] enforce using Oceananigans#ss/fix-zstar-bc --- .buildkite/examples_build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index 66d2197e3..1a13c882a 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -29,7 +29,7 @@ steps: - label: "Run documentation" key: "build_documentation" commands: - - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'" + - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.add(url=\"https://github.com/CliMA/Oceananigans.jl\", rev=\"ss/fix-zstar-bc\"); Pkg.instantiate()'" - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project=docs/ docs/make.jl" agents: queue: ClimaOcean-docs @@ -38,10 +38,10 @@ steps: TMPDIR: "$TARTARUS_HOME/tmp" JULIA_DEPOT_PATH: "$TARTARUS_HOME/.julia-$BUILDKITE_BUILD_NUMBER" JULIA_DEBUG: "Documenter" - # This environment variable is needed to avoid SSL verification errors when Downloads.jl + # This environment variable is needed to avoid SSL verification errors when Downloads.jl # tries to download the bathymetry data. It should not be required so we need to fix our certificates # and remove this environment variable. ref: https://github.com/JuliaLang/Downloads.jl/issues/97 - JULIA_SSL_NO_VERIFY: "**" + JULIA_SSL_NO_VERIFY: "**" timeout_in_minutes: 1440 From 2beac0e38026cdab1a5b1088fec601a9a68f5123 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 05:44:31 +1000 Subject: [PATCH 132/203] use julia v1.10.10 --- .buildkite/examples_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index 1a13c882a..8d5d3fe67 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -1,6 +1,6 @@ env: - JULIA_VERSION: "1.10.9" + JULIA_VERSION: "1.10.10" JULIA_MINOR_VERSION: "1.10" TARTARUS_HOME: "/storage5/buildkite-agent" JULIA_PKG_SERVER_REGISTRY_PREFERENCE: eager From ea869897a391af893367151e8c73c27d705c0f21 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 05:46:13 +1000 Subject: [PATCH 133/203] precompile again --- .buildkite/examples_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index 8d5d3fe67..eab790d78 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -29,7 +29,7 @@ steps: - label: "Run documentation" key: "build_documentation" commands: - - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.add(url=\"https://github.com/CliMA/Oceananigans.jl\", rev=\"ss/fix-zstar-bc\"); Pkg.instantiate()'" + - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.add(url=\"https://github.com/CliMA/Oceananigans.jl\", rev=\"ss/fix-zstar-bc\"); Pkg.instantiate(); Pkg.precompile(; strict=true)'" - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project=docs/ docs/make.jl" agents: queue: ClimaOcean-docs From 89af369f76440915e71c39fbc905b0e34bced69e Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 05:47:12 +1000 Subject: [PATCH 134/203] use julia v1.10.10 --- .buildkite/examples_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index eab790d78..23eaf99c6 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -18,7 +18,7 @@ steps: TMPDIR: "$TARTARUS_HOME/tmp" command: - "echo '--- Instantiate project'" - - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using Pkg; Pkg.instantiate(; verbose=true); Pkg.precompile(; strict=true)'" + - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using Pkg; Pkg.add(url=\"https://github.com/CliMA/Oceananigans.jl\", rev=\"ss/fix-zstar-bc\"); Pkg.instantiate(; verbose=true); Pkg.precompile(; strict=true)'" # force the initialization of the CUDA runtime as it is lazily loaded by default - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using CUDA; CUDA.precompile_runtime()'" agents: From 9e2482b520bcaf9d2d2b5706c747ab789c027485 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 06:09:35 +1000 Subject: [PATCH 135/203] first oceananigans; then develop --- .buildkite/examples_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index 23eaf99c6..2a568bf49 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -29,7 +29,7 @@ steps: - label: "Run documentation" key: "build_documentation" commands: - - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.add(url=\"https://github.com/CliMA/Oceananigans.jl\", rev=\"ss/fix-zstar-bc\"); Pkg.instantiate(); Pkg.precompile(; strict=true)'" + - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project=docs/ -e 'using Pkg; Pkg.add(url=\"https://github.com/CliMA/Oceananigans.jl\", rev=\"ss/fix-zstar-bc\"); Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile(; strict=true)'" - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project=docs/ docs/make.jl" agents: queue: ClimaOcean-docs From 9affa64c4d2dcef68949a10a19681bc951d990bc Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 07:07:04 +1000 Subject: [PATCH 136/203] add CUDA --- docs/Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Project.toml b/docs/Project.toml index 6d7549798..53bb627fb 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,6 @@ [deps] CFTime = "179af706-886a-5703-950a-314cd64e0468" +CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" From 77175331e8e2f1d04fa48cffef6d9df8a8d63e96 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Fri, 18 Jul 2025 08:56:37 +1000 Subject: [PATCH 137/203] using CUDA + record from Makie not CUDA --- README.md | 1 + docs/src/index.md | 2 ++ examples/ecco_mixed_layer_depth.jl | 2 +- examples/inspect_JRA55_data.jl | 2 +- examples/near_global_ocean_simulation.jl | 2 +- examples/one_degree_simulation.jl | 2 +- examples/single_column_os_papa_simulation.jl | 2 +- experiments/arctic_simulation.jl | 3 +-- .../inspect_one_degree_near_global_simulation.jl | 2 +- .../one_degree_near_global_simulation.jl | 2 +- .../perfect_one_degree_model_calibration.jl | 1 + 11 files changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 480808e33..abfd7b19e 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ To illustrate how `OceanSeaIceModel` works we set up a simulation on a grid with using Oceananigans using Oceananigans.Units using Dates +using CUDA import ClimaOcean arch = GPU() diff --git a/docs/src/index.md b/docs/src/index.md index 56573195a..818eeeee9 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -38,6 +38,8 @@ The following script implements a near-global ocean simulation initialized from using Oceananigans using Oceananigans.Units using Dates +using CUDA + import ClimaOcean arch = GPU() diff --git a/examples/ecco_mixed_layer_depth.jl b/examples/ecco_mixed_layer_depth.jl index f8fcf955d..78217ba37 100644 --- a/examples/ecco_mixed_layer_depth.jl +++ b/examples/ecco_mixed_layer_depth.jl @@ -71,7 +71,7 @@ fig # And record a movie -record(fig, "ecco_mld.mp4", 1:Nt-1, framerate=4) do nn +CairoMakie.record(fig, "ecco_mld.mp4", 1:Nt-1, framerate=4) do nn @info "Drawing frame $nn of $Nt..." n[] = nn end diff --git a/examples/inspect_JRA55_data.jl b/examples/inspect_JRA55_data.jl index 058a15761..03305aca8 100644 --- a/examples/inspect_JRA55_data.jl +++ b/examples/inspect_JRA55_data.jl @@ -72,7 +72,7 @@ snapshot_interval = 3hours # JRE55 time-resolution rotation_period = 60days rotation_rate = 2π / rotation_period -record(fig, "JRA55_data.mp4", 1:Nt, framerate=16) do nn +CairoMakie.record(fig, "JRA55_data.mp4", 1:Nt, framerate=16) do nn @info nn/Nt n[] = nn diff --git a/examples/near_global_ocean_simulation.jl b/examples/near_global_ocean_simulation.jl index 94c89d217..b6e54095e 100644 --- a/examples/near_global_ocean_simulation.jl +++ b/examples/near_global_ocean_simulation.jl @@ -252,7 +252,7 @@ nothing #hide # And now we make a movie: -record(fig, "near_global_ocean_surface.mp4", 1:Nt, framerate = 8) do nn +CairoMakie.record(fig, "near_global_ocean_surface.mp4", 1:Nt, framerate = 8) do nn n[] = nn end nothing #hide diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index 7836fd4e9..64275864c 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -294,7 +294,7 @@ nothing #hide # And now a movie: -record(fig, "one_degree_global_ocean_surface.mp4", 1:Nt, framerate = 8) do nn +CairoMakie.record(fig, "one_degree_global_ocean_surface.mp4", 1:Nt, framerate = 8) do nn n[] = nn end nothing #hide diff --git a/examples/single_column_os_papa_simulation.jl b/examples/single_column_os_papa_simulation.jl index 94a2fa7ce..9f07663fc 100644 --- a/examples/single_column_os_papa_simulation.jl +++ b/examples/single_column_os_papa_simulation.jl @@ -322,7 +322,7 @@ Smax = maximum(interior(S)) Smin = minimum(interior(S)) xlims!(axSz, Smin - 0.2, Smax + 0.2) -record(fig, "single_column_profiles.mp4", 1:Nt, framerate=24) do nn +CairoMakie.record(fig, "single_column_profiles.mp4", 1:Nt, framerate=24) do nn @info "Drawing frame $nn of $Nt..." n[] = nn end diff --git a/experiments/arctic_simulation.jl b/experiments/arctic_simulation.jl index cd4cda1b1..0d0433349 100644 --- a/experiments/arctic_simulation.jl +++ b/experiments/arctic_simulation.jl @@ -11,12 +11,11 @@ using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium using Printf using CUDA -CUDA.device!(1) arch = GPU() depth = 2000meters Nz = 30 -z = ExponentialCoordinate(Nz, depth; scale=depth/3) +z = ExponentialCoordinate(Nz, -depth; scale=depth/3) z = MutableVerticalDiscretization(z) Nx = 180 # longitudinal direction -> 250 points is about 1.5ᵒ resolution diff --git a/experiments/one_degree_calibration/inspect_one_degree_near_global_simulation.jl b/experiments/one_degree_calibration/inspect_one_degree_near_global_simulation.jl index 7e1d5b9f7..69e9cf1e5 100644 --- a/experiments/one_degree_calibration/inspect_one_degree_near_global_simulation.jl +++ b/experiments/one_degree_calibration/inspect_one_degree_near_global_simulation.jl @@ -126,7 +126,7 @@ Colorbar(fig[4, 4], hm_N2; vertical=true, tellheight=false, flipaxis=true, label display(fig) -record(fig, "one_degree_near_global_simulation_$(closure_name).mp4", 1:Nt, framerate=24) do nn +CairoMakie.record(fig, "one_degree_near_global_simulation_$(closure_name).mp4", 1:Nt, framerate=24) do nn n[] = nn end diff --git a/experiments/one_degree_calibration/one_degree_near_global_simulation.jl b/experiments/one_degree_calibration/one_degree_near_global_simulation.jl index 757229fe5..d37d50f05 100644 --- a/experiments/one_degree_calibration/one_degree_near_global_simulation.jl +++ b/experiments/one_degree_calibration/one_degree_near_global_simulation.jl @@ -10,6 +10,7 @@ using Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivities: #using ParameterEstimocean.Parameters: closure_with_parameters using JLD2 +using CUDA const years = 365days @@ -147,4 +148,3 @@ simulation.Δt = 20minutes run!(simulation) @info "Simulation took $(prettytime(simulation.run_wall_time))." - diff --git a/experiments/one_degree_calibration/perfect_one_degree_model_calibration.jl b/experiments/one_degree_calibration/perfect_one_degree_model_calibration.jl index a258714fb..2d2a0cfb7 100644 --- a/experiments/one_degree_calibration/perfect_one_degree_model_calibration.jl +++ b/experiments/one_degree_calibration/perfect_one_degree_model_calibration.jl @@ -9,6 +9,7 @@ using ParameterEstimocean.Utils: map_gpus_to_ranks! using ParameterEstimocean.Observations: FieldTimeSeriesCollector using ParameterEstimocean.Parameters: closure_with_parameters using JLD2 +using CUDA arch = GPU() From 6e0be0902fcf85256bf362ea4d752d4cb383b188 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 18 Jul 2025 11:01:21 +0200 Subject: [PATCH 138/203] Update one_degree_simulation.jl --- examples/one_degree_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index 64275864c..2571aef61 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -53,8 +53,8 @@ grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height); eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=2e3, κ_symmetric=2e3) horizontal_viscosity = HorizontalScalarDiffusivity(ν=4000) -vertical_mixing = Oceananigans.TurbulenceClosures.CATKEVerticalDiffusivity(Oceananigans.TurbulenceClosures.ExplicitTimeDiscretization(), minimum_tke=1e-6) - +vertical_mixing = ClimaOcean.OceanSimulations.default_ocean_closure() + # ### Ocean simulation # Now we bring everything together to construct the ocean simulation. # We use a split-explicit timestepping with 70 substeps for the barotropic From 4488c2e89576fe4168ca75cd547eb6030d2fdd72 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 18 Jul 2025 13:46:35 +0200 Subject: [PATCH 139/203] some changes --- .../InterfaceComputations/atmosphere_ocean_fluxes.jl | 6 +++++- .../InterfaceComputations/component_interfaces.jl | 7 +++++-- .../InterfaceComputations/interface_states.jl | 2 +- .../similarity_theory_turbulent_fluxes.jl | 8 ++++++-- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl index 319ba5366..96f115028 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl @@ -33,6 +33,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) flux_formulation = coupled_model.interfaces.atmosphere_ocean_interface.flux_formulation interface_fluxes = coupled_model.interfaces.atmosphere_ocean_interface.fluxes interface_temperature = coupled_model.interfaces.atmosphere_ocean_interface.temperature + interface_humidity = coupled_model.interfaces.atmosphere_ocean_interface.humidity interface_properties = coupled_model.interfaces.atmosphere_ocean_interface.properties ocean_properties = coupled_model.interfaces.ocean_properties atmosphere_properties = (thermodynamics_parameters = thermodynamics_parameters(atmosphere), @@ -45,6 +46,7 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) _compute_atmosphere_ocean_interface_state!, interface_fluxes, interface_temperature, + interface_humidity, grid, clock, flux_formulation, @@ -60,6 +62,7 @@ end """ Compute turbulent fluxes between an atmosphere and a interface state using similarity theory """ @kernel function _compute_atmosphere_ocean_interface_state!(interface_fluxes, interface_temperature, + interface_humidity, grid, clock, turbulent_flux_formulation, @@ -164,7 +167,6 @@ end cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity ℒv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) - # Store fluxes Qv = interface_fluxes.latent_heat Qc = interface_fluxes.sensible_heat @@ -172,6 +174,7 @@ end ρτx = interface_fluxes.x_momentum ρτy = interface_fluxes.y_momentum Ts = interface_temperature + qs = interface_humidity @inbounds begin # +0: cooling, -0: heating @@ -181,6 +184,7 @@ end ρτx[i, j, 1] = + ρₐ * τx ρτy[i, j, 1] = + ρₐ * τy Ts[i, j, 1] = convert_from_kelvin(ocean_properties.temperature_units, Ψₛ.T) + qs[i, j, 1] = Ψₛ.q interface_fluxes.friction_velocity[i, j, 1] = u★ interface_fluxes.temperature_scale[i, j, 1] = θ★ diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index d32f21093..23e178f89 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -39,6 +39,7 @@ mutable struct AtmosphereInterface{J, F, ST, P} fluxes :: J flux_formulation :: F temperature :: ST + humidity :: ST properties :: P end @@ -213,8 +214,9 @@ function atmosphere_ocean_interface(atmos, velocity_formulation) interface_temperature = Field{Center, Center, Nothing}(ocean.model.grid) + interface_humidity = Field{Center, Center, Nothing}(ocean.model.grid) - return AtmosphereInterface(ao_fluxes, ao_flux_formulation, interface_temperature, ao_properties) + return AtmosphereInterface(ao_fluxes, ao_flux_formulation, interface_temperature, interface_humidity, ao_properties) end atmosphere_sea_ice_interface(atmos, sea_ice, args...) = nothing @@ -250,8 +252,9 @@ function atmosphere_sea_ice_interface(atmos, velocity_formulation) interface_temperature = sea_ice.model.ice_thermodynamics.top_surface_temperature + interface_humidity = Field{Center, Center, Nothing}(sea_ice.model.grid) - return AtmosphereInterface(fluxes, ai_flux_formulation, interface_temperature, properties) + return AtmosphereInterface(fluxes, ai_flux_formulation, interface_temperature, interface_humidity, properties) end sea_ice_ocean_interface(sea_ice, ocean) = nothing diff --git a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl index a98b1cea3..05e172bab 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl @@ -103,7 +103,7 @@ function WaterMoleFraction(FT=Oceananigans.defaults.FloatType) magnesium = SalinityConstituent{FT}(24.31, 0.05), ) - return SeawaterComposition(water_molar_mass, salinity_constituents) + return WaterMoleFraction(water_molar_mass, salinity_constituents) end @inline function compute_water_mole_fraction(wmf::WaterMoleFraction, S) diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index 8b8a61506..eb8b69b2c 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -24,6 +24,7 @@ struct SimilarityTheoryFluxes{FT, UF, R, B, S} von_karman_constant :: FT # parameter turbulent_prandtl_number :: FT # parameter gustiness_parameter :: FT # bulk velocity parameter + minimum_velocity_scale :: FT # minimum velocity scale stability_functions :: UF # functions for turbulent fluxes roughness_lengths :: R # parameterization for turbulent fluxes similarity_form :: B # similarity profile relating atmosphere to interface state @@ -87,11 +88,12 @@ Keyword Arguments function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; von_karman_constant = 0.4, turbulent_prandtl_number = 1, - gustiness_parameter = 1, + gustiness_parameter = 2, stability_functions = atmosphere_ocean_stability_functions(FT), momentum_roughness_length = MomentumRoughnessLength(FT), temperature_roughness_length = ScalarRoughnessLength(FT), water_vapor_roughness_length = ScalarRoughnessLength(FT), + minimum_velocity_scale = 0.5, similarity_form = LogarithmicSimilarityProfile(), solver_stop_criteria = nothing, solver_tolerance = 1e-8, @@ -114,6 +116,7 @@ function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; return SimilarityTheoryFluxes(convert(FT, von_karman_constant), convert(FT, turbulent_prandtl_number), convert(FT, gustiness_parameter), + convert(FT, minimum_velocity_scale), stability_functions, roughness_lengths, similarity_form, @@ -203,7 +206,8 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, approximate_interface_state) U = sqrt(Δu^2 + Δv^2 + Uᴳ^2) - + U = max(U, flux_formulation.minimum_velocity_scale) + # Compute roughness length scales ℓu₀ = roughness_length(ℓu, u★, U, 𝒬ₛ, ℂₐ) ℓq₀ = roughness_length(ℓq, ℓu₀, u★, U, 𝒬ₛ, ℂₐ) From a436bed9654a4d169102151fbe24be3df5051705 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Fri, 18 Jul 2025 07:58:58 -0400 Subject: [PATCH 140/203] increase a bit --- .../similarity_theory_turbulent_fluxes.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index 7c8cad4cf..dd3221952 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -24,6 +24,7 @@ struct SimilarityTheoryFluxes{FT, UF, R, B, S} von_karman_constant :: FT # parameter turbulent_prandtl_number :: FT # parameter gustiness_parameter :: FT # bulk velocity parameter + minimum_velocity_scale :: FT # minimum velocity scale stability_functions :: UF # functions for turbulent fluxes roughness_lengths :: R # parameterization for turbulent fluxes similarity_form :: B # similarity profile relating atmosphere to interface state @@ -58,7 +59,7 @@ end gravitational_acceleration = 9.81, von_karman_constant = 0.4, turbulent_prandtl_number = 1, - gustiness_parameter = 1, + gustiness_parameter = 3.5, stability_functions = default_stability_functions(FT), roughness_lengths = default_roughness_lengths(FT), similarity_form = LogarithmicSimilarityProfile(), @@ -87,11 +88,12 @@ Keyword Arguments function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; von_karman_constant = 0.4, turbulent_prandtl_number = 1, - gustiness_parameter = 1.2, + gustiness_parameter = 3.5, stability_functions = atmosphere_ocean_stability_functions(FT), momentum_roughness_length = MomentumRoughnessLength(FT), temperature_roughness_length = ScalarRoughnessLength(FT), water_vapor_roughness_length = ScalarRoughnessLength(FT), + minimum_velocity_scale = 0.5, similarity_form = LogarithmicSimilarityProfile(), solver_stop_criteria = nothing, solver_tolerance = 1e-8, @@ -114,6 +116,7 @@ function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; return SimilarityTheoryFluxes(convert(FT, von_karman_constant), convert(FT, turbulent_prandtl_number), convert(FT, gustiness_parameter), + convert(FT, minimum_velocity_scale), stability_functions, roughness_lengths, similarity_form, @@ -195,7 +198,7 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, # Buoyancy flux characteristic scale for gustiness (Edson et al. 2013) h_bℓ = atmosphere_state.h_bℓ Jᵇ = - u★ * b★ - Uᴳ = max(0.5, β * cbrt(Jᵇ * h_bℓ)) + Uᴳ = β * cbrt(Jᵇ * h_bℓ) # New velocity difference accounting for gustiness Δu, Δv = velocity_difference(interface_properties.velocity_formulation, @@ -203,7 +206,8 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, approximate_interface_state) U = sqrt(Δu^2 + Δv^2 + Uᴳ^2) - + U = max(U, flux_formulation.minimum_velocity_scale) + # Compute roughness length scales ℓu₀ = roughness_length(ℓu, u★, U, 𝒬ₛ, ℂₐ) ℓq₀ = roughness_length(ℓq, ℓu₀, u★, U, 𝒬ₛ, ℂₐ) From 57466526747e903dbc8fa098b6d5e6f8a80c7250 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 18 Jul 2025 14:28:21 +0200 Subject: [PATCH 141/203] add more stuff --- .../InterfaceComputations/atmosphere_sea_ice_fluxes.jl | 6 +++--- .../coefficient_based_turbulent_fluxes.jl | 2 +- .../InterfaceComputations/compute_interface_state.jl | 3 ++- .../InterfaceComputations/interface_states.jl | 2 ++ .../similarity_theory_turbulent_fluxes.jl | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl index d12ae69b3..b95dfa36f 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl @@ -128,7 +128,7 @@ end # Guess Sₛ = zero(FT) # what should we use for interface salinity? - initial_interface_state = InterfaceState(u★, u★, u★, uᵢ, vᵢ, Tₛ, Sₛ, convert(FT, qₛ)) + initial_interface_state = InterfaceState(u★, u★, u★, uᵢ, uᵢ, vᵢ, Tₛ, Sₛ, convert(FT, qₛ)) not_water = inactive_node(i, j, kᴺ, grid, Center(), Center(), Center()) ice_free = ℵᵢ == 0 @@ -136,7 +136,7 @@ end needs_to_converge = stop_criteria isa ConvergenceStopCriteria if (needs_to_converge && not_water) || ice_free - interface_state = InterfaceState(zero(FT), zero(FT), zero(FT), uᵢ, vᵢ, Tᵢ, Sₛ, zero(FT)) + interface_state = InterfaceState(zero(FT), zero(FT), zero(FT), uᵢ, uᵢ, vᵢ, Tᵢ, Sₛ, zero(FT)) else interface_state = compute_interface_state(turbulent_flux_formulation, initial_interface_state, @@ -154,7 +154,7 @@ end Ψₛ = interface_state Ψₐ = local_atmosphere_state Δu, Δv = velocity_difference(interface_properties.velocity_formulation, Ψₐ, Ψₛ) - ΔU = sqrt(Δu^2 + Δv^2) + ΔU = interface_state.ΔU τx = - u★^2 * Δu / ΔU τy = - u★^2 * Δv / ΔU diff --git a/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl index 647339b06..526dc73a9 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl @@ -117,5 +117,5 @@ end θ★ = Ch / sqrt(Cd) * Δθ q★ = Cq / sqrt(Cd) * Δq - return u★, θ★, q★ + return u★, θ★, q★, ΔU end diff --git a/src/OceanSeaIceModels/InterfaceComputations/compute_interface_state.jl b/src/OceanSeaIceModels/InterfaceComputations/compute_interface_state.jl index d2dbddb9d..2ad417cfd 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/compute_interface_state.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/compute_interface_state.jl @@ -102,7 +102,7 @@ and interior properties `ℙₛ`, `ℙₐ`, and `ℙᵢ`. Δθ = θₐ - Tₛ Δh = atmosphere_state.z # Assumption! The surface is at z = 0 -> Δh = zₐ - 0 - u★, θ★, q★ = iterate_interface_fluxes(flux_formulation, + u★, θ★, q★, U = iterate_interface_fluxes(flux_formulation, Tₛ, qₛ, Δθ, Δq, Δh, approximate_interface_state, atmosphere_state, @@ -116,6 +116,7 @@ and interior properties `ℙₛ`, `ℙₐ`, and `ℙᵢ`. return InterfaceState(convert(FT, u★), convert(FT, θ★), convert(FT, q★), + convert(FT, U), convert(FT, u), convert(FT, v), convert(FT, Tₛ), diff --git a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl index 05e172bab..387d163b1 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl @@ -363,6 +363,7 @@ struct InterfaceState{FT} u★ :: FT # friction velocity θ★ :: FT # flux characteristic temperature q★ :: FT # flux characteristic specific humidity + ΔU :: FT # velocity difference magnitude u :: FT # interface x-velocity v :: FT # interface y-velocity T :: FT # interface temperature @@ -393,6 +394,7 @@ end zero(FT), zero(FT), zero(FT), + zero(FT), convert(FT, 273.15), zero(FT), zero(FT)) diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index eb8b69b2c..a6a861e88 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -227,7 +227,7 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, θ★ = χθ * Δθ q★ = χq * Δq - return u★, θ★, q★ + return u★, θ★, q★, U end """ From 5127f058932ff34595228953f733162b7900b361 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 18 Jul 2025 14:35:22 +0200 Subject: [PATCH 142/203] improvements --- .../InterfaceComputations/interface_states.jl | 4 ++-- .../similarity_theory_turbulent_fluxes.jl | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl index 387d163b1..b085a057e 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl @@ -372,8 +372,8 @@ struct InterfaceState{FT} melting :: Bool end -@inline InterfaceState(u★, θ★, q★, u, v, T, S, q) = - InterfaceState(u★, θ★, q★, u, v, T, S, q, false) +@inline InterfaceState(u★, θ★, q★, ΔU, u, v, T, S, q) = + InterfaceState(u★, θ★, q★, ΔU, u, v, T, S, q, false) Base.eltype(::InterfaceState{FT}) where FT = FT diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index a6a861e88..9439347e1 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -35,6 +35,7 @@ Adapt.adapt_structure(to, fluxes::SimilarityTheoryFluxes) = SimilarityTheoryFluxes(adapt(to, fluxes.von_karman_constant), adapt(to, fluxes.turbulent_prandtl_number), adapt(to, fluxes.gustiness_parameter), + adapt(to, fluxes.minimum_velocity_scale), adapt(to, fluxes.stability_functions), adapt(to, fluxes.roughness_lengths), adapt(to, fluxes.similarity_form), From 1037980b7a29b26ddf90b7e51bd3832e01897909 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 18 Jul 2025 14:36:09 +0200 Subject: [PATCH 143/203] improve --- .../InterfaceComputations/atmosphere_ocean_fluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl index 96f115028..b4ec43202 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl @@ -118,7 +118,7 @@ end # Estimate interface specific humidity using interior temperature q_formulation = interface_properties.specific_humidity_formulation qₛ = surface_specific_humidity(q_formulation, ℂₐ, 𝒬ₐ, Tᵢ, Sᵢ) - initial_interface_state = InterfaceState(u★, u★, u★, uᵢ, vᵢ, Tᵢ, Sᵢ, qₛ) + initial_interface_state = InterfaceState(u★, u★, u★, uᵢ, uᵢ, vᵢ, Tᵢ, Sᵢ, qₛ) # Don't use convergence criteria in an inactive cell stop_criteria = turbulent_flux_formulation.solver_stop_criteria From 71c82f5d7c431e4dda6bf49c80dba212245ff10e Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 21 Jul 2025 12:08:04 +0200 Subject: [PATCH 144/203] add an equatorial single column --- equatorial_single_column.jl | 275 ++++++++++++++++++ .../atmosphere_ocean_fluxes.jl | 2 +- .../coefficient_based_turbulent_fluxes.jl | 2 +- .../compute_interface_state.jl | 3 +- .../InterfaceComputations/interface_states.jl | 6 +- .../similarity_theory_turbulent_fluxes.jl | 2 +- 6 files changed, 281 insertions(+), 9 deletions(-) create mode 100644 equatorial_single_column.jl diff --git a/equatorial_single_column.jl b/equatorial_single_column.jl new file mode 100644 index 000000000..2aaeb91ec --- /dev/null +++ b/equatorial_single_column.jl @@ -0,0 +1,275 @@ +using ClimaOcean +using Oceananigans +using Oceananigans.Units +using Oceananigans.BuoyancyFormulations: buoyancy_frequency +using Oceananigans.Units: Time +using Dates +using Printf +using GLMakie + +location_name = "equatorial_shallow_regions" +z_faces = ExponentialCoordinate(60, -6200) +z_faces = Oceananigans.Grids.MutableVerticalDiscretization(z_faces) +λ★ = 123.21302547843129 +φ★ = 9.894610398995553 + +grid = LatitudeLongitudeGrid(size = (3, 3, 60), + longitude = (λ★-0.5, λ★+0.5), + latitude = (φ★-0.5, φ★+0.5), + z = z_faces, + topology = (Bounded, Bounded, Bounded)) + +bottom_height = [0.0 0.0 0.0; + 0.0 0.0 0.0; + -384.522 -161.595 0.0] + +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +@info "Building the simulation" + +ocean = ocean_simulation(grid; + Δt=20minutes, + momentum_advection=nothing, + tracer_advection=nothing) + +set!(ocean.model, T=Metadatum(:temperature, dataset=ECCO4Monthly()), + S=Metadatum(:salinity, dataset=ECCO4Monthly())) + +atmosphere = JRA55PrescribedAtmosphere(end_date = DateTime(1958, 12, 30), # Last day of the simulation + backend = JRA55NetCDFBackend(100), + dataset = MultiYearJRA55(), + dir = "./") +radiation = Radiation() +coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) +simulation = Simulation(coupled_model, Δt=ocean.Δt, stop_time=7200days) + +wall_clock = Ref(time_ns()) + +function progress(sim) + msg = "Ocean Station Papa" + msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) + + elapsed = 1e-9 * (time_ns() - wall_clock[]) + msg *= string(", wall time: ", prettytime(elapsed)) + wall_clock[] = time_ns() + + u, v, w = sim.model.ocean.model.velocities + msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) + + T = sim.model.ocean.model.tracers.T + S = sim.model.ocean.model.tracers.S + e = if sim.model.ocean.model.closure isa CATKEVerticalDiffusivity + sim.model.ocean.model.tracers.e + else + sim.model.ocean.model.tracers.S + end + + τx = first(sim.model.interfaces.net_fluxes.ocean_surface.u) + τy = first(sim.model.interfaces.net_fluxes.ocean_surface.v) + Q = first(sim.model.interfaces.net_fluxes.ocean_surface.Q) + + u★ = sqrt(sqrt(τx^2 + τy^2)) + + Nz = size(T, 3) + msg *= @sprintf(", u★: %.2f m s⁻¹", u★) + msg *= @sprintf(", Q: %.2f W m⁻²", Q) + msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) + msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) + msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) + msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) + + @info msg + + return nothing +end + +simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) + +# Build flux outputs +τx = simulation.model.interfaces.net_fluxes.ocean_surface.u +τy = simulation.model.interfaces.net_fluxes.ocean_surface.v +JT = simulation.model.interfaces.net_fluxes.ocean_surface.T +Js = simulation.model.interfaces.net_fluxes.ocean_surface.S +E = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.water_vapor +Qc = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.sensible_heat +Qv = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.latent_heat +Qu = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.upwelling_longwave +Ql = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.downwelling_longwave +Qs = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.downwelling_shortwave +ρₒ = simulation.model.interfaces.ocean_properties.reference_density +cₚ = simulation.model.interfaces.ocean_properties.heat_capacity +ua = simulation.model.interfaces.exchanger.exchange_atmosphere_state.u +va = simulation.model.interfaces.exchanger.exchange_atmosphere_state.v +Ta = simulation.model.interfaces.exchanger.exchange_atmosphere_state.T +qa = simulation.model.interfaces.exchanger.exchange_atmosphere_state.q +Fwf = simulation.model.interfaces.exchanger.exchange_atmosphere_state.Mp +u★ = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity +θ★ = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.temperature_scale +q★ = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.water_vapor_scale +Ts = simulation.model.interfaces.atmosphere_ocean_interface.temperature +qs = simulation.model.interfaces.atmosphere_ocean_interface.humidity + +Q = ρₒ * cₚ * JT +ρτx = ρₒ * τx +ρτy = ρₒ * τy +N² = buoyancy_frequency(ocean.model) +κc = ocean.model.diffusivity_fields.κc + +fluxes = (; ρτx, ρτy, E, Js, JT, Q, Qv, Qc, ua, va, Ta, qa, Qs, Ql, Qu, Fwf, u★, θ★, q★, Ts, qs) +auxiliary_fields = (; N², κc) +fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) + +# Slice fields at the surface +outputs = merge(fields, fluxes) + +filename = "single_column_omip_$(location_name)_take2" + +simulation.output_writers[:jld2] = JLD2Writer(ocean.model, outputs; filename, + schedule = TimeInterval(8hours), + overwrite_existing = true) + +run!(simulation) + +filename *= ".jld2" + +ua = FieldTimeSeries(filename, "ua") +va = FieldTimeSeries(filename, "va") +Ta = FieldTimeSeries(filename, "Ta") +qa = FieldTimeSeries(filename, "qa") +Ql = FieldTimeSeries(filename, "Ql") +Qs = FieldTimeSeries(filename, "Qs") +Qu = FieldTimeSeries(filename, "Qu") +Pt = FieldTimeSeries(filename, "Fwf") + +u = FieldTimeSeries(filename, "u") +v = FieldTimeSeries(filename, "v") +T = FieldTimeSeries(filename, "T") +S = FieldTimeSeries(filename, "S") +e = if ocean.model.closure isa CATKEVerticalDiffusivity + FieldTimeSeries(filename, "e") +else + FieldTimeSeries(filename, "S") # Use salinity as a proxy for e +end + +N² = FieldTimeSeries(filename, "N²") +κ = FieldTimeSeries(filename, "κc") + +Qv = FieldTimeSeries(filename, "Qv") +Qc = FieldTimeSeries(filename, "Qc") +Q = FieldTimeSeries(filename, "Q") +Js = FieldTimeSeries(filename, "Js") +Ev = FieldTimeSeries(filename, "E") +ρτx = FieldTimeSeries(filename, "ρτx") +ρτy = FieldTimeSeries(filename, "ρτy") +u★ = FieldTimeSeries(filename, "u★") +θ★ = FieldTimeSeries(filename, "θ★") +q★ = FieldTimeSeries(filename, "q★") +Ts = FieldTimeSeries(filename, "Ts") +qs = FieldTimeSeries(filename, "qs") + +Nz = size(T, 3) +times = Qc.times +ρₒ = coupled_model.interfaces.ocean_properties.reference_density + +fig = Figure(size=(1800, 1800)) + +axτ = Axis(fig[1, 1:3], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") +axQ = Axis(fig[1, 4:6], xlabel="Days since Oct 1 1992", ylabel="Heat flux (W m⁻²)") +axu = Axis(fig[2, 1:3], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") +axT = Axis(fig[2, 4:6], xlabel="Days since Oct 1 1992", ylabel="Surface temperature (ᵒC)") +axF = Axis(fig[3, 1:3], xlabel="Days since Oct 1 1992", ylabel="Freshwater volume flux (m s⁻¹)") +axS = Axis(fig[3, 4:6], xlabel="Days since Oct 1 1992", ylabel="Surface salinity (g kg⁻¹)") + +axuz = Axis(fig[4:5, 1:2], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") +axTz = Axis(fig[4:5, 3:4], xlabel="Temperature (ᵒC)", ylabel="z (m)") +axSz = Axis(fig[4:5, 5:6], xlabel="Salinity (g kg⁻¹)", ylabel="z (m)") +axNz = Axis(fig[6:7, 1:2], xlabel="Buoyancy frequency (s⁻²)", ylabel="z (m)") +axκz = Axis(fig[6:7, 3:4], xlabel="Eddy diffusivity (m² s⁻¹)", ylabel="z (m)") #, xscale=log10) +axez = Axis(fig[6:7, 5:6], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)") #, xscale=log10) + +title = @sprintf("Single-column simulation at %.2f, %.2f", φ★, λ★) +Label(fig[0, 1:6], title) + +n = Observable(1) + +times = (times .- times[1]) ./days +Nt = length(times) +tn = @lift times[$n] + +colors = Makie.wong_colors() + +τx = interior(ρτx, 3, 2, 1, :) ./ ρₒ +τy = interior(ρτy, 3, 2, 1, :) ./ ρₒ + +lines!(axu, times, interior(u, 3, 2, Nz, :), color=colors[1], label="Zonal") +lines!(axu, times, interior(v, 3, 2, Nz, :), color=colors[2], label="Meridional") +lines!(axu, times, interior(u★, 3, 2, 1, :), color=colors[3], label="Ocean-side u★") +vlines!(axu, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axu) + +lines!(axτ, times, interior(ρτx, 3, 2, 1, :), label="Zonal") +lines!(axτ, times, interior(ρτy, 3, 2, 1, :), label="Meridional") +vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axτ) + +lines!(axT, times, interior(Ta, 3, 2, 1, 1:Nt) .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") +lines!(axT, times, interior(T, 3, 2, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") +vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axT) + +lines!(axQ, times, interior(Qc, 3, 2, 1, 1:Nt), color=colors[2], label="Sensible", linewidth=2) +lines!(axQ, times, interior(Qv, 3, 2, 1, 1:Nt), color=colors[3], label="Latent", linewidth=2) +lines!(axQ, times, interior(Qs, 3, 2, 1, 1:Nt), color=colors[4], label="Shortwave", linewidth=2) +lines!(axQ, times, interior(Ql, 3, 2, 1, 1:Nt), color=colors[5], label="Longwave", linewidth=2) +lines!(axQ, times, interior(Qu, 3, 2, 1, 1:Nt), color=colors[6], label="Upwelling", linewidth=2) +lines!(axQ, times, interior(Q, 3, 2, 1, 1:Nt), color=colors[7], label="Total heat flux", linewidth=4) +vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axQ) + +lines!(axF, times, interior(Pt, 3, 2, 1, 1:Nt), label="Prescribed freshwater flux") +lines!(axF, times, - interior(Ev, 3, 2, 1, 1:Nt), label="Evaporation") +vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) +axislegend(axF) + +lines!(axS, times, interior(S, 3, 2, Nz, :)) +vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) + +zc = znodes(T) +zf = znodes(κ) +un = @lift interior(u[$n], 3, 2, :) +vn = @lift interior(v[$n], 3, 2, :) +Tn = @lift interior(T[$n], 3, 2, :) +Sn = @lift interior(S[$n], 3, 2, :) +κn = @lift log10.(interior(κ[$n], 3, 2, :)) +en = @lift interior(e[$n], 3, 2, :) +N²n = @lift interior(N²[$n], 3, 2, :) + +scatterlines!(axuz, un, zc, label="u") +scatterlines!(axuz, vn, zc, label="v") +scatterlines!(axTz, Tn, zc) +scatterlines!(axSz, Sn, zc) +scatterlines!(axez, en, zc) +scatterlines!(axNz, N²n, zf) +scatterlines!(axκz, κn, zf) +ylims!(axuz, (-400, 0)) +ylims!(axTz, (-400, 0)) +ylims!(axSz, (-400, 0)) +ylims!(axez, (-400, 0)) +ylims!(axNz, (-400, 0)) +ylims!(axκz, (-400, 0)) + +xlims!(axTz, (15, 45)) +xlims!(axSz, (32, 37)) +xlims!(axez, (0, 0.00035)) +xlims!(axκz, (-8, 1)) +xlims!(axSz, (32, 37)) + +axislegend(axuz) + +record(fig, "single_column_profiles.mp4", 1:Nt, framerate=24) do nn + @info "Drawing frame $nn of $Nt..." + n[] = nn +end +nothing #hide + +# ![](single_column_profiles.mp4) diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl index b4ec43202..96f115028 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl @@ -118,7 +118,7 @@ end # Estimate interface specific humidity using interior temperature q_formulation = interface_properties.specific_humidity_formulation qₛ = surface_specific_humidity(q_formulation, ℂₐ, 𝒬ₐ, Tᵢ, Sᵢ) - initial_interface_state = InterfaceState(u★, u★, u★, uᵢ, uᵢ, vᵢ, Tᵢ, Sᵢ, qₛ) + initial_interface_state = InterfaceState(u★, u★, u★, uᵢ, vᵢ, Tᵢ, Sᵢ, qₛ) # Don't use convergence criteria in an inactive cell stop_criteria = turbulent_flux_formulation.solver_stop_criteria diff --git a/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl index 526dc73a9..647339b06 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/coefficient_based_turbulent_fluxes.jl @@ -117,5 +117,5 @@ end θ★ = Ch / sqrt(Cd) * Δθ q★ = Cq / sqrt(Cd) * Δq - return u★, θ★, q★, ΔU + return u★, θ★, q★ end diff --git a/src/OceanSeaIceModels/InterfaceComputations/compute_interface_state.jl b/src/OceanSeaIceModels/InterfaceComputations/compute_interface_state.jl index 2ad417cfd..d2dbddb9d 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/compute_interface_state.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/compute_interface_state.jl @@ -102,7 +102,7 @@ and interior properties `ℙₛ`, `ℙₐ`, and `ℙᵢ`. Δθ = θₐ - Tₛ Δh = atmosphere_state.z # Assumption! The surface is at z = 0 -> Δh = zₐ - 0 - u★, θ★, q★, U = iterate_interface_fluxes(flux_formulation, + u★, θ★, q★ = iterate_interface_fluxes(flux_formulation, Tₛ, qₛ, Δθ, Δq, Δh, approximate_interface_state, atmosphere_state, @@ -116,7 +116,6 @@ and interior properties `ℙₛ`, `ℙₐ`, and `ℙᵢ`. return InterfaceState(convert(FT, u★), convert(FT, θ★), convert(FT, q★), - convert(FT, U), convert(FT, u), convert(FT, v), convert(FT, Tₛ), diff --git a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl index b085a057e..05e172bab 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl @@ -363,7 +363,6 @@ struct InterfaceState{FT} u★ :: FT # friction velocity θ★ :: FT # flux characteristic temperature q★ :: FT # flux characteristic specific humidity - ΔU :: FT # velocity difference magnitude u :: FT # interface x-velocity v :: FT # interface y-velocity T :: FT # interface temperature @@ -372,8 +371,8 @@ struct InterfaceState{FT} melting :: Bool end -@inline InterfaceState(u★, θ★, q★, ΔU, u, v, T, S, q) = - InterfaceState(u★, θ★, q★, ΔU, u, v, T, S, q, false) +@inline InterfaceState(u★, θ★, q★, u, v, T, S, q) = + InterfaceState(u★, θ★, q★, u, v, T, S, q, false) Base.eltype(::InterfaceState{FT}) where FT = FT @@ -394,7 +393,6 @@ end zero(FT), zero(FT), zero(FT), - zero(FT), convert(FT, 273.15), zero(FT), zero(FT)) diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index 9439347e1..88dfea7bf 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -228,7 +228,7 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, θ★ = χθ * Δθ q★ = χq * Δq - return u★, θ★, q★, U + return u★, θ★, q★ end """ From bc33d079b6a33063908bcacf2e80e387460b670e Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 21 Jul 2025 14:24:38 +0200 Subject: [PATCH 145/203] possibly remove a bug? --- .../InterfaceComputations/similarity_theory_turbulent_fluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index 88dfea7bf..efaf8eca3 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -216,7 +216,7 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, # Transfer coefficients at height `h` ϰ = flux_formulation.von_karman_constant - L★ = ifelse(b★ == 0, Inf, - u★^2 / (ϰ * b★)) + L★ = ifelse(b★ == 0, Inf, u★^2 / (ϰ * b★)) form = flux_formulation.similarity_form χu = ϰ / similarity_profile(form, ψu, Δh, ℓu₀, L★) From ed0d210a010ac8646fc7ea14798b814c09efe768 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 21 Jul 2025 14:34:29 +0200 Subject: [PATCH 146/203] Update atmosphere_sea_ice_fluxes.jl --- .../InterfaceComputations/atmosphere_sea_ice_fluxes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl index b95dfa36f..4f0dbdef5 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl @@ -128,7 +128,7 @@ end # Guess Sₛ = zero(FT) # what should we use for interface salinity? - initial_interface_state = InterfaceState(u★, u★, u★, uᵢ, uᵢ, vᵢ, Tₛ, Sₛ, convert(FT, qₛ)) + initial_interface_state = InterfaceState(u★, u★, u★, uᵢ, vᵢ, Tₛ, Sₛ, convert(FT, qₛ)) not_water = inactive_node(i, j, kᴺ, grid, Center(), Center(), Center()) ice_free = ℵᵢ == 0 @@ -136,7 +136,7 @@ end needs_to_converge = stop_criteria isa ConvergenceStopCriteria if (needs_to_converge && not_water) || ice_free - interface_state = InterfaceState(zero(FT), zero(FT), zero(FT), uᵢ, uᵢ, vᵢ, Tᵢ, Sₛ, zero(FT)) + interface_state = InterfaceState(zero(FT), zero(FT), zero(FT), uᵢ, vᵢ, Tᵢ, Sₛ, zero(FT)) else interface_state = compute_interface_state(turbulent_flux_formulation, initial_interface_state, From 5b5b747e181737f37a362bb6385a2c39f73ec83c Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 21 Jul 2025 14:35:22 +0200 Subject: [PATCH 147/203] Update atmosphere_sea_ice_fluxes.jl --- .../InterfaceComputations/atmosphere_sea_ice_fluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl index 4f0dbdef5..d12ae69b3 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl @@ -154,7 +154,7 @@ end Ψₛ = interface_state Ψₐ = local_atmosphere_state Δu, Δv = velocity_difference(interface_properties.velocity_formulation, Ψₐ, Ψₛ) - ΔU = interface_state.ΔU + ΔU = sqrt(Δu^2 + Δv^2) τx = - u★^2 * Δu / ΔU τy = - u★^2 * Δv / ΔU From 28d3e4edf2d4b38413204cc69b07d543694af9d9 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 21 Jul 2025 14:36:26 +0200 Subject: [PATCH 148/203] adding the correct Manifest --- Manifest.toml | 1547 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1547 insertions(+) create mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 000000000..8397e00df --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,1547 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.10" +manifest_format = "2.0" +project_hash = "bb09aa984e1a9dbd83743fc29ea3d49437328c99" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + + [deps.AbstractFFTs.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] +git-tree-sha1 = "3b86719127f50670efe356bc11073d84b4ed7a5d" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.42" + + [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 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.3.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "f87e559f87a45bece9c9ed97458d3afe98b1ebb9" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.1.0" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra"] +git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.19.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = "CUDSS" + ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + 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" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "b5bb4dc6248fde467be2a863eb8452993e74d402" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "1.1.1" + + [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.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random"] +git-tree-sha1 = "3b642331600250f592719140c60cf12372b82d66" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.1" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BitTwiddlingConvenienceFunctions]] +deps = ["Static"] +git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" +uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" +version = "0.1.6" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "535c80f1c0847a4c967ea945fca21becc9de1522" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.7+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "937628bf8b377208ac359f57314fd85d3e0165d9" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.1.4" + +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] +git-tree-sha1 = "5a97e67919535d6841172016c9530fd69494e5ec" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.6" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] +git-tree-sha1 = "b8ae59258f3d96ce75a00f9229e719356eb929d6" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.8.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_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "18afa851ed10552e6df25dfaa7ef450104ae73d4" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.13.1+0" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "33576c7c1b2500f8e7e6baa082e04563203b3a45" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.3.5" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "b5c173a64f9f4224a82fdc26fda8614cb2ecfa27" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.17.1+0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "8166751d954fdaa2e9fe183ad1a24b01343d422f" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.3.1" + +[[deps.CloseOpenIntervals]] +deps = ["Static", "StaticArrayInterface"] +git-tree-sha1 = "05ba0d07cd4fd8b7a39541e31a7b0254704ea581" +uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" +version = "0.1.13" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "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" + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + + [deps.ColorTypes.weakdeps] + StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" + +[[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", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "358bf5a7d5c1387b995a43577673290c5d344758" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.8" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[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 = "3a3dfb30697e96a440e4149c8c51bf32f818c0f3" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.17.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.1+0" + +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.ConstructionBase]] +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.6.0" + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" + ConstructionBaseStaticArraysExt = "StaticArrays" + + [deps.ConstructionBase.weakdeps] + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.CpuId]] +deps = ["Markdown"] +git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" +uuid = "adafc99b-e345-5852-983c-f28acb93d879" +version = "0.3.1" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["TaylorSeries"] +git-tree-sha1 = "afe9e8c11bf816a6fee878ddfc661e0bd138b747" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.3.2" + +[[deps.CubicSplines]] +deps = ["Random", "Test"] +git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" +uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" +version = "0.2.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "fb61b4812c49343d7ef0b533ba982c46021938a6" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.7.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DiskArrays]] +deps = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] +git-tree-sha1 = "16d93ff95ecc421463eaefd694e6746bb1c0919e" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.4.14" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.12" + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + + [deps.Distances.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.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 = "4a8c0a9eebf807ac42f0f6de758e60a20be25ffb" +uuid = "21656369-7473-754a-2065-74616d696c43" +version = "1.1.3" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "797762812ed063b9b94f6cc7742bc8883bb5e69e" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.9.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.11+0" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "b66970a70db13f45b7e57fbda1736e1cf72174ea" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.17.0" +weakdeps = ["HTTP"] + + [deps.FileIO.extensions] + HTTPExt = "HTTP" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.0.1" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "Statistics"] +git-tree-sha1 = "be941842a40b6daac98496994ea69054ba4c5144" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "11.2.3" + +[[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 = "eb1e212e12cc058fa16712082d44be499d23638c" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "1.6.1" + +[[deps.GPUToolbox]] +git-tree-sha1 = "15d8b0f5a6dca9bf8c02eeaf6687660dafa638d0" +uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" +version = "0.2.0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "e94f84da9af7ce9c6be049e9067e511e17ff89ec" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.6+0" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "ed5e9c58612c4e081aecdb6e1a479e18462e041e" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.17" + +[[deps.HashArrayMappedTries]] +git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" +uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" +version = "0.2.0" + +[[deps.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] +git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.17" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.12.1+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 = "cffa21df12f00ca1a365eb8ed107614b40e8c6da" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.4.6" + +[[deps.Inflate]] +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.InlineStrings]] +git-tree-sha1 = "8594fac023c5ce1ef78260f24d1ad18b4327b420" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.4" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + ParsersExt = "Parsers" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "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" + +[[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 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.4" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] +git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.5.15" +weakdeps = ["UnPack"] + + [deps.JLD2.extensions] + UnPackExt = "UnPack" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.0" + +[[deps.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] +git-tree-sha1 = "38a03910123867c11af988e8718d12c98bf6a234" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.37" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + LinearAlgebraExt = "LinearAlgebra" + SparseArraysExt = "SparseArrays" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.Krylov]] +deps = ["LinearAlgebra", "Printf", "SparseArrays"] +git-tree-sha1 = "b94257a1a8737099ca40bc7271a8b374033473ed" +uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" +version = "0.10.1" + +[[deps.KrylovPreconditioners]] +deps = ["Adapt", "KernelAbstractions", "LightGraphs", "LinearAlgebra", "Metis", "SparseArrays"] +git-tree-sha1 = "52d302d5e950e242f037316b6dd6e1e080afea09" +uuid = "45d422c2-293f-44ce-8315-2cb988662dec" +version = "0.3.4" + + [deps.KrylovPreconditioners.extensions] + KrylovPreconditionersAMDGPUExt = "AMDGPU" + KrylovPreconditionersCUDAExt = "CUDA" + KrylovPreconditionersOneAPIExt = "oneAPI" + + [deps.KrylovPreconditioners.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] +git-tree-sha1 = "9c7c721cfd800d87d48c745d8bfb65144f0a91df" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "9.4.2" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "2ea068aac1e7f0337d381b0eae3110581e3f3216" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.37+2" + +[[deps.LLVMLoopInfo]] +git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" +uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" +version = "1.0.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" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.LibTracyClient_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d2bc4e1034b2d43076b50f0e34ea094c2cb0a717" +uuid = "ad6e5548-8b26-5c9f-8ef3-ef0ad883f3a5" +version = "0.9.1+6" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.LightGraphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "432428df5f360964040ed60418dd5601ecd240b6" +uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" +version = "1.3.5" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[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" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f02b56007b064fbfddb4c9cd60161b6dd0f40df3" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.1.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 = "e5afce7eaf5b5ca0d444bcb4dc4fd78c54cbbac0" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.172" + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + SpecialFunctionsExt = "SpecialFunctions" + + [deps.LoopVectorization.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "191686b1ac1ea9c89fc52e996ad15d1d241d1e33" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.10.1+0" + +[[deps.METIS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2eefa8baa858871ae7770c98c3c2a7e46daba5b4" +uuid = "d00139f3-1899-568f-a2f0-47f597d42d70" +version = "5.1.3+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", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "892676019c58f34e38743bc989b0eca5bce5edc5" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.22" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.3.1+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.11" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.5.4+0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.Metis]] +deps = ["CEnum", "LinearAlgebra", "METIS_jll", "SparseArrays"] +git-tree-sha1 = "54aca4fd53d39dcd2c3f1bef367b6921e8178628" +uuid = "2679e427-3c69-5b7f-982b-ece356f1e94b" +version = "1.5.0" + + [deps.Metis.extensions] + MetisGraphs = "Graphs" + MetisLightGraphs = "LightGraphs" + MetisSimpleWeightedGraphs = ["SimpleWeightedGraphs", "Graphs"] + + [deps.Metis.weakdeps] + Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" + LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" + SimpleWeightedGraphs = "47aef6b3-ad0c-573a-a1e2-d07658019622" + +[[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" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.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 = "be1095e2b767c19529409ec670bcfb01b825d717" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.8" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "1a24c3430fa2ef3317c4c97fa7e431ef45793bd2" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "1.0.0" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "cd475b587ff77910789a18e68da789fc446a2a05" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.2.1+0" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML", "XML2_jll", "Zlib_jll", "Zstd_jll", "libaec_jll", "libzip_jll"] +git-tree-sha1 = "d574803b6055116af212434460adf654ce98e345" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "401.900.300+0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Oceananigans]] +deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "50edc3e63e5e72c1a1cbe08701d79adb3a0cbed3" +repo-rev = "ss/fix-zstar-bc" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.97.1" + + [deps.Oceananigans.extensions] + OceananigansAMDGPUExt = "AMDGPU" + OceananigansCUDAExt = "CUDA" + OceananigansEnzymeExt = "Enzyme" + OceananigansMakieExt = ["MakieCore", "Makie"] + OceananigansMetalExt = "Metal" + OceananigansNCDatasetsExt = "NCDatasets" + OceananigansOneAPIExt = "oneAPI" + OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase"] + + [deps.Oceananigans.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" + Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" + 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.23+4" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.5+0" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] +git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.8+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "87510f7292a2b21aeff97912b0898f9553cc5c2c" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+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.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PolyesterWeave]] +deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] +git-tree-sha1 = "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 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.4.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.6" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Random123]] +deps = ["Random", "RandomNumbers"] +git-tree-sha1 = "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.ReactantCore]] +deps = ["ExpressionExplorer", "MacroTools"] +git-tree-sha1 = "120feaf6a97738e3a63902644a0afb3b69cc7b98" +uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" +version = "0.1.15" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.RootSolvers]] +deps = ["ForwardDiff", "Printf"] +git-tree-sha1 = "892b77767827af30868111d257930f567d5d78f8" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.4" + +[[deps.Roots]] +deps = ["Accessors", "CommonSolve", "Printf"] +git-tree-sha1 = "668e411c0616a70860249b4c96e5d35296631a1d" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.2.8" + + [deps.Roots.extensions] + RootsChainRulesCoreExt = "ChainRulesCore" + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + + [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" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.1" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SIMDTypes]] +git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" +uuid = "94e857df-77ce-4151-89e5-788b33177be4" +version = "0.1.0" + +[[deps.SLEEFPirates]] +deps = ["IfElse", "Static", "VectorizationBase"] +git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.43" + +[[deps.ScopedValues]] +deps = ["HashArrayMappedTries", "Logging"] +git-tree-sha1 = "7f44eef6b1d284465fafc66baf4d9bdcc239a15b" +uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" +version = "1.4.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 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.8" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.5.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "be1cf4eb0ac528d96f5115b4ed80c26a8d8ae621" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.2" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] +git-tree-sha1 = "f737d444cb0ad07e61b3c1bef8eb91203c321eff" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.2.0" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] +git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.8.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "cbea8a6bd7bed51b1619658dec70035e07b8502f" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.14" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.4.1" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "8ad2e38cbb812e29348719cc63580ec1dfeb9de4" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.7.1" +weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = ["GPUArraysCore", "KernelAbstractions"] + StructArraysLinearAlgebraExt = "LinearAlgebra" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "aee530bde85cd41374273568cb649e72d82921e7" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.12.0" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "ClimaParams" + + [deps.SurfaceFluxes.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "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 = "2c308aab2e14b399e4b8d6af7c486a241c8ca87a" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.19.1" + + [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" + +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "94f0e8e3135840568082e62fb69d31669539e627" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.14" + + [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 = "91dbaee0f50faa4357f7e9fc69442c7b6364dfe5" +uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" +version = "0.1.5" + + [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" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "b13c4edda90890e5b04ba24e20a310fbe6f249ff" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.3.0" +weakdeps = ["LLVM"] + + [deps.UnsafeAtomics.extensions] + UnsafeAtomicsLLVM = ["LLVM"] + +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "4ab62a49f1d8d9548a1c8d1a75e5f55cf196f64e" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.71" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "b8b243e47228b4a3877f1dd6aee0c5d56db7fcf4" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.13.6+1" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.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.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.demumble_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6498e3581023f8e530f34760d18f75a69e3a4ea8" +uuid = "1e29f10c-031c-5a83-9565-69cddfc27673" +version = "1.3.0+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f5733a5a9047722470b95a81e1b172383971105c" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.1.3+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.11.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.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2022.0.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" From d7ef440c5ea314f52367efa88ddca1483c4dbf09 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 21 Jul 2025 09:11:50 -0400 Subject: [PATCH 149/203] update --- .../similarity_theory_turbulent_fluxes.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index dd3221952..efaf8eca3 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -35,6 +35,7 @@ Adapt.adapt_structure(to, fluxes::SimilarityTheoryFluxes) = SimilarityTheoryFluxes(adapt(to, fluxes.von_karman_constant), adapt(to, fluxes.turbulent_prandtl_number), adapt(to, fluxes.gustiness_parameter), + adapt(to, fluxes.minimum_velocity_scale), adapt(to, fluxes.stability_functions), adapt(to, fluxes.roughness_lengths), adapt(to, fluxes.similarity_form), @@ -59,7 +60,7 @@ end gravitational_acceleration = 9.81, von_karman_constant = 0.4, turbulent_prandtl_number = 1, - gustiness_parameter = 3.5, + gustiness_parameter = 1, stability_functions = default_stability_functions(FT), roughness_lengths = default_roughness_lengths(FT), similarity_form = LogarithmicSimilarityProfile(), @@ -88,7 +89,7 @@ Keyword Arguments function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; von_karman_constant = 0.4, turbulent_prandtl_number = 1, - gustiness_parameter = 3.5, + gustiness_parameter = 2, stability_functions = atmosphere_ocean_stability_functions(FT), momentum_roughness_length = MomentumRoughnessLength(FT), temperature_roughness_length = ScalarRoughnessLength(FT), @@ -215,7 +216,7 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, # Transfer coefficients at height `h` ϰ = flux_formulation.von_karman_constant - L★ = ifelse(b★ == 0, Inf, - u★^2 / (ϰ * b★)) + L★ = ifelse(b★ == 0, Inf, u★^2 / (ϰ * b★)) form = flux_formulation.similarity_form χu = ϰ / similarity_profile(form, ψu, Δh, ℓu₀, L★) From b3ab48b124502a0f539322105746ed984d868f7f Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 22 Jul 2025 10:50:12 +0200 Subject: [PATCH 150/203] remove equatorial single column --- equatorial_single_column.jl | 275 ------------------------------------ 1 file changed, 275 deletions(-) delete mode 100644 equatorial_single_column.jl diff --git a/equatorial_single_column.jl b/equatorial_single_column.jl deleted file mode 100644 index 2aaeb91ec..000000000 --- a/equatorial_single_column.jl +++ /dev/null @@ -1,275 +0,0 @@ -using ClimaOcean -using Oceananigans -using Oceananigans.Units -using Oceananigans.BuoyancyFormulations: buoyancy_frequency -using Oceananigans.Units: Time -using Dates -using Printf -using GLMakie - -location_name = "equatorial_shallow_regions" -z_faces = ExponentialCoordinate(60, -6200) -z_faces = Oceananigans.Grids.MutableVerticalDiscretization(z_faces) -λ★ = 123.21302547843129 -φ★ = 9.894610398995553 - -grid = LatitudeLongitudeGrid(size = (3, 3, 60), - longitude = (λ★-0.5, λ★+0.5), - latitude = (φ★-0.5, φ★+0.5), - z = z_faces, - topology = (Bounded, Bounded, Bounded)) - -bottom_height = [0.0 0.0 0.0; - 0.0 0.0 0.0; - -384.522 -161.595 0.0] - -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) - -@info "Building the simulation" - -ocean = ocean_simulation(grid; - Δt=20minutes, - momentum_advection=nothing, - tracer_advection=nothing) - -set!(ocean.model, T=Metadatum(:temperature, dataset=ECCO4Monthly()), - S=Metadatum(:salinity, dataset=ECCO4Monthly())) - -atmosphere = JRA55PrescribedAtmosphere(end_date = DateTime(1958, 12, 30), # Last day of the simulation - backend = JRA55NetCDFBackend(100), - dataset = MultiYearJRA55(), - dir = "./") -radiation = Radiation() -coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation) -simulation = Simulation(coupled_model, Δt=ocean.Δt, stop_time=7200days) - -wall_clock = Ref(time_ns()) - -function progress(sim) - msg = "Ocean Station Papa" - msg *= string(", iter: ", iteration(sim), ", time: ", prettytime(sim)) - - elapsed = 1e-9 * (time_ns() - wall_clock[]) - msg *= string(", wall time: ", prettytime(elapsed)) - wall_clock[] = time_ns() - - u, v, w = sim.model.ocean.model.velocities - msg *= @sprintf(", max|u|: (%.2e, %.2e)", maximum(abs, u), maximum(abs, v)) - - T = sim.model.ocean.model.tracers.T - S = sim.model.ocean.model.tracers.S - e = if sim.model.ocean.model.closure isa CATKEVerticalDiffusivity - sim.model.ocean.model.tracers.e - else - sim.model.ocean.model.tracers.S - end - - τx = first(sim.model.interfaces.net_fluxes.ocean_surface.u) - τy = first(sim.model.interfaces.net_fluxes.ocean_surface.v) - Q = first(sim.model.interfaces.net_fluxes.ocean_surface.Q) - - u★ = sqrt(sqrt(τx^2 + τy^2)) - - Nz = size(T, 3) - msg *= @sprintf(", u★: %.2f m s⁻¹", u★) - msg *= @sprintf(", Q: %.2f W m⁻²", Q) - msg *= @sprintf(", T₀: %.2f ᵒC", first(interior(T, 1, 1, Nz))) - msg *= @sprintf(", extrema(T): (%.2f, %.2f) ᵒC", minimum(T), maximum(T)) - msg *= @sprintf(", S₀: %.2f g/kg", first(interior(S, 1, 1, Nz))) - msg *= @sprintf(", e₀: %.2e m² s⁻²", first(interior(e, 1, 1, Nz))) - - @info msg - - return nothing -end - -simulation.callbacks[:progress] = Callback(progress, IterationInterval(100)) - -# Build flux outputs -τx = simulation.model.interfaces.net_fluxes.ocean_surface.u -τy = simulation.model.interfaces.net_fluxes.ocean_surface.v -JT = simulation.model.interfaces.net_fluxes.ocean_surface.T -Js = simulation.model.interfaces.net_fluxes.ocean_surface.S -E = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.water_vapor -Qc = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.sensible_heat -Qv = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.latent_heat -Qu = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.upwelling_longwave -Ql = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.downwelling_longwave -Qs = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.downwelling_shortwave -ρₒ = simulation.model.interfaces.ocean_properties.reference_density -cₚ = simulation.model.interfaces.ocean_properties.heat_capacity -ua = simulation.model.interfaces.exchanger.exchange_atmosphere_state.u -va = simulation.model.interfaces.exchanger.exchange_atmosphere_state.v -Ta = simulation.model.interfaces.exchanger.exchange_atmosphere_state.T -qa = simulation.model.interfaces.exchanger.exchange_atmosphere_state.q -Fwf = simulation.model.interfaces.exchanger.exchange_atmosphere_state.Mp -u★ = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity -θ★ = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.temperature_scale -q★ = simulation.model.interfaces.atmosphere_ocean_interface.fluxes.water_vapor_scale -Ts = simulation.model.interfaces.atmosphere_ocean_interface.temperature -qs = simulation.model.interfaces.atmosphere_ocean_interface.humidity - -Q = ρₒ * cₚ * JT -ρτx = ρₒ * τx -ρτy = ρₒ * τy -N² = buoyancy_frequency(ocean.model) -κc = ocean.model.diffusivity_fields.κc - -fluxes = (; ρτx, ρτy, E, Js, JT, Q, Qv, Qc, ua, va, Ta, qa, Qs, Ql, Qu, Fwf, u★, θ★, q★, Ts, qs) -auxiliary_fields = (; N², κc) -fields = merge(ocean.model.velocities, ocean.model.tracers, auxiliary_fields) - -# Slice fields at the surface -outputs = merge(fields, fluxes) - -filename = "single_column_omip_$(location_name)_take2" - -simulation.output_writers[:jld2] = JLD2Writer(ocean.model, outputs; filename, - schedule = TimeInterval(8hours), - overwrite_existing = true) - -run!(simulation) - -filename *= ".jld2" - -ua = FieldTimeSeries(filename, "ua") -va = FieldTimeSeries(filename, "va") -Ta = FieldTimeSeries(filename, "Ta") -qa = FieldTimeSeries(filename, "qa") -Ql = FieldTimeSeries(filename, "Ql") -Qs = FieldTimeSeries(filename, "Qs") -Qu = FieldTimeSeries(filename, "Qu") -Pt = FieldTimeSeries(filename, "Fwf") - -u = FieldTimeSeries(filename, "u") -v = FieldTimeSeries(filename, "v") -T = FieldTimeSeries(filename, "T") -S = FieldTimeSeries(filename, "S") -e = if ocean.model.closure isa CATKEVerticalDiffusivity - FieldTimeSeries(filename, "e") -else - FieldTimeSeries(filename, "S") # Use salinity as a proxy for e -end - -N² = FieldTimeSeries(filename, "N²") -κ = FieldTimeSeries(filename, "κc") - -Qv = FieldTimeSeries(filename, "Qv") -Qc = FieldTimeSeries(filename, "Qc") -Q = FieldTimeSeries(filename, "Q") -Js = FieldTimeSeries(filename, "Js") -Ev = FieldTimeSeries(filename, "E") -ρτx = FieldTimeSeries(filename, "ρτx") -ρτy = FieldTimeSeries(filename, "ρτy") -u★ = FieldTimeSeries(filename, "u★") -θ★ = FieldTimeSeries(filename, "θ★") -q★ = FieldTimeSeries(filename, "q★") -Ts = FieldTimeSeries(filename, "Ts") -qs = FieldTimeSeries(filename, "qs") - -Nz = size(T, 3) -times = Qc.times -ρₒ = coupled_model.interfaces.ocean_properties.reference_density - -fig = Figure(size=(1800, 1800)) - -axτ = Axis(fig[1, 1:3], xlabel="Days since Oct 1 1992", ylabel="Wind stress (N m⁻²)") -axQ = Axis(fig[1, 4:6], xlabel="Days since Oct 1 1992", ylabel="Heat flux (W m⁻²)") -axu = Axis(fig[2, 1:3], xlabel="Days since Oct 1 1992", ylabel="Velocities (m s⁻¹)") -axT = Axis(fig[2, 4:6], xlabel="Days since Oct 1 1992", ylabel="Surface temperature (ᵒC)") -axF = Axis(fig[3, 1:3], xlabel="Days since Oct 1 1992", ylabel="Freshwater volume flux (m s⁻¹)") -axS = Axis(fig[3, 4:6], xlabel="Days since Oct 1 1992", ylabel="Surface salinity (g kg⁻¹)") - -axuz = Axis(fig[4:5, 1:2], xlabel="Velocities (m s⁻¹)", ylabel="z (m)") -axTz = Axis(fig[4:5, 3:4], xlabel="Temperature (ᵒC)", ylabel="z (m)") -axSz = Axis(fig[4:5, 5:6], xlabel="Salinity (g kg⁻¹)", ylabel="z (m)") -axNz = Axis(fig[6:7, 1:2], xlabel="Buoyancy frequency (s⁻²)", ylabel="z (m)") -axκz = Axis(fig[6:7, 3:4], xlabel="Eddy diffusivity (m² s⁻¹)", ylabel="z (m)") #, xscale=log10) -axez = Axis(fig[6:7, 5:6], xlabel="Turbulent kinetic energy (m² s⁻²)", ylabel="z (m)") #, xscale=log10) - -title = @sprintf("Single-column simulation at %.2f, %.2f", φ★, λ★) -Label(fig[0, 1:6], title) - -n = Observable(1) - -times = (times .- times[1]) ./days -Nt = length(times) -tn = @lift times[$n] - -colors = Makie.wong_colors() - -τx = interior(ρτx, 3, 2, 1, :) ./ ρₒ -τy = interior(ρτy, 3, 2, 1, :) ./ ρₒ - -lines!(axu, times, interior(u, 3, 2, Nz, :), color=colors[1], label="Zonal") -lines!(axu, times, interior(v, 3, 2, Nz, :), color=colors[2], label="Meridional") -lines!(axu, times, interior(u★, 3, 2, 1, :), color=colors[3], label="Ocean-side u★") -vlines!(axu, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axu) - -lines!(axτ, times, interior(ρτx, 3, 2, 1, :), label="Zonal") -lines!(axτ, times, interior(ρτy, 3, 2, 1, :), label="Meridional") -vlines!(axτ, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axτ) - -lines!(axT, times, interior(Ta, 3, 2, 1, 1:Nt) .- 273.15, color=colors[1], linewidth=2, linestyle=:dash, label="Atmosphere temperature") -lines!(axT, times, interior(T, 3, 2, Nz, :), color=colors[2], linewidth=4, label="Ocean surface temperature") -vlines!(axT, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axT) - -lines!(axQ, times, interior(Qc, 3, 2, 1, 1:Nt), color=colors[2], label="Sensible", linewidth=2) -lines!(axQ, times, interior(Qv, 3, 2, 1, 1:Nt), color=colors[3], label="Latent", linewidth=2) -lines!(axQ, times, interior(Qs, 3, 2, 1, 1:Nt), color=colors[4], label="Shortwave", linewidth=2) -lines!(axQ, times, interior(Ql, 3, 2, 1, 1:Nt), color=colors[5], label="Longwave", linewidth=2) -lines!(axQ, times, interior(Qu, 3, 2, 1, 1:Nt), color=colors[6], label="Upwelling", linewidth=2) -lines!(axQ, times, interior(Q, 3, 2, 1, 1:Nt), color=colors[7], label="Total heat flux", linewidth=4) -vlines!(axQ, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axQ) - -lines!(axF, times, interior(Pt, 3, 2, 1, 1:Nt), label="Prescribed freshwater flux") -lines!(axF, times, - interior(Ev, 3, 2, 1, 1:Nt), label="Evaporation") -vlines!(axF, tn, linewidth=4, color=(:black, 0.5)) -axislegend(axF) - -lines!(axS, times, interior(S, 3, 2, Nz, :)) -vlines!(axS, tn, linewidth=4, color=(:black, 0.5)) - -zc = znodes(T) -zf = znodes(κ) -un = @lift interior(u[$n], 3, 2, :) -vn = @lift interior(v[$n], 3, 2, :) -Tn = @lift interior(T[$n], 3, 2, :) -Sn = @lift interior(S[$n], 3, 2, :) -κn = @lift log10.(interior(κ[$n], 3, 2, :)) -en = @lift interior(e[$n], 3, 2, :) -N²n = @lift interior(N²[$n], 3, 2, :) - -scatterlines!(axuz, un, zc, label="u") -scatterlines!(axuz, vn, zc, label="v") -scatterlines!(axTz, Tn, zc) -scatterlines!(axSz, Sn, zc) -scatterlines!(axez, en, zc) -scatterlines!(axNz, N²n, zf) -scatterlines!(axκz, κn, zf) -ylims!(axuz, (-400, 0)) -ylims!(axTz, (-400, 0)) -ylims!(axSz, (-400, 0)) -ylims!(axez, (-400, 0)) -ylims!(axNz, (-400, 0)) -ylims!(axκz, (-400, 0)) - -xlims!(axTz, (15, 45)) -xlims!(axSz, (32, 37)) -xlims!(axez, (0, 0.00035)) -xlims!(axκz, (-8, 1)) -xlims!(axSz, (32, 37)) - -axislegend(axuz) - -record(fig, "single_column_profiles.mp4", 1:Nt, framerate=24) do nn - @info "Drawing frame $nn of $Nt..." - n[] = nn -end -nothing #hide - -# ![](single_column_profiles.mp4) From d1c74502ef7641f32defa811777a0c452f419bcb Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 22 Jul 2025 10:50:37 +0200 Subject: [PATCH 151/203] remove manifest --- Manifest.toml | 1547 ------------------------------------------------- 1 file changed, 1547 deletions(-) delete mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index 8397e00df..000000000 --- a/Manifest.toml +++ /dev/null @@ -1,1547 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.10" -manifest_format = "2.0" -project_hash = "bb09aa984e1a9dbd83743fc29ea3d49437328c99" - -[[deps.AbstractFFTs]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.5.0" - - [deps.AbstractFFTs.extensions] - AbstractFFTsChainRulesCoreExt = "ChainRulesCore" - AbstractFFTsTestExt = "Test" - - [deps.AbstractFFTs.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "3b86719127f50670efe356bc11073d84b4ed7a5d" -uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.42" - - [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 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.3.0" -weakdeps = ["SparseArrays", "StaticArrays"] - - [deps.Adapt.extensions] - AdaptSparseArraysExt = "SparseArrays" - AdaptStaticArraysExt = "StaticArrays" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.ArnoldiMethod]] -deps = ["LinearAlgebra", "Random", "StaticArrays"] -git-tree-sha1 = "f87e559f87a45bece9c9ed97458d3afe98b1ebb9" -uuid = "ec485272-7323-5ecc-a04f-4719b315124d" -version = "0.1.0" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.19.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = "CUDSS" - ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceSparseArraysExt = "SparseArrays" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - 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" - -[[deps.Atomix]] -deps = ["UnsafeAtomics"] -git-tree-sha1 = "b5bb4dc6248fde467be2a863eb8452993e74d402" -uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" -version = "1.1.1" - - [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.BFloat16s]] -deps = ["LinearAlgebra", "Printf", "Random"] -git-tree-sha1 = "3b642331600250f592719140c60cf12372b82d66" -uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" -version = "0.5.1" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[deps.BitFlags]] -git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.9" - -[[deps.BitTwiddlingConvenienceFunctions]] -deps = ["Static"] -git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" -uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" -version = "0.1.6" - -[[deps.Blosc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "535c80f1c0847a4c967ea945fca21becc9de1522" -uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" -version = "1.21.7+0" - -[[deps.Bzip2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" -uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.9+0" - -[[deps.CEnum]] -git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" -uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.5.0" - -[[deps.CFTime]] -deps = ["Dates", "Printf"] -git-tree-sha1 = "937628bf8b377208ac359f57314fd85d3e0165d9" -uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.1.4" - -[[deps.CPUSummary]] -deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "5a97e67919535d6841172016c9530fd69494e5ec" -uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.6" - -[[deps.CUDA]] -deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] -git-tree-sha1 = "b8ae59258f3d96ce75a00f9229e719356eb929d6" -uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.8.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_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "18afa851ed10552e6df25dfaa7ef450104ae73d4" -uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.13.1+0" - -[[deps.CUDA_Runtime_Discovery]] -deps = ["Libdl"] -git-tree-sha1 = "33576c7c1b2500f8e7e6baa082e04563203b3a45" -uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.3.5" - -[[deps.CUDA_Runtime_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "b5c173a64f9f4224a82fdc26fda8614cb2ecfa27" -uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.17.1+0" - -[[deps.ClimaSeaIce]] -deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "8166751d954fdaa2e9fe183ad1a24b01343d422f" -uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.3.1" - -[[deps.CloseOpenIntervals]] -deps = ["Static", "StaticArrayInterface"] -git-tree-sha1 = "05ba0d07cd4fd8b7a39541e31a7b0254704ea581" -uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" -version = "0.1.13" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "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" - - [deps.ColorTypes.extensions] - StyledStringsExt = "StyledStrings" - - [deps.ColorTypes.weakdeps] - StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" - -[[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", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "358bf5a7d5c1387b995a43577673290c5d344758" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.8" - -[[deps.CommonSolve]] -git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" -uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.4" - -[[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 = "3a3dfb30697e96a440e4149c8c51bf32f818c0f3" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.17.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.1+0" - -[[deps.CompositionsBase]] -git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" -uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" -version = "0.1.2" -weakdeps = ["InverseFunctions"] - - [deps.CompositionsBase.extensions] - CompositionsBaseInverseFunctionsExt = "InverseFunctions" - -[[deps.ConcurrentUtilities]] -deps = ["Serialization", "Sockets"] -git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.5.0" - -[[deps.ConstructionBase]] -git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.6.0" - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseLinearAlgebraExt = "LinearAlgebra" - ConstructionBaseStaticArraysExt = "StaticArrays" - - [deps.ConstructionBase.weakdeps] - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.CpuId]] -deps = ["Markdown"] -git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" -uuid = "adafc99b-e345-5852-983c-f28acb93d879" -version = "0.3.1" - -[[deps.Crayons]] -git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" -uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" -version = "4.1.1" - -[[deps.CubedSphere]] -deps = ["TaylorSeries"] -git-tree-sha1 = "afe9e8c11bf816a6fee878ddfc661e0bd138b747" -uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.3.2" - -[[deps.CubicSplines]] -deps = ["Random", "Test"] -git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" -uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" -version = "0.2.1" - -[[deps.DataAPI]] -git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.16.0" - -[[deps.DataDeps]] -deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] -git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" -uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.13" - -[[deps.DataFrames]] -deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "fb61b4812c49343d7ef0b533ba982c46021938a6" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.7.0" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.22" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.DiffResults]] -deps = ["StaticArraysCore"] -git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "1.1.0" - -[[deps.DiffRules]] -deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.15.1" - -[[deps.DiskArrays]] -deps = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] -git-tree-sha1 = "16d93ff95ecc421463eaefd694e6746bb1c0919e" -uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.4.14" - -[[deps.Distances]] -deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.12" - - [deps.Distances.extensions] - DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesSparseArraysExt = "SparseArrays" - - [deps.Distances.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[deps.DocStringExtensions]] -git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.5" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.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 = "4a8c0a9eebf807ac42f0f6de758e60a20be25ffb" -uuid = "21656369-7473-754a-2065-74616d696c43" -version = "1.1.3" - -[[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "797762812ed063b9b94f6cc7742bc8883bb5e69e" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.9.0" - -[[deps.FFTW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" -uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.11+0" - -[[deps.FileIO]] -deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "b66970a70db13f45b7e57fbda1736e1cf72174ea" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.17.0" -weakdeps = ["HTTP"] - - [deps.FileIO.extensions] - HTTPExt = "HTTP" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.0.1" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[deps.GPUArrays]] -deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "Statistics"] -git-tree-sha1 = "be941842a40b6daac98496994ea69054ba4c5144" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "11.2.3" - -[[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 = "eb1e212e12cc058fa16712082d44be499d23638c" -uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "1.6.1" - -[[deps.GPUToolbox]] -git-tree-sha1 = "15d8b0f5a6dca9bf8c02eeaf6687660dafa638d0" -uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" -version = "0.2.0" - -[[deps.Glob]] -git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" -uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" -version = "1.3.1" - -[[deps.HDF5_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] -git-tree-sha1 = "e94f84da9af7ce9c6be049e9067e511e17ff89ec" -uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" -version = "1.14.6+0" - -[[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "ed5e9c58612c4e081aecdb6e1a479e18462e041e" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.17" - -[[deps.HashArrayMappedTries]] -git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" -uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" -version = "0.2.0" - -[[deps.HostCPUFeatures]] -deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] -git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" -uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.17" - -[[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.12.1+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 = "cffa21df12f00ca1a365eb8ed107614b40e8c6da" -uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" -version = "0.4.6" - -[[deps.Inflate]] -git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.5" - -[[deps.InlineStrings]] -git-tree-sha1 = "8594fac023c5ce1ef78260f24d1ad18b4327b420" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.4" - - [deps.InlineStrings.extensions] - ArrowTypesExt = "ArrowTypes" - ParsersExt = "Parsers" - - [deps.InlineStrings.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "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" - -[[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 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.4" - -[[deps.IterativeSolvers]] -deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] -git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" -uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" -version = "0.9.4" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] -git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.5.15" -weakdeps = ["UnPack"] - - [deps.JLD2.extensions] - UnPackExt = "UnPack" - -[[deps.JLLWrappers]] -deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.7.0" - -[[deps.JuliaNVTXCallbacks_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" -uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" -version = "0.2.1+0" - -[[deps.KernelAbstractions]] -deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] -git-tree-sha1 = "38a03910123867c11af988e8718d12c98bf6a234" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.37" - - [deps.KernelAbstractions.extensions] - EnzymeExt = "EnzymeCore" - LinearAlgebraExt = "LinearAlgebra" - SparseArraysExt = "SparseArrays" - - [deps.KernelAbstractions.weakdeps] - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[deps.Krylov]] -deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "b94257a1a8737099ca40bc7271a8b374033473ed" -uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.10.1" - -[[deps.KrylovPreconditioners]] -deps = ["Adapt", "KernelAbstractions", "LightGraphs", "LinearAlgebra", "Metis", "SparseArrays"] -git-tree-sha1 = "52d302d5e950e242f037316b6dd6e1e080afea09" -uuid = "45d422c2-293f-44ce-8315-2cb988662dec" -version = "0.3.4" - - [deps.KrylovPreconditioners.extensions] - KrylovPreconditionersAMDGPUExt = "AMDGPU" - KrylovPreconditionersCUDAExt = "CUDA" - KrylovPreconditionersOneAPIExt = "oneAPI" - - [deps.KrylovPreconditioners.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" - -[[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] -git-tree-sha1 = "9c7c721cfd800d87d48c745d8bfb65144f0a91df" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "9.4.2" -weakdeps = ["BFloat16s"] - - [deps.LLVM.extensions] - BFloat16sExt = "BFloat16s" - -[[deps.LLVMExtra_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "2ea068aac1e7f0337d381b0eae3110581e3f3216" -uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.37+2" - -[[deps.LLVMLoopInfo]] -git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" -uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" -version = "1.0.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" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.4.0+0" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.6.4+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.LibTracyClient_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d2bc4e1034b2d43076b50f0e34ea094c2cb0a717" -uuid = "ad6e5548-8b26-5c9f-8ef3-ef0ad883f3a5" -version = "0.9.1+6" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.18.0+0" - -[[deps.LightGraphs]] -deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "432428df5f360964040ed60418dd5601ecd240b6" -uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" -version = "1.3.5" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[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" - -[[deps.LoggingExtras]] -deps = ["Dates", "Logging"] -git-tree-sha1 = "f02b56007b064fbfddb4c9cd60161b6dd0f40df3" -uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.1.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 = "e5afce7eaf5b5ca0d444bcb4dc4fd78c54cbbac0" -uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.172" - - [deps.LoopVectorization.extensions] - ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] - SpecialFunctionsExt = "SpecialFunctions" - - [deps.LoopVectorization.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.Lz4_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "191686b1ac1ea9c89fc52e996ad15d1d241d1e33" -uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" -version = "1.10.1+0" - -[[deps.METIS_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2eefa8baa858871ae7770c98c3c2a7e46daba5b4" -uuid = "d00139f3-1899-568f-a2f0-47f597d42d70" -version = "5.1.3+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", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] -git-tree-sha1 = "892676019c58f34e38743bc989b0eca5bce5edc5" -uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" -version = "0.20.22" - - [deps.MPI.extensions] - AMDGPUExt = "AMDGPU" - CUDAExt = "CUDA" - - [deps.MPI.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - -[[deps.MPICH_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.3.1+0" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.11" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.5.4+0" - -[[deps.MacroTools]] -git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.16" - -[[deps.ManualMemory]] -git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" -uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" -version = "0.1.8" - -[[deps.MappedArrays]] -git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.2" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.9" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+1" - -[[deps.Metis]] -deps = ["CEnum", "LinearAlgebra", "METIS_jll", "SparseArrays"] -git-tree-sha1 = "54aca4fd53d39dcd2c3f1bef367b6921e8178628" -uuid = "2679e427-3c69-5b7f-982b-ece356f1e94b" -version = "1.5.0" - - [deps.Metis.extensions] - MetisGraphs = "Graphs" - MetisLightGraphs = "LightGraphs" - MetisSimpleWeightedGraphs = ["SimpleWeightedGraphs", "Graphs"] - - [deps.Metis.weakdeps] - Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" - LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" - SimpleWeightedGraphs = "47aef6b3-ad0c-573a-a1e2-d07658019622" - -[[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" - -[[deps.MosaicViews]] -deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] -git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" -uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" -version = "0.3.4" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.1.10" - -[[deps.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 = "be1095e2b767c19529409ec670bcfb01b825d717" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.8" - -[[deps.NVTX]] -deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] -git-tree-sha1 = "1a24c3430fa2ef3317c4c97fa7e431ef45793bd2" -uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" -version = "1.0.0" - -[[deps.NVTX_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cd475b587ff77910789a18e68da789fc446a2a05" -uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" -version = "3.2.1+0" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.1.3" - -[[deps.NetCDF_jll]] -deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML", "XML2_jll", "Zlib_jll", "Zstd_jll", "libaec_jll", "libzip_jll"] -git-tree-sha1 = "d574803b6055116af212434460adf654ce98e345" -uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" -version = "401.900.300+0" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.Oceananigans]] -deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "50edc3e63e5e72c1a1cbe08701d79adb3a0cbed3" -repo-rev = "ss/fix-zstar-bc" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" -uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.97.1" - - [deps.Oceananigans.extensions] - OceananigansAMDGPUExt = "AMDGPU" - OceananigansCUDAExt = "CUDA" - OceananigansEnzymeExt = "Enzyme" - OceananigansMakieExt = ["MakieCore", "Makie"] - OceananigansMetalExt = "Metal" - OceananigansNCDatasetsExt = "NCDatasets" - OceananigansOneAPIExt = "oneAPI" - OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase"] - - [deps.Oceananigans.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" - Metal = "dde4c033-4e86-420c-a63e-0dd931031962" - NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" - Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" - 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.23+4" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.5+0" - -[[deps.OpenMPI_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] -git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.8+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.5.0" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "87510f7292a2b21aeff97912b0898f9553cc5c2c" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.1+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.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.10.0" - -[[deps.PkgVersion]] -deps = ["Pkg"] -git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" -uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.3" - -[[deps.PolyesterWeave]] -deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] -git-tree-sha1 = "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 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.1" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.3" - -[[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34" -uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.4.0" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[deps.Quaternions]] -deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" -uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.6" - -[[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[deps.Random123]] -deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "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.ReactantCore]] -deps = ["ExpressionExplorer", "MacroTools"] -git-tree-sha1 = "120feaf6a97738e3a63902644a0afb3b69cc7b98" -uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" -version = "0.1.15" - -[[deps.RealDot]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" -uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" -version = "0.1.0" - -[[deps.RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.1" - -[[deps.RootSolvers]] -deps = ["ForwardDiff", "Printf"] -git-tree-sha1 = "892b77767827af30868111d257930f567d5d78f8" -uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" -version = "0.4.4" - -[[deps.Roots]] -deps = ["Accessors", "CommonSolve", "Printf"] -git-tree-sha1 = "668e411c0616a70860249b4c96e5d35296631a1d" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.2.8" - - [deps.Roots.extensions] - RootsChainRulesCoreExt = "ChainRulesCore" - RootsForwardDiffExt = "ForwardDiff" - RootsIntervalRootFindingExt = "IntervalRootFinding" - RootsSymPyExt = "SymPy" - RootsSymPyPythonCallExt = "SymPyPythonCall" - - [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" - -[[deps.Rotations]] -deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] -git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" -uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" -version = "1.7.1" -weakdeps = ["RecipesBase"] - - [deps.Rotations.extensions] - RotationsRecipesBaseExt = "RecipesBase" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.SIMDTypes]] -git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" -uuid = "94e857df-77ce-4151-89e5-788b33177be4" -version = "0.1.0" - -[[deps.SLEEFPirates]] -deps = ["IfElse", "Static", "VectorizationBase"] -git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" -uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" -version = "0.6.43" - -[[deps.ScopedValues]] -deps = ["HashArrayMappedTries", "Logging"] -git-tree-sha1 = "7f44eef6b1d284465fafc66baf4d9bdcc239a15b" -uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" -version = "1.4.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 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" -uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.8" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[deps.SimpleBufferStream]] -git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.2.0" - -[[deps.SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[deps.SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.10.0" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.5.1" - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - - [deps.SpecialFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "be1cf4eb0ac528d96f5115b4ed80c26a8d8ae621" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.2" - -[[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] -git-tree-sha1 = "f737d444cb0ad07e61b3c1bef8eb91203c321eff" -uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.2.0" - -[[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] -git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" -uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.8.0" -weakdeps = ["OffsetArrays", "StaticArrays"] - - [deps.StaticArrayInterface.extensions] - StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" - StaticArrayInterfaceStaticArraysExt = "StaticArrays" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "cbea8a6bd7bed51b1619658dec70035e07b8502f" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.14" - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - - [deps.StaticArrays.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.3" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.1" - -[[deps.StringManipulation]] -deps = ["PrecompileTools"] -git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023" -uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.4.1" - -[[deps.StructArrays]] -deps = ["ConstructionBase", "DataAPI", "Tables"] -git-tree-sha1 = "8ad2e38cbb812e29348719cc63580ec1dfeb9de4" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.7.1" -weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"] - - [deps.StructArrays.extensions] - StructArraysAdaptExt = "Adapt" - StructArraysGPUArraysCoreExt = ["GPUArraysCore", "KernelAbstractions"] - StructArraysLinearAlgebraExt = "LinearAlgebra" - StructArraysSparseArraysExt = "SparseArrays" - StructArraysStaticArraysExt = "StaticArrays" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" - -[[deps.SurfaceFluxes]] -deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "aee530bde85cd41374273568cb649e72d82921e7" -uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.12.0" - - [deps.SurfaceFluxes.extensions] - CreateParametersExt = "ClimaParams" - - [deps.SurfaceFluxes.weakdeps] - ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "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 = "2c308aab2e14b399e4b8d6af7c486a241c8ca87a" -uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.19.1" - - [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" - -[[deps.Thermodynamics]] -deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "94f0e8e3135840568082e62fb69d31669539e627" -uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.12.14" - - [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 = "91dbaee0f50faa4357f7e9fc69442c7b6364dfe5" -uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" -version = "0.1.5" - - [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" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[deps.UnsafeAtomics]] -git-tree-sha1 = "b13c4edda90890e5b04ba24e20a310fbe6f249ff" -uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" -version = "0.3.0" -weakdeps = ["LLVM"] - - [deps.UnsafeAtomics.extensions] - UnsafeAtomicsLLVM = ["LLVM"] - -[[deps.VectorizationBase]] -deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "4ab62a49f1d8d9548a1c8d1a75e5f55cf196f64e" -uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.71" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "b8b243e47228b4a3877f1dd6aee0c5d56db7fcf4" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.6+1" - -[[deps.XZ_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" -uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.8.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.2.13+1" - -[[deps.Zstd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.7+1" - -[[deps.demumble_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6498e3581023f8e530f34760d18f75a69e3a4ea8" -uuid = "1e29f10c-031c-5a83-9565-69cddfc27673" -version = "1.3.0+0" - -[[deps.libaec_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f5733a5a9047722470b95a81e1b172383971105c" -uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.1.3+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.11.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.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" - -[[deps.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2022.0.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" From a1ede1f3b5622adcb86d28f3836fce9f67d2892e Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 22 Jul 2025 10:53:05 +0200 Subject: [PATCH 152/203] revert --- .../InterfaceComputations/atmosphere_ocean_fluxes.jl | 6 +----- .../InterfaceComputations/component_interfaces.jl | 7 ++----- .../similarity_theory_turbulent_fluxes.jl | 9 ++------- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl index 96f115028..319ba5366 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl @@ -33,7 +33,6 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) flux_formulation = coupled_model.interfaces.atmosphere_ocean_interface.flux_formulation interface_fluxes = coupled_model.interfaces.atmosphere_ocean_interface.fluxes interface_temperature = coupled_model.interfaces.atmosphere_ocean_interface.temperature - interface_humidity = coupled_model.interfaces.atmosphere_ocean_interface.humidity interface_properties = coupled_model.interfaces.atmosphere_ocean_interface.properties ocean_properties = coupled_model.interfaces.ocean_properties atmosphere_properties = (thermodynamics_parameters = thermodynamics_parameters(atmosphere), @@ -46,7 +45,6 @@ function compute_atmosphere_ocean_fluxes!(coupled_model) _compute_atmosphere_ocean_interface_state!, interface_fluxes, interface_temperature, - interface_humidity, grid, clock, flux_formulation, @@ -62,7 +60,6 @@ end """ Compute turbulent fluxes between an atmosphere and a interface state using similarity theory """ @kernel function _compute_atmosphere_ocean_interface_state!(interface_fluxes, interface_temperature, - interface_humidity, grid, clock, turbulent_flux_formulation, @@ -167,6 +164,7 @@ end cₚ = AtmosphericThermodynamics.cp_m(ℂₐ, 𝒬ₐ) # moist heat capacity ℒv = AtmosphericThermodynamics.latent_heat_vapor(ℂₐ, 𝒬ₐ) + # Store fluxes Qv = interface_fluxes.latent_heat Qc = interface_fluxes.sensible_heat @@ -174,7 +172,6 @@ end ρτx = interface_fluxes.x_momentum ρτy = interface_fluxes.y_momentum Ts = interface_temperature - qs = interface_humidity @inbounds begin # +0: cooling, -0: heating @@ -184,7 +181,6 @@ end ρτx[i, j, 1] = + ρₐ * τx ρτy[i, j, 1] = + ρₐ * τy Ts[i, j, 1] = convert_from_kelvin(ocean_properties.temperature_units, Ψₛ.T) - qs[i, j, 1] = Ψₛ.q interface_fluxes.friction_velocity[i, j, 1] = u★ interface_fluxes.temperature_scale[i, j, 1] = θ★ diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index 23e178f89..d32f21093 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -39,7 +39,6 @@ mutable struct AtmosphereInterface{J, F, ST, P} fluxes :: J flux_formulation :: F temperature :: ST - humidity :: ST properties :: P end @@ -214,9 +213,8 @@ function atmosphere_ocean_interface(atmos, velocity_formulation) interface_temperature = Field{Center, Center, Nothing}(ocean.model.grid) - interface_humidity = Field{Center, Center, Nothing}(ocean.model.grid) - return AtmosphereInterface(ao_fluxes, ao_flux_formulation, interface_temperature, interface_humidity, ao_properties) + return AtmosphereInterface(ao_fluxes, ao_flux_formulation, interface_temperature, ao_properties) end atmosphere_sea_ice_interface(atmos, sea_ice, args...) = nothing @@ -252,9 +250,8 @@ function atmosphere_sea_ice_interface(atmos, velocity_formulation) interface_temperature = sea_ice.model.ice_thermodynamics.top_surface_temperature - interface_humidity = Field{Center, Center, Nothing}(sea_ice.model.grid) - return AtmosphereInterface(fluxes, ai_flux_formulation, interface_temperature, interface_humidity, properties) + return AtmosphereInterface(fluxes, ai_flux_formulation, interface_temperature, properties) end sea_ice_ocean_interface(sea_ice, ocean) = nothing diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index 537caae86..401e49fb1 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -24,7 +24,6 @@ struct SimilarityTheoryFluxes{FT, UF, R, B, S} von_karman_constant :: FT # parameter turbulent_prandtl_number :: FT # parameter gustiness_parameter :: FT # bulk velocity parameter - minimum_velocity_scale :: FT # minimum velocity scale stability_functions :: UF # functions for turbulent fluxes roughness_lengths :: R # parameterization for turbulent fluxes similarity_form :: B # similarity profile relating atmosphere to interface state @@ -35,7 +34,6 @@ Adapt.adapt_structure(to, fluxes::SimilarityTheoryFluxes) = SimilarityTheoryFluxes(adapt(to, fluxes.von_karman_constant), adapt(to, fluxes.turbulent_prandtl_number), adapt(to, fluxes.gustiness_parameter), - adapt(to, fluxes.minimum_velocity_scale), adapt(to, fluxes.stability_functions), adapt(to, fluxes.roughness_lengths), adapt(to, fluxes.similarity_form), @@ -89,12 +87,11 @@ Keyword Arguments function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; von_karman_constant = 0.4, turbulent_prandtl_number = 1, - gustiness_parameter = 2, + gustiness_parameter = 1, stability_functions = atmosphere_ocean_stability_functions(FT), momentum_roughness_length = MomentumRoughnessLength(FT), temperature_roughness_length = ScalarRoughnessLength(FT), water_vapor_roughness_length = ScalarRoughnessLength(FT), - minimum_velocity_scale = 0.5, similarity_form = LogarithmicSimilarityProfile(), solver_stop_criteria = nothing, solver_tolerance = 1e-8, @@ -117,7 +114,6 @@ function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; return SimilarityTheoryFluxes(convert(FT, von_karman_constant), convert(FT, turbulent_prandtl_number), convert(FT, gustiness_parameter), - convert(FT, minimum_velocity_scale), stability_functions, roughness_lengths, similarity_form, @@ -207,8 +203,7 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, approximate_interface_state) U = sqrt(Δu^2 + Δv^2 + Uᴳ^2) - U = max(U, flux_formulation.minimum_velocity_scale) - + # Compute roughness length scales ℓu₀ = roughness_length(ℓu, u★, U, 𝒬ₛ, ℂₐ) ℓq₀ = roughness_length(ℓq, ℓu₀, u★, U, 𝒬ₛ, ℂₐ) From 4015bf4e82e59972f038050a9d6f45bdb2a71675 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 22 Jul 2025 11:00:51 +0200 Subject: [PATCH 153/203] token --- .github/workflows/ci.yml | 2 +- src/DataWrangling/DataWrangling.jl | 6 +++--- src/DataWrangling/ECCO/ECCO.jl | 14 +++++++------- src/DataWrangling/ECCO/README.md | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32806c868..a74dbd74d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: env: TEST_GROUP: "downloading" ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} # To download ECCO data from the podaac website - ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} # To download ECCO data from the podaac website + ECCO_TOKEN: ${{ secrets.ECCO_PASSWORD }} # To download ECCO data from the podaac website - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v5 with: diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index 4c6415013..d44f1b73b 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -148,12 +148,12 @@ Arguments !!! info "Credential setup requirements for ECCO datasets" For ECCO datasets, the data download requires a username and password to be provided in - the `ECCO_USERNAME` and `ECCO_PASSWORD` environment variables respectively. This can be + the `ECCO_USERNAME` and `ECCO_TOKEN` environment variables respectively. This can be done by exporting the environment variables in the shell before running the script, or by launching julia with ``` - ECCO_USERNAME=myusername ECCO_PASSWORD=mypassword julia + ECCO_USERNAME=myusername ECCO_TOKEN=mytoken julia ``` or by invoking @@ -161,7 +161,7 @@ Arguments ```julia julia> ENV["ECCO_USERNAME"] = "myusername" - julia> ENV["ECCO_PASSWORD"] = "mypassword" + julia> ENV["ECCO_TOKEN"] = "mytoken" ``` within julia. diff --git a/src/DataWrangling/ECCO/ECCO.jl b/src/DataWrangling/ECCO/ECCO.jl index 9bb40b38e..08cb1b0f5 100644 --- a/src/DataWrangling/ECCO/ECCO.jl +++ b/src/DataWrangling/ECCO/ECCO.jl @@ -257,7 +257,7 @@ end function download_dataset(metadata::ECCOMetadata) username = get(ENV, "ECCO_USERNAME", nothing) - password = get(ENV, "ECCO_PASSWORD", nothing) + ecco_tkn = get(ENV, "ECCO_TOKEN", nothing) dir = metadata.dir # Create a temporary directory to store the .netrc file @@ -265,7 +265,7 @@ function download_dataset(metadata::ECCOMetadata) @root mktempdir(dir) do tmp # Write down the username and password in a .netrc file - downloader = netrc_downloader(username, password, "ecco.jpl.nasa.gov", tmp) + downloader = netrc_downloader(username, ecco_tkn, "ecco.jpl.nasa.gov", tmp) ntasks = Threads.nthreads() asyncmap(metadata; ntasks) do metadatum # Distribute the download among tasks @@ -276,14 +276,14 @@ function download_dataset(metadata::ECCOMetadata) if !isfile(filepath) instructions_msg = "\n See ClimaOcean.jl/src/DataWrangling/ECCO/README.md for instructions." if isnothing(username) - msg = "Could not find the ECCO_PASSWORD environment variable. \ + msg = "Could not find the ECCO_TOKEN environment variable. \ See ClimaOcean.jl/src/DataWrangling/ECCO/README.md for instructions on obtaining \ - and setting your ECCO_USERNAME and ECCO_PASSWORD." * instructions_msg + and setting your ECCO_USERNAME and ECCO_TOKEN." * instructions_msg throw(ArgumentError(msg)) - elseif isnothing(password) - msg = "Could not find the ECCO_PASSWORD environment variable. \ + elseif isnothing(ecco_tkn) + msg = "Could not find the ECCO_TOKEN environment variable. \ See ClimaOcean.jl/src/DataWrangling/ECCO/README.md for instructions on obtaining \ - and setting your ECCO_USERNAME and ECCO_PASSWORD." * instructions_msg + and setting your ECCO_USERNAME and ECCO_TOKEN." * instructions_msg throw(ArgumentError(msg)) end @info "Downloading ECCO data: $(metadatum.name) in $(metadatum.dir)..." diff --git a/src/DataWrangling/ECCO/README.md b/src/DataWrangling/ECCO/README.md index f2adc136c..a2a2c8242 100644 --- a/src/DataWrangling/ECCO/README.md +++ b/src/DataWrangling/ECCO/README.md @@ -1,4 +1,4 @@ -# Setting `ECCO_USERNAME` and `ECCO_PASSWORD` environment variables for downloading ECCO datasets +# Setting `ECCO_USERNAME` and `ECCO_TOKEN` environment variables for downloading ECCO datasets The first step is to find the username and password for your "programmatic API" credentials on NASA's Earthdrive. For this you have to either login or make an account via the "EARTHDATA login": @@ -13,19 +13,19 @@ This should produce a screen similar to the following: ![image](https://github.com/user-attachments/assets/490d9098-aece-4e9c-82d7-3ec86e833347) -showing your Programmatic API credentials -- except in place of the black boxes that say `your_username` and `cRaZYpASSwORD`, +showing your Programmatic API credentials -- except in place of the black boxes that say `your_username` and `cRaZtoKEn`, you should see _your_ username and password. -Copy the content of `Username:` to the environment variable `ECCO_USERNAME` and the content of `Password` to `ECCO_PASSWORD`, +Copy the content of `Username:` to the environment variable `ECCO_USERNAME` and the content of `Password` to `ECCO_TOKEN`, either in a file: ```bash export ECCO_USERNAME=your_username -export ECCO_PASSWORD=cRaZYpASSwORD +export ECCO_TOKEN=cRaZYpASSwORD ``` or within Julia by writing ```julia ENV["ECCO_USERNAME"] = "your_username" -ENV["ECCO_PASSWORD"] = "cRaZYpASSwORD" +ENV["ECCO_TOKEN"] = "cRaZtoKEn" ``` From 970ffeb14fcecfce6191cdab321eab9bafc6fed5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 22 Jul 2025 11:01:47 +0200 Subject: [PATCH 154/203] Revert "token" This reverts commit 4015bf4e82e59972f038050a9d6f45bdb2a71675. --- .github/workflows/ci.yml | 2 +- src/DataWrangling/DataWrangling.jl | 6 +++--- src/DataWrangling/ECCO/ECCO.jl | 14 +++++++------- src/DataWrangling/ECCO/README.md | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a74dbd74d..32806c868 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: env: TEST_GROUP: "downloading" ECCO_USERNAME: ${{ secrets.ECCO_USERNAME }} # To download ECCO data from the podaac website - ECCO_TOKEN: ${{ secrets.ECCO_PASSWORD }} # To download ECCO data from the podaac website + ECCO_PASSWORD: ${{ secrets.ECCO_PASSWORD }} # To download ECCO data from the podaac website - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v5 with: diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index d44f1b73b..4c6415013 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -148,12 +148,12 @@ Arguments !!! info "Credential setup requirements for ECCO datasets" For ECCO datasets, the data download requires a username and password to be provided in - the `ECCO_USERNAME` and `ECCO_TOKEN` environment variables respectively. This can be + the `ECCO_USERNAME` and `ECCO_PASSWORD` environment variables respectively. This can be done by exporting the environment variables in the shell before running the script, or by launching julia with ``` - ECCO_USERNAME=myusername ECCO_TOKEN=mytoken julia + ECCO_USERNAME=myusername ECCO_PASSWORD=mypassword julia ``` or by invoking @@ -161,7 +161,7 @@ Arguments ```julia julia> ENV["ECCO_USERNAME"] = "myusername" - julia> ENV["ECCO_TOKEN"] = "mytoken" + julia> ENV["ECCO_PASSWORD"] = "mypassword" ``` within julia. diff --git a/src/DataWrangling/ECCO/ECCO.jl b/src/DataWrangling/ECCO/ECCO.jl index 08cb1b0f5..9bb40b38e 100644 --- a/src/DataWrangling/ECCO/ECCO.jl +++ b/src/DataWrangling/ECCO/ECCO.jl @@ -257,7 +257,7 @@ end function download_dataset(metadata::ECCOMetadata) username = get(ENV, "ECCO_USERNAME", nothing) - ecco_tkn = get(ENV, "ECCO_TOKEN", nothing) + password = get(ENV, "ECCO_PASSWORD", nothing) dir = metadata.dir # Create a temporary directory to store the .netrc file @@ -265,7 +265,7 @@ function download_dataset(metadata::ECCOMetadata) @root mktempdir(dir) do tmp # Write down the username and password in a .netrc file - downloader = netrc_downloader(username, ecco_tkn, "ecco.jpl.nasa.gov", tmp) + downloader = netrc_downloader(username, password, "ecco.jpl.nasa.gov", tmp) ntasks = Threads.nthreads() asyncmap(metadata; ntasks) do metadatum # Distribute the download among tasks @@ -276,14 +276,14 @@ function download_dataset(metadata::ECCOMetadata) if !isfile(filepath) instructions_msg = "\n See ClimaOcean.jl/src/DataWrangling/ECCO/README.md for instructions." if isnothing(username) - msg = "Could not find the ECCO_TOKEN environment variable. \ + msg = "Could not find the ECCO_PASSWORD environment variable. \ See ClimaOcean.jl/src/DataWrangling/ECCO/README.md for instructions on obtaining \ - and setting your ECCO_USERNAME and ECCO_TOKEN." * instructions_msg + and setting your ECCO_USERNAME and ECCO_PASSWORD." * instructions_msg throw(ArgumentError(msg)) - elseif isnothing(ecco_tkn) - msg = "Could not find the ECCO_TOKEN environment variable. \ + elseif isnothing(password) + msg = "Could not find the ECCO_PASSWORD environment variable. \ See ClimaOcean.jl/src/DataWrangling/ECCO/README.md for instructions on obtaining \ - and setting your ECCO_USERNAME and ECCO_TOKEN." * instructions_msg + and setting your ECCO_USERNAME and ECCO_PASSWORD." * instructions_msg throw(ArgumentError(msg)) end @info "Downloading ECCO data: $(metadatum.name) in $(metadatum.dir)..." diff --git a/src/DataWrangling/ECCO/README.md b/src/DataWrangling/ECCO/README.md index a2a2c8242..f2adc136c 100644 --- a/src/DataWrangling/ECCO/README.md +++ b/src/DataWrangling/ECCO/README.md @@ -1,4 +1,4 @@ -# Setting `ECCO_USERNAME` and `ECCO_TOKEN` environment variables for downloading ECCO datasets +# Setting `ECCO_USERNAME` and `ECCO_PASSWORD` environment variables for downloading ECCO datasets The first step is to find the username and password for your "programmatic API" credentials on NASA's Earthdrive. For this you have to either login or make an account via the "EARTHDATA login": @@ -13,19 +13,19 @@ This should produce a screen similar to the following: ![image](https://github.com/user-attachments/assets/490d9098-aece-4e9c-82d7-3ec86e833347) -showing your Programmatic API credentials -- except in place of the black boxes that say `your_username` and `cRaZtoKEn`, +showing your Programmatic API credentials -- except in place of the black boxes that say `your_username` and `cRaZYpASSwORD`, you should see _your_ username and password. -Copy the content of `Username:` to the environment variable `ECCO_USERNAME` and the content of `Password` to `ECCO_TOKEN`, +Copy the content of `Username:` to the environment variable `ECCO_USERNAME` and the content of `Password` to `ECCO_PASSWORD`, either in a file: ```bash export ECCO_USERNAME=your_username -export ECCO_TOKEN=cRaZYpASSwORD +export ECCO_PASSWORD=cRaZYpASSwORD ``` or within Julia by writing ```julia ENV["ECCO_USERNAME"] = "your_username" -ENV["ECCO_TOKEN"] = "cRaZtoKEn" +ENV["ECCO_PASSWORD"] = "cRaZYpASSwORD" ``` From e6ff0d4d7e2c792abdd33c4972900849050843b2 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 22 Jul 2025 05:35:22 -0400 Subject: [PATCH 155/203] changed JRA55 --- src/DataWrangling/JRA55/JRA55.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DataWrangling/JRA55/JRA55.jl b/src/DataWrangling/JRA55/JRA55.jl index 34dc0097d..a3e45fec7 100644 --- a/src/DataWrangling/JRA55/JRA55.jl +++ b/src/DataWrangling/JRA55/JRA55.jl @@ -5,7 +5,6 @@ export JRA55FieldTimeSeries, JRA55PrescribedAtmosphere, RepeatYearJRA55, MultiYe using Oceananigans using Oceananigans.Units -using Oceananigans.Architectures: arch_array using Oceananigans.DistributedComputations using Oceananigans.DistributedComputations: child_architecture using Oceananigans.BoundaryConditions: fill_halo_regions! From ef45d0cc22bd6f309da9ec4baf9f2d57a5364289 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Tue, 22 Jul 2025 05:36:09 -0400 Subject: [PATCH 156/203] added Project --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index f31d23962..38662c9cb 100644 --- a/Project.toml +++ b/Project.toml @@ -55,7 +55,7 @@ JLD2 = "0.4, 0.5" KernelAbstractions = "0.9" MPI = "0.20" NCDatasets = "0.12, 0.13, 0.14" -Oceananigans = "0.96" +Oceananigans = "0.97.1" OffsetArrays = "1.14" PrecompileTools = "1" PythonCall = "0.9" From ea3ee12e7d95c7688a3d2f1a2c6cad881ec6ea8c Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 22 Jul 2025 14:14:27 +0200 Subject: [PATCH 157/203] bugfix --- .../time_step_ocean_sea_ice_model.jl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index 9222a147b..bd0e39e0c 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -54,18 +54,19 @@ function update_state!(coupled_model::OceanSeaIceModel, callbacks=[]; compute_te end function (wizard::TimeStepWizard)(simulation::Simulation{<:OceanSeaIceModel}) - ocean_Δt = wizard(simulation.ocean) + model = simulation.model + ocean_Δt = wizard(model.ocean) - sea_ice_Δt = if isnothing(simulation.sea_ice) + sea_ice_Δt = if isnothing(model.sea_ice) Inf else - wizard(simulation.sea_ice) + wizard(model.sea_ice) end - atmosphere_Δt = if isnothing(simulation.atmosphere) + atmosphere_Δt = if isnothing(model.atmosphere) Inf else - wizard(simulation.atmosphere) + wizard(model.atmosphere) end return min(ocean_Δt, sea_ice_Δt, atmosphere_Δt) From add5526324c7c5db118c831009ac648abe2324f5 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 22 Jul 2025 16:47:21 +0200 Subject: [PATCH 158/203] this should fix it --- src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index bd0e39e0c..331b91fcd 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -69,6 +69,10 @@ function (wizard::TimeStepWizard)(simulation::Simulation{<:OceanSeaIceModel}) wizard(model.atmosphere) end - return min(ocean_Δt, sea_ice_Δt, atmosphere_Δt) + Δt = min(ocean_Δt, sea_ice_Δt, atmosphere_Δt) + + simulation.Δt = Δt + + return nothing end From 92fda283226a329610239ad12a1b62f58ce3f911 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Mon, 28 Jul 2025 04:43:47 -0400 Subject: [PATCH 159/203] change sea ice --- src/SeaIceSimulations.jl | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index 22dddc0bd..7f5faa593 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -21,7 +21,7 @@ using ClimaSeaIce.Rheologies using ClimaSeaIce.SeaIceDynamics: SplitExplicitSolver, SemiImplicitStress, SeaIceMomentumEquation, StressBalanceFreeDrift using ClimaSeaIce.Rheologies: IceStrength, ElastoViscoPlasticRheology -using ClimaOcean.OceanSimulations: Default +using ClimaOcean.OceanSimulations: Default, u_immersed_bottom_drag, v_immersed_bottom_drag function sea_ice_simulation(grid, ocean=nothing; Δt = 5minutes, @@ -63,6 +63,12 @@ function sea_ice_simulation(grid, ocean=nothing; bottom_heat_flux = Field{Center, Center, Nothing}(grid) top_heat_flux = Field{Center, Center, Nothing}(grid) + immersed_u_bc = FluxBoundaryCondition(u_immersed_bottom_drag, discrete_form=true, parameters=1e-1) + immersed_v_bc = FluxBoundaryCondition(v_immersed_bottom_drag, discrete_form=true, parameters=1e-1) + + u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing); immersed = immersed_u_bc) + v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing); immersed = immersed_v_bc) + # Build the sea ice model sea_ice_model = SeaIceModel(grid; ice_salinity, @@ -82,12 +88,17 @@ function sea_ice_simulation(grid, ocean=nothing; return sea_ice end +default_solver(::Nothing) = SplitExplicitSolver(120) +default_solver(ocean::Simulation) = default_solver(ocean.model.timestepper) +default_solver(::Oceananigans.TimeSteppers.QuasiAdamsBashforth2TimeStepper) = SplitExplicitSolver(120) +default_solver(::Oceananigans.TimeSteppers.SplitRungeKutta3TimeStepper) = SplitExplicitSolver(360) + function sea_ice_dynamics(grid, ocean=nothing; - sea_ice_ocean_drag_coefficient = 5.5e-3, + sea_ice_ocean_drag_coefficient = 2.5e-3, rheology = ElastoViscoPlasticRheology(), coriolis = nothing, free_drift = nothing, - solver = SplitExplicitSolver(120)) + solver = default_solver(ocean)) if isnothing(ocean) SSU = Oceananigans.Fields.ZeroField() From 469bcb117e415e9883982313f91d958fc60da810 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 30 Jul 2025 15:09:44 +0200 Subject: [PATCH 160/203] consolidate sea ice temperature --- .../InterfaceComputations/atmosphere_sea_ice_fluxes.jl | 4 +++- .../InterfaceComputations/interface_states.jl | 10 +++++++--- src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl index d12ae69b3..9f0b3de73 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl @@ -14,6 +14,7 @@ function compute_atmosphere_sea_ice_fluxes!(coupled_model) v = ZeroField(), h = sea_ice.model.ice_thickness, ℵ = sea_ice.model.ice_concentration, + hc = sea_ice.model.ice_consolidation_thickness, Tₒ = ocean.model.tracers.T, Sₒ = ocean.model.tracers.S) @@ -97,6 +98,7 @@ end uᵢ = zero(FT) # ℑxᶜᵃᵃ(i, j, 1, grid, interior_state.u) vᵢ = zero(FT) # ℑyᵃᶜᵃ(i, j, 1, grid, interior_state.v) hᵢ = interior_state.h[i, j, 1] + hc = interior_state.hc[i, j, 1] ℵᵢ = interior_state.ℵ[i, j, 1] Tₛ = interface_temperature[i, j, 1] Tₛ = convert_to_kelvin(sea_ice_properties.temperature_units, Tₛ) @@ -117,7 +119,7 @@ end h_bℓ = atmosphere_state.h_bℓ) downwelling_radiation = (; Qs, Qℓ) - local_interior_state = (u=uᵢ, v=vᵢ, T=Tᵢ, S=Sᵢ, h=hᵢ) + local_interior_state = (u=uᵢ, v=vᵢ, T=Tᵢ, S=Sᵢ, h=hᵢ, hc=hc) # Estimate initial interface state u★ = convert(FT, 1e-4) diff --git a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl index 05e172bab..56954d6d9 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl @@ -269,9 +269,10 @@ end # where Ωc (the sensible heat transfer coefficient) is given by Ωc = Qc / (Tₐ - Tˢ) # ⟹ Tₛ = (Tᵢ * k - (Qv + Qu + Qd + Ωc * Tₐ) * h / (k - Ωc * h) @inline function flux_balance_temperature(st::SkinTemperature{<:ClimaSeaIce.ConductiveFlux}, Ψₛ, ℙₛ, Qc, Qv, Qu, Qd, Ψᵢ, ℙᵢ, Ψₐ, ℙₐ) - F = st.internal_flux - k = F.conductivity - h = Ψᵢ.h + F = st.internal_flux + k = F.conductivity + h = Ψᵢ.h + hc = Ψᵢ.hc # Critical thickness for ice consolidation # Bottom temperature at the melting temperature Tᵢ = ClimaSeaIce.SeaIceThermodynamics.melting_temperature(ℙᵢ.liquidus, Ψᵢ.S) @@ -303,6 +304,9 @@ end Tₘ = convert_to_kelvin(ℙᵢ.temperature_units, Tₘ) Tₛ⁺ = min(Tₛ⁺, Tₘ) + # If the ice is not consolidated, use the bottom temperature + Tₛ⁺ = ifelse(h ≥ hc, Tₛ⁺, Tᵢ) + return Tₛ⁺ end diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index 331b91fcd..937d11654 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -21,10 +21,10 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_ # TODO after ice time-step: # - Adjust ocean heat flux if the ice completely melts? - time_step!(ocean, Δt) + !isnothing(ocean) && time_step!(ocean, Δt) # Time step the atmosphere - time_step!(atmosphere, Δt) + !isnothing(atmosphere) && time_step!(atmosphere, Δt) # TODO: # - Store fractional ice-free / ice-covered _time_ for more From 736ac4cd1c50fe323704385d7a0813c648feefd3 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Wed, 30 Jul 2025 10:46:38 -0400 Subject: [PATCH 161/203] adding the manifest --- Manifest.toml | 1549 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1549 insertions(+) create mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 000000000..4e18691a1 --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,1549 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.9" +manifest_format = "2.0" +project_hash = "9c3a7f83d8ac3461a9bebf2f68c603f45bfa10bf" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + + [deps.AbstractFFTs.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] +git-tree-sha1 = "3b86719127f50670efe356bc11073d84b4ed7a5d" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.42" + + [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 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.3.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "f87e559f87a45bece9c9ed97458d3afe98b1ebb9" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.1.0" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra"] +git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.19.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = "CUDSS" + ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + 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" + +[[deps.Atomix]] +deps = ["UnsafeAtomics"] +git-tree-sha1 = "b5bb4dc6248fde467be2a863eb8452993e74d402" +uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" +version = "1.1.1" + + [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.BFloat16s]] +deps = ["LinearAlgebra", "Printf", "Random"] +git-tree-sha1 = "3b642331600250f592719140c60cf12372b82d66" +uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" +version = "0.5.1" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BitTwiddlingConvenienceFunctions]] +deps = ["Static"] +git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" +uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" +version = "0.1.6" + +[[deps.Blosc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "535c80f1c0847a4c967ea945fca21becc9de1522" +uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" +version = "1.21.7+0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CFTime]] +deps = ["Dates", "Printf"] +git-tree-sha1 = "9b37e9e51aeea9763eea65b9b3aa1728fca94ffc" +uuid = "179af706-886a-5703-950a-314cd64e0468" +version = "0.2.1" + +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] +git-tree-sha1 = "5a97e67919535d6841172016c9530fd69494e5ec" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.6" + +[[deps.CUDA]] +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] +git-tree-sha1 = "b8ae59258f3d96ce75a00f9229e719356eb929d6" +uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" +version = "5.8.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_Driver_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "18afa851ed10552e6df25dfaa7ef450104ae73d4" +uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" +version = "0.13.1+0" + +[[deps.CUDA_Runtime_Discovery]] +deps = ["Libdl"] +git-tree-sha1 = "33576c7c1b2500f8e7e6baa082e04563203b3a45" +uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" +version = "0.3.5" + +[[deps.CUDA_Runtime_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "b5c173a64f9f4224a82fdc26fda8614cb2ecfa27" +uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" +version = "0.17.1+0" + +[[deps.ClimaSeaIce]] +deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "a03e0b78e613effa713161eaf46985a7f8421510" +repo-rev = "ss/no-heat-flux-when-unconsolidated" +repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" +uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" +version = "0.3.4" + +[[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" + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + + [deps.ColorTypes.weakdeps] + StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" + +[[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", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "a4f9a314202585fcdce4f1a3c4b86ce988ce76b1" +uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" +version = "0.3.9" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[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 = "3a3dfb30697e96a440e4149c8c51bf32f818c0f3" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.17.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.1+0" + +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.ConstructionBase]] +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.6.0" + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" + ConstructionBaseStaticArraysExt = "StaticArrays" + + [deps.ConstructionBase.weakdeps] + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.CpuId]] +deps = ["Markdown"] +git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" +uuid = "adafc99b-e345-5852-983c-f28acb93d879" +version = "0.3.1" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.CubedSphere]] +deps = ["TaylorSeries"] +git-tree-sha1 = "afe9e8c11bf816a6fee878ddfc661e0bd138b747" +uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" +version = "0.3.2" + +[[deps.CubicSplines]] +deps = ["Random", "Test"] +git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" +uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" +version = "0.2.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataDeps]] +deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] +git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" +uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" +version = "0.7.13" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "fb61b4812c49343d7ef0b533ba982c46021938a6" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.7.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DiskArrays]] +deps = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] +git-tree-sha1 = "16d93ff95ecc421463eaefd694e6746bb1c0919e" +uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" +version = "0.4.14" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.12" + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + + [deps.Distances.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.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 = "4a8c0a9eebf807ac42f0f6de758e60a20be25ffb" +uuid = "21656369-7473-754a-2065-74616d696c43" +version = "1.1.3" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "797762812ed063b9b94f6cc7742bc8883bb5e69e" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.9.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.11+0" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "b66970a70db13f45b7e57fbda1736e1cf72174ea" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.17.0" +weakdeps = ["HTTP"] + + [deps.FileIO.extensions] + HTTPExt = "HTTP" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.0.1" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GPUArrays]] +deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "Statistics"] +git-tree-sha1 = "be941842a40b6daac98496994ea69054ba4c5144" +uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" +version = "11.2.3" + +[[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 = "eb1e212e12cc058fa16712082d44be499d23638c" +uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" +version = "1.6.1" + +[[deps.GPUToolbox]] +git-tree-sha1 = "15d8b0f5a6dca9bf8c02eeaf6687660dafa638d0" +uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" +version = "0.2.0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] +git-tree-sha1 = "e94f84da9af7ce9c6be049e9067e511e17ff89ec" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.14.6+0" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "ed5e9c58612c4e081aecdb6e1a479e18462e041e" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.17" + +[[deps.HashArrayMappedTries]] +git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" +uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" +version = "0.2.0" + +[[deps.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] +git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.17" + +[[deps.Hwloc_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" +uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" +version = "2.12.1+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 = "cffa21df12f00ca1a365eb8ed107614b40e8c6da" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.4.6" + +[[deps.Inflate]] +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.InlineStrings]] +git-tree-sha1 = "8594fac023c5ce1ef78260f24d1ad18b4327b420" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.4" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + ParsersExt = "Parsers" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "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" + +[[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 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.4" + +[[deps.IterativeSolvers]] +deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] +git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" +uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" +version = "0.9.4" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] +git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.5.15" +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.JuliaNVTXCallbacks_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" +uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" +version = "0.2.1+0" + +[[deps.KernelAbstractions]] +deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] +git-tree-sha1 = "83c617e9e9b02306a7acab79e05ec10253db7c87" +uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" +version = "0.9.38" + + [deps.KernelAbstractions.extensions] + EnzymeExt = "EnzymeCore" + LinearAlgebraExt = "LinearAlgebra" + SparseArraysExt = "SparseArrays" + + [deps.KernelAbstractions.weakdeps] + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.Krylov]] +deps = ["LinearAlgebra", "Printf", "SparseArrays"] +git-tree-sha1 = "b94257a1a8737099ca40bc7271a8b374033473ed" +uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" +version = "0.10.1" + +[[deps.KrylovPreconditioners]] +deps = ["Adapt", "KernelAbstractions", "LightGraphs", "LinearAlgebra", "Metis", "SparseArrays"] +git-tree-sha1 = "52d302d5e950e242f037316b6dd6e1e080afea09" +uuid = "45d422c2-293f-44ce-8315-2cb988662dec" +version = "0.3.4" + + [deps.KrylovPreconditioners.extensions] + KrylovPreconditionersAMDGPUExt = "AMDGPU" + KrylovPreconditionersCUDAExt = "CUDA" + KrylovPreconditionersOneAPIExt = "oneAPI" + + [deps.KrylovPreconditioners.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" + +[[deps.LLVM]] +deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] +git-tree-sha1 = "9c7c721cfd800d87d48c745d8bfb65144f0a91df" +uuid = "929cbde3-209d-540e-8aea-75f648917ca0" +version = "9.4.2" +weakdeps = ["BFloat16s"] + + [deps.LLVM.extensions] + BFloat16sExt = "BFloat16s" + +[[deps.LLVMExtra_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "2ea068aac1e7f0337d381b0eae3110581e3f3216" +uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" +version = "0.0.37+2" + +[[deps.LLVMLoopInfo]] +git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" +uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" +version = "1.0.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" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.LibTracyClient_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d2bc4e1034b2d43076b50f0e34ea094c2cb0a717" +uuid = "ad6e5548-8b26-5c9f-8ef3-ef0ad883f3a5" +version = "0.9.1+6" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.LightGraphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "432428df5f360964040ed60418dd5601ecd240b6" +uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" +version = "1.3.5" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[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" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f02b56007b064fbfddb4c9cd60161b6dd0f40df3" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.1.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 = "e5afce7eaf5b5ca0d444bcb4dc4fd78c54cbbac0" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.172" + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + SpecialFunctionsExt = "SpecialFunctions" + + [deps.LoopVectorization.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.Lz4_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "191686b1ac1ea9c89fc52e996ad15d1d241d1e33" +uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" +version = "1.10.1+0" + +[[deps.METIS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2eefa8baa858871ae7770c98c3c2a7e46daba5b4" +uuid = "d00139f3-1899-568f-a2f0-47f597d42d70" +version = "5.1.3+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", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] +git-tree-sha1 = "a61ecf714d71064b766d481ef43c094d4c6e3c52" +uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" +version = "0.20.23" + + [deps.MPI.extensions] + AMDGPUExt = "AMDGPU" + CUDAExt = "CUDA" + + [deps.MPI.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.MPICH_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" +uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" +version = "4.3.1+0" + +[[deps.MPIPreferences]] +deps = ["Libdl", "Preferences"] +git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" +uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +version = "0.1.11" + +[[deps.MPItrampoline_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] +git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" +uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" +version = "5.5.4+0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.Metis]] +deps = ["CEnum", "LinearAlgebra", "METIS_jll", "SparseArrays"] +git-tree-sha1 = "54aca4fd53d39dcd2c3f1bef367b6921e8178628" +uuid = "2679e427-3c69-5b7f-982b-ece356f1e94b" +version = "1.5.0" + + [deps.Metis.extensions] + MetisGraphs = "Graphs" + MetisLightGraphs = "LightGraphs" + MetisSimpleWeightedGraphs = ["SimpleWeightedGraphs", "Graphs"] + + [deps.Metis.weakdeps] + Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" + LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" + SimpleWeightedGraphs = "47aef6b3-ad0c-573a-a1e2-d07658019622" + +[[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" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.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 = "be1095e2b767c19529409ec670bcfb01b825d717" +uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" +version = "0.14.8" + +[[deps.NVTX]] +deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] +git-tree-sha1 = "6b573a3e66decc7fc747afd1edbf083ff78c813a" +uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" +version = "1.0.1" + +[[deps.NVTX_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "cd475b587ff77910789a18e68da789fc446a2a05" +uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" +version = "3.2.1+0" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NetCDF_jll]] +deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML", "XML2_jll", "Zlib_jll", "Zstd_jll", "libaec_jll", "libzip_jll"] +git-tree-sha1 = "d574803b6055116af212434460adf654ce98e345" +uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" +version = "401.900.300+0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Oceananigans]] +deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "b0ea5f938cb437ab7f194c4d0785588f941af765" +repo-rev = "ss/omip-branch" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" +version = "0.97.5" + + [deps.Oceananigans.extensions] + OceananigansAMDGPUExt = "AMDGPU" + OceananigansCUDAExt = "CUDA" + OceananigansEnzymeExt = "Enzyme" + OceananigansMakieExt = ["MakieCore", "Makie"] + OceananigansMetalExt = "Metal" + OceananigansNCDatasetsExt = "NCDatasets" + OceananigansOneAPIExt = "oneAPI" + OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase"] + + [deps.Oceananigans.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" + Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" + 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.23+4" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+4" + +[[deps.OpenMPI_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] +git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" +uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" +version = "5.0.8+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "87510f7292a2b21aeff97912b0898f9553cc5c2c" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+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.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PolyesterWeave]] +deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] +git-tree-sha1 = "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 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.4.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.6" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Random123]] +deps = ["Random", "RandomNumbers"] +git-tree-sha1 = "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.ReactantCore]] +deps = ["ExpressionExplorer", "MacroTools"] +git-tree-sha1 = "120feaf6a97738e3a63902644a0afb3b69cc7b98" +uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" +version = "0.1.15" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.RootSolvers]] +deps = ["ForwardDiff", "Printf"] +git-tree-sha1 = "892b77767827af30868111d257930f567d5d78f8" +uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" +version = "0.4.4" + +[[deps.Roots]] +deps = ["Accessors", "CommonSolve", "Printf"] +git-tree-sha1 = "668e411c0616a70860249b4c96e5d35296631a1d" +uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" +version = "2.2.8" + + [deps.Roots.extensions] + RootsChainRulesCoreExt = "ChainRulesCore" + RootsForwardDiffExt = "ForwardDiff" + RootsIntervalRootFindingExt = "IntervalRootFinding" + RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" + + [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" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.1" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SIMDTypes]] +git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" +uuid = "94e857df-77ce-4151-89e5-788b33177be4" +version = "0.1.0" + +[[deps.SLEEFPirates]] +deps = ["IfElse", "Static", "VectorizationBase"] +git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.43" + +[[deps.ScopedValues]] +deps = ["HashArrayMappedTries", "Logging"] +git-tree-sha1 = "7f44eef6b1d284465fafc66baf4d9bdcc239a15b" +uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" +version = "1.4.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 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.8" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.5.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "be1cf4eb0ac528d96f5115b4ed80c26a8d8ae621" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.2" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] +git-tree-sha1 = "f737d444cb0ad07e61b3c1bef8eb91203c321eff" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.2.0" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] +git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.8.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "cbea8a6bd7bed51b1619658dec70035e07b8502f" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.14" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.4.1" + +[[deps.StructArrays]] +deps = ["ConstructionBase", "DataAPI", "Tables"] +git-tree-sha1 = "8ad2e38cbb812e29348719cc63580ec1dfeb9de4" +uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" +version = "0.7.1" +weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"] + + [deps.StructArrays.extensions] + StructArraysAdaptExt = "Adapt" + StructArraysGPUArraysCoreExt = ["GPUArraysCore", "KernelAbstractions"] + StructArraysLinearAlgebraExt = "LinearAlgebra" + StructArraysSparseArraysExt = "SparseArrays" + StructArraysStaticArraysExt = "StaticArrays" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.SurfaceFluxes]] +deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] +git-tree-sha1 = "aee530bde85cd41374273568cb649e72d82921e7" +uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" +version = "0.12.0" + + [deps.SurfaceFluxes.extensions] + CreateParametersExt = "ClimaParams" + + [deps.SurfaceFluxes.weakdeps] + ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "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 = "2c308aab2e14b399e4b8d6af7c486a241c8ca87a" +uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +version = "0.19.1" + + [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" + +[[deps.Thermodynamics]] +deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "bff801ad0a9bbb5c1bf38ffe89a83907a1b145cd" +uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" +version = "0.12.15" + + [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 = "91dbaee0f50faa4357f7e9fc69442c7b6364dfe5" +uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" +version = "0.1.5" + + [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" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnsafeAtomics]] +git-tree-sha1 = "b13c4edda90890e5b04ba24e20a310fbe6f249ff" +uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" +version = "0.3.0" +weakdeps = ["LLVM"] + + [deps.UnsafeAtomics.extensions] + UnsafeAtomicsLLVM = ["LLVM"] + +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "4ab62a49f1d8d9548a1c8d1a75e5f55cf196f64e" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.71" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "b8b243e47228b4a3877f1dd6aee0c5d56db7fcf4" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.13.6+1" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.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.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.demumble_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6498e3581023f8e530f34760d18f75a69e3a4ea8" +uuid = "1e29f10c-031c-5a83-9565-69cddfc27673" +version = "1.3.0+0" + +[[deps.libaec_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f5733a5a9047722470b95a81e1b172383971105c" +uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" +version = "1.1.3+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.11.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.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2022.0.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" From 6db860a52613b8384d30f293362e308e8385ed25 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Fri, 1 Aug 2025 05:40:38 -0400 Subject: [PATCH 162/203] adding Manifest --- Manifest.toml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 4e18691a1..ae012b645 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -59,9 +59,9 @@ version = "1.1.1" [[deps.ArnoldiMethod]] deps = ["LinearAlgebra", "Random", "StaticArrays"] -git-tree-sha1 = "f87e559f87a45bece9c9ed97458d3afe98b1ebb9" +git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" uuid = "ec485272-7323-5ecc-a04f-4719b315124d" -version = "0.1.0" +version = "0.4.0" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] @@ -203,7 +203,7 @@ version = "0.17.1+0" [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "a03e0b78e613effa713161eaf46985a7f8421510" +git-tree-sha1 = "fec29f3dd61c8179b6bd757fd2fd24c4dee2402e" repo-rev = "ss/no-heat-flux-when-unconsolidated" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" @@ -273,9 +273,9 @@ version = "1.0.0" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "3a3dfb30697e96a440e4149c8c51bf32f818c0f3" +git-tree-sha1 = "0037835448781bb46feb39866934e243886d756a" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.17.0" +version = "4.18.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -506,6 +506,12 @@ git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" version = "1.3.1" +[[deps.Graphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "c5abfa0ae0aaee162a3fbb053c13ecda39be545b" +uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" +version = "1.13.0" + [[deps.HDF5_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] git-tree-sha1 = "e94f84da9af7ce9c6be049e9067e511e17ff89ec" @@ -656,10 +662,10 @@ uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" version = "0.10.1" [[deps.KrylovPreconditioners]] -deps = ["Adapt", "KernelAbstractions", "LightGraphs", "LinearAlgebra", "Metis", "SparseArrays"] -git-tree-sha1 = "52d302d5e950e242f037316b6dd6e1e080afea09" +deps = ["Adapt", "Graphs", "KernelAbstractions", "LinearAlgebra", "Metis", "SparseArrays"] +git-tree-sha1 = "77e0d2f1a250af347261c9aa89f74b0cfc530a71" uuid = "45d422c2-293f-44ce-8315-2cb988662dec" -version = "0.3.4" +version = "0.3.6" [deps.KrylovPreconditioners.extensions] KrylovPreconditionersAMDGPUExt = "AMDGPU" @@ -755,12 +761,6 @@ git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" version = "1.18.0+0" -[[deps.LightGraphs]] -deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "432428df5f360964040ed60418dd5601ecd240b6" -uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" -version = "1.3.5" - [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -967,8 +967,8 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "b0ea5f938cb437ab7f194c4d0785588f941af765" -repo-rev = "ss/omip-branch" +git-tree-sha1 = "72ef9588d32a97f29dd13db42b57dcfd96841dc2" +repo-rev = "ss/omip-branch-2" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.97.5" From 5e0997c34260dc1c7720077ffdb90558741e8637 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Fri, 1 Aug 2025 05:41:12 -0400 Subject: [PATCH 163/203] comment out for now --- src/SeaIceSimulations.jl | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index 7f5faa593..809905097 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -63,11 +63,13 @@ function sea_ice_simulation(grid, ocean=nothing; bottom_heat_flux = Field{Center, Center, Nothing}(grid) top_heat_flux = Field{Center, Center, Nothing}(grid) - immersed_u_bc = FluxBoundaryCondition(u_immersed_bottom_drag, discrete_form=true, parameters=1e-1) - immersed_v_bc = FluxBoundaryCondition(v_immersed_bottom_drag, discrete_form=true, parameters=1e-1) - - u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing); immersed = immersed_u_bc) - v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing); immersed = immersed_v_bc) + u_bc = FluxBoundaryCondition(u_immersed_bottom_drag, discrete_form=true, parameters=1e-1) + v_bc = FluxBoundaryCondition(v_immersed_bottom_drag, discrete_form=true, parameters=1e-1) + + # immersed_u_bc = ImmersedBoundaryConditions(top=nothing, bottom=nothing, west=nothing, east=nothing, south=u_bc, north=u_bc) + # immersed_v_bc = ImmersedBoundaryConditions(top=nothing, bottom=nothing, south=nothing, north=nothing, west=v_bc, east=v_bc) + # u_bcs = FieldBoundaryConditions(grid, (Face(), Center(), nothing); immersed = immersed_u_bc) + # v_bcs = FieldBoundaryConditions(grid, (Center(), Face(), nothing); immersed = immersed_v_bc) # Build the sea ice model sea_ice_model = SeaIceModel(grid; From 049dacd4c33a94dd138718b9a6618265bd820d27 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 8 Aug 2025 16:18:23 +0200 Subject: [PATCH 164/203] go for it --- src/InitialConditions/InitialConditions.jl | 40 +--------------------- src/SeaIceSimulations.jl | 6 ---- 2 files changed, 1 insertion(+), 45 deletions(-) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index 6a815f056..a529e6046 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -18,7 +18,7 @@ using JLD2 # Implementation of 3-dimensional regridding # TODO: move all the following to Oceananigans! -using Oceananigans.Fields: regrid!, interpolate! +using Oceananigans.Fields: interpolate! using Oceananigans.Grids: cpu_face_constructor_x, cpu_face_constructor_y, cpu_face_constructor_z, @@ -31,44 +31,6 @@ construct_grid(::Type{<:RectilinearGrid}, arch, size, extent, topology) = construct_grid(::Type{<:LatitudeLongitudeGrid}, arch, size, extent, topology) = LatitudeLongitudeGrid(arch; size, longitude = extent[1], latitude = extent[2], z = extent[3], topology) -# Regrid a field in three dimensions -function three_dimensional_regrid!(a, b) - target_grid = a.grid isa ImmersedBoundaryGrid ? a.grid.underlying_grid : a.grid - source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid - - topo = topology(target_grid) - arch = architecture(target_grid) - arch = child_architecture(arch) - - target_y = yt = cpu_face_constructor_y(target_grid) - target_z = zt = cpu_face_constructor_z(target_grid) - - target_size = Nt = size(target_grid) - - source_x = xs = cpu_face_constructor_x(source_grid) - source_y = ys = cpu_face_constructor_y(source_grid) - - source_size = Ns = size(source_grid) - - # Start by regridding in z - @debug "Regridding in z" - zgrid = construct_grid(typeof(target_grid), arch, (Ns[1], Ns[2], Nt[3]), (xs, ys, zt), topo) - field_z = Field(location(b), zgrid) - regrid!(field_z, zgrid, source_grid, b) - - # regrid in y - @debug "Regridding in y" - ygrid = construct_grid(typeof(target_grid), arch, (Ns[1], Nt[2], Nt[3]), (xs, yt, zt), topo) - field_y = Field(location(b), ygrid); - regrid!(field_y, ygrid, zgrid, field_z); - - # Finally regrid in x - @debug "Regridding in x" - regrid!(a, target_grid, ygrid, field_y) - - return a -end - include("diffuse_tracers.jl") end # module diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index 7f5faa593..69a34a469 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -63,12 +63,6 @@ function sea_ice_simulation(grid, ocean=nothing; bottom_heat_flux = Field{Center, Center, Nothing}(grid) top_heat_flux = Field{Center, Center, Nothing}(grid) - immersed_u_bc = FluxBoundaryCondition(u_immersed_bottom_drag, discrete_form=true, parameters=1e-1) - immersed_v_bc = FluxBoundaryCondition(v_immersed_bottom_drag, discrete_form=true, parameters=1e-1) - - u_bcs = FieldBoundaryConditions(grid, (Face, Center, Nothing); immersed = immersed_u_bc) - v_bcs = FieldBoundaryConditions(grid, (Center, Face, Nothing); immersed = immersed_v_bc) - # Build the sea ice model sea_ice_model = SeaIceModel(grid; ice_salinity, From 17a22507fa279310c637ba2105d5f6a22fae493c Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 8 Aug 2025 16:24:38 +0200 Subject: [PATCH 165/203] improve --- Manifest.toml | 69 ++++++++++++++++++++++++++++----------------------- Project.toml | 2 +- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index ae012b645..66fd186c7 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.9" +julia_version = "1.10.10" manifest_format = "2.0" -project_hash = "9c3a7f83d8ac3461a9bebf2f68c603f45bfa10bf" +project_hash = "9146dada698eda5ffee4e42d71b36798d21b236d" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -160,16 +160,16 @@ uuid = "179af706-886a-5703-950a-314cd64e0468" version = "0.2.1" [[deps.CPUSummary]] -deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "5a97e67919535d6841172016c9530fd69494e5ec" +deps = ["CpuId", "IfElse", "PrecompileTools", "Preferences", "Static"] +git-tree-sha1 = "f3a21d7fc84ba618a779d1ed2fcca2e682865bab" uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.6" +version = "0.2.7" [[deps.CUDA]] -deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] -git-tree-sha1 = "b8ae59258f3d96ce75a00f9229e719356eb929d6" +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Compiler_jll", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] +git-tree-sha1 = "27f69b3923e58730f0a71396070e9114fc0bba40" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.8.2" +version = "5.8.3" [deps.CUDA.extensions] ChainRulesCoreExt = "ChainRulesCore" @@ -183,31 +183,37 @@ version = "5.8.2" SparseMatricesCSR = "a0a7dd2c-ebf4-11e9-1f05-cf50bc540ca1" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" +[[deps.CUDA_Compiler_jll]] +deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "144046baf05523e2e8510505d45e50fe5d18feef" +uuid = "d1e2174e-dfdc-576e-b43e-73b79eb1aca8" +version = "0.2.0+0" + [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "18afa851ed10552e6df25dfaa7ef450104ae73d4" +git-tree-sha1 = "12621de83838b5ce6a185050db5a184f4540679b" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "0.13.1+0" +version = "13.0.0+0" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] -git-tree-sha1 = "33576c7c1b2500f8e7e6baa082e04563203b3a45" +git-tree-sha1 = "f9a521f52d236fe49f1028d69e549e7f2644bb72" uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "0.3.5" +version = "1.0.0" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "b5c173a64f9f4224a82fdc26fda8614cb2ecfa27" +git-tree-sha1 = "cc727d90c9769db27945219f9ba149dbddc74f06" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.17.1+0" +version = "0.19.0+0" [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "fec29f3dd61c8179b6bd757fd2fd24c4dee2402e" +git-tree-sha1 = "03be9bbf454f4cefd81b80eaa9af79efb23fc7e9" repo-rev = "ss/no-heat-flux-when-unconsolidated" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.3.4" +version = "0.3.5" [[deps.CloseOpenIntervals]] deps = ["Static", "StaticArrayInterface"] @@ -497,9 +503,10 @@ uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" version = "1.6.1" [[deps.GPUToolbox]] -git-tree-sha1 = "15d8b0f5a6dca9bf8c02eeaf6687660dafa638d0" +deps = ["LLVM"] +git-tree-sha1 = "5bfe837129bf49e2e049b4f1517546055cc16a93" uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" -version = "0.2.0" +version = "0.3.0" [[deps.Glob]] git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" @@ -945,9 +952,9 @@ version = "1.0.1" [[deps.NVTX_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cd475b587ff77910789a18e68da789fc446a2a05" +git-tree-sha1 = "af2232f69447494514c25742ba1503ec7e9877fe" uuid = "e98f9f5b-d649-5603-91fd-7774390e6439" -version = "3.2.1+0" +version = "3.2.2+0" [[deps.NaNMath]] deps = ["OpenLibm_jll"] @@ -967,11 +974,11 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "72ef9588d32a97f29dd13db42b57dcfd96841dc2" +git-tree-sha1 = "54321f75f4ea124802a16c0d1e17ea488f867e03" repo-rev = "ss/omip-branch-2" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.97.5" +version = "0.97.6" [deps.Oceananigans.extensions] OceananigansAMDGPUExt = "AMDGPU" @@ -1012,7 +1019,7 @@ version = "0.3.23+4" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+4" +version = "0.8.5+0" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] @@ -1028,9 +1035,9 @@ version = "1.5.0" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "87510f7292a2b21aeff97912b0898f9553cc5c2c" +git-tree-sha1 = "2ae7d4ddec2e13ad3bddf5c0796f7547cf682391" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.1+0" +version = "3.5.2+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] @@ -1151,9 +1158,9 @@ version = "1.3.1" [[deps.RootSolvers]] deps = ["ForwardDiff", "Printf"] -git-tree-sha1 = "892b77767827af30868111d257930f567d5d78f8" +git-tree-sha1 = "769388dbf7656e70f6ee250f35bb6cbca8f43203" uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" -version = "0.4.4" +version = "0.4.6" [[deps.Roots]] deps = ["Accessors", "CommonSolve", "Printf"] @@ -1237,18 +1244,18 @@ version = "1.2.0" [[deps.SimpleTraits]] deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +git-tree-sha1 = "be8eeac05ec97d379347584fa9fe2f5f76795bcb" uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" +version = "0.9.5" [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" +version = "1.2.2" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] diff --git a/Project.toml b/Project.toml index 06e2fbda3..0450c7845 100644 --- a/Project.toml +++ b/Project.toml @@ -76,4 +76,4 @@ MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Coverage", "Test", "MPIPreferences", "CUDA_Runtime_jll", "Reactant", "PythonCall", "CondaPkg"] +test = ["Coverage", "Test", "MPIPreferences", "CUDA_Runtime_jll"] From 7d6ce58b03ee5cf1e1563493a3c8071640394f89 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 18 Aug 2025 16:50:35 +0200 Subject: [PATCH 166/203] improving the performance --- Manifest.toml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 66fd186c7..9077fbe39 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.10" manifest_format = "2.0" -project_hash = "9146dada698eda5ffee4e42d71b36798d21b236d" +project_hash = "f57e0b9bc9bbdd1cb6d317ebea00412e67510515" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -100,9 +100,9 @@ uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [[deps.Atomix]] deps = ["UnsafeAtomics"] -git-tree-sha1 = "b5bb4dc6248fde467be2a863eb8452993e74d402" +git-tree-sha1 = "29bb0eb6f578a587a49da16564705968667f5fa8" uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" -version = "1.1.1" +version = "1.1.2" [deps.Atomix.extensions] AtomixCUDAExt = "CUDA" @@ -185,9 +185,9 @@ version = "5.8.3" [[deps.CUDA_Compiler_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "144046baf05523e2e8510505d45e50fe5d18feef" +git-tree-sha1 = "fdb9ddf3e08e2aca4c84b3252df2dea046caadee" uuid = "d1e2174e-dfdc-576e-b43e-73b79eb1aca8" -version = "0.2.0+0" +version = "0.2.0+1" [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -209,8 +209,8 @@ version = "0.19.0+0" [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "03be9bbf454f4cefd81b80eaa9af79efb23fc7e9" -repo-rev = "ss/no-heat-flux-when-unconsolidated" +git-tree-sha1 = "f5b45114d7c47faa799ac72cc0a07c1e86ac0e29" +repo-rev = "ss/omip-branch-2" repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.3.5" @@ -391,9 +391,9 @@ version = "1.15.1" [[deps.DiskArrays]] deps = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] -git-tree-sha1 = "16d93ff95ecc421463eaefd694e6746bb1c0919e" +git-tree-sha1 = "bfde0790720fcac006a3d62149309a685fc3aa13" uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.4.14" +version = "0.4.15" [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] @@ -515,9 +515,9 @@ version = "1.3.1" [[deps.Graphs]] deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "c5abfa0ae0aaee162a3fbb053c13ecda39be545b" +git-tree-sha1 = "7a98c6502f4632dbe9fb1973a4244eaa3324e84d" uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" -version = "1.13.0" +version = "1.13.1" [[deps.HDF5_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] @@ -974,11 +974,11 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "54321f75f4ea124802a16c0d1e17ea488f867e03" +git-tree-sha1 = "cedd312ffaa62606155dff01e404c2d7201fc321" repo-rev = "ss/omip-branch-2" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.97.6" +version = "0.97.7" [deps.Oceananigans.extensions] OceananigansAMDGPUExt = "AMDGPU" @@ -1087,9 +1087,9 @@ version = "1.2.1" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.3" +version = "1.5.0" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] @@ -1354,9 +1354,9 @@ version = "7.2.1+1" [[deps.SurfaceFluxes]] deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "aee530bde85cd41374273568cb649e72d82921e7" +git-tree-sha1 = "eb96fea9de18a3935a836ee8634af3c126d6b77f" uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.12.0" +version = "0.12.1" [deps.SurfaceFluxes.extensions] CreateParametersExt = "ClimaParams" @@ -1415,10 +1415,10 @@ deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.Thermodynamics]] -deps = ["DocStringExtensions", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "bff801ad0a9bbb5c1bf38ffe89a83907a1b145cd" +deps = ["DocStringExtensions", "ForwardDiff", "KernelAbstractions", "Random", "RootSolvers"] +git-tree-sha1 = "edce99e94489c25f5c7f5b4065c06ffb5adb1317" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.12.15" +version = "0.13.1" [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" From 5e66a542dfe623d0bd517dc64dac8ab76f2dc63f Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 18 Aug 2025 17:02:06 +0200 Subject: [PATCH 167/203] speed up --- Manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index 9077fbe39..e31e9c89a 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -974,7 +974,7 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "cedd312ffaa62606155dff01e404c2d7201fc321" +git-tree-sha1 = "e5f3d3ec8343b3e0f7434f8d7b590a7d7f94fde8" repo-rev = "ss/omip-branch-2" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" From 9063e3e6f46ca4adccc1779a71252c269a1f0529 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 18 Aug 2025 17:21:17 +0200 Subject: [PATCH 168/203] recorrect Oceananigans --- Manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index e31e9c89a..2ac9a6980 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -974,7 +974,7 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "e5f3d3ec8343b3e0f7434f8d7b590a7d7f94fde8" +git-tree-sha1 = "b3abffc1ec12bf80dfb16de1c1c0c06dcf2d0fb6" repo-rev = "ss/omip-branch-2" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" From e7845a5380660584ba6793bc88d52e0968b7dc90 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 18 Aug 2025 17:31:34 +0200 Subject: [PATCH 169/203] new Manifest --- Manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index 2ac9a6980..e31e9c89a 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -974,7 +974,7 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "b3abffc1ec12bf80dfb16de1c1c0c06dcf2d0fb6" +git-tree-sha1 = "e5f3d3ec8343b3e0f7434f8d7b590a7d7f94fde8" repo-rev = "ss/omip-branch-2" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" From fca54844db3d503ec259b134f2a4f6e46955e88d Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 18 Aug 2025 17:38:38 +0200 Subject: [PATCH 170/203] do not add Oceananigans --- .buildkite/examples_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/examples_build.yml b/.buildkite/examples_build.yml index 7563f7be9..86c282d22 100644 --- a/.buildkite/examples_build.yml +++ b/.buildkite/examples_build.yml @@ -18,7 +18,7 @@ steps: TMPDIR: "$TARTARUS_HOME/tmp" command: - "echo '--- Instantiate project'" - - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using Pkg; Pkg.add(url=\"https://github.com/CliMA/Oceananigans.jl\", rev=\"ss/fix-zstar-bc\"); Pkg.instantiate(; verbose=true); Pkg.precompile(; strict=true)'" + - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using Pkg; Pkg.instantiate(; verbose=true); Pkg.precompile(; strict=true)'" # force the initialization of the CUDA runtime as it is lazily loaded by default - "$TARTARUS_HOME/julia-$JULIA_VERSION/bin/julia --color=yes -O0 --project -e 'using CUDA; CUDA.precompile_runtime()'" agents: From 09d22a35ad48cc63e7e74f0b5ca939ad95f2a1ae Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 18 Aug 2025 20:56:11 +0200 Subject: [PATCH 171/203] Update make.jl --- docs/make.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index 929866380..ffa9b171c 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -9,7 +9,7 @@ using Pkg Pkg.add(PackageSpec( name = "Oceananigans", url = "https://github.com/CliMA/Oceananigans.jl", - rev = "ss/fix-zstar-bc" + rev = "ss/omip-branch-2" )) Pkg.resolve() @show Pkg.status() From 38856681f5e18365ae37f930781f3790819044f9 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Wed, 20 Aug 2025 04:05:33 -0400 Subject: [PATCH 172/203] one-degree-ompi for calibration --- experiments/omip_prototype/one_degree_omip.jl | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/experiments/omip_prototype/one_degree_omip.jl b/experiments/omip_prototype/one_degree_omip.jl index 038d49ca1..4a1ccf0a8 100644 --- a/experiments/omip_prototype/one_degree_omip.jl +++ b/experiments/omip_prototype/one_degree_omip.jl @@ -30,15 +30,15 @@ Nx = 360 # longitudinal direction Ny = 180 # meridional direction Nz = 60 -r_faces = ClimaOcean.ExponentialCoordinate(Nz, -6000) -z_faces = MutableVerticalDiscretization(r_faces) +z_faces = ExponentialCoordinate(Nz, -6000, 0) +# z_faces = MutableVerticalDiscretization(z_faces) grid = TripolarGrid(arch; size = (Nx, Ny, Nz), z = z_faces, halo = (7, 7, 7)) -bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=15) +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=75) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) ##### @@ -51,34 +51,44 @@ using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVertic momentum_advection = WENOVectorInvariant(order=5) tracer_advection = WENO(order=5) -free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt=20minutes) +free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=45minutes) -mixing_length = CATKEMixingLength(Cᵇ=0.01) -turbulent_kinetic_energy_equation = CATKEEquation(Cᵂϵ=1.0) +eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=1e3, κ_symmetric=1e3) +catke_closure = ClimaOcean.OceanSimulations.default_ocean_closure() # RiBasedVerticalDiffusivity() # +closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4), eddy_closure) -catke_closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) -closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) +dataset = EN4Monthly() +date = DateTime(1958, 1, 1) +@inline mask(x, y, z, t) = z ≥ z_surf - 1 +Smetadata = Metadata(:salinity; dataset) + +FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 10) ocean = ocean_simulation(grid; Δt=1minutes, momentum_advection, tracer_advection, + timestepper = :SplitRungeKutta3, free_surface, + forcing = (; S = FS), closure) -dataset = ECCO4Monthly() +dataset = EN4Monthly() +date = DateTime(1958, 1, 1) + +set!(ocean.model, T=Metadatum(:temperature; dataset, date), + S=Metadatum(:salinity; dataset, date)) -set!(ocean.model, T=Metadatum(:temperature; dataset), - S=Metadatum(:salinity; dataset)) +@info ocean.model.clock ##### ##### A Prognostic Sea-ice model ##### # Default sea-ice dynamics and salinity coupling are included in the defaults -sea_ice = sea_ice_simulation(grid; advection=WENO(order=7)) +sea_ice = sea_ice_simulation(grid, ocean; advection=WENO(order=7)) -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), - ℵ=Metadatum(:sea_ice_concentration; dataset)) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly()), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly())) ##### ##### A Prescribed Atmosphere model @@ -94,21 +104,20 @@ radiation = Radiation() ##### ##### An ocean-sea ice coupled model ##### - + omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=30, stop_time=60days) +omip = Simulation(omip, Δt=30minutes, stop_time=60days) # Figure out the outputs.... - checkpointer_address(::SeaIceModel) = "SeaIceModel" ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, - schedule = IterationInterval(10000), + schedule = IterationInterval(1000), prefix = "ocean_checkpoint_onedegree", overwrite_existing = true) sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, - schedule = IterationInterval(10000), + schedule = IterationInterval(1000), prefix = "sea_ice_checkpoint_onedegree", overwrite_existing = true) @@ -143,11 +152,11 @@ function progress(sim) end # And add it as a callback to the simulation. -add_callback!(omip, progress, IterationInterval(50)) +add_callback!(omip, progress, IterationInterval(1)) run!(omip) -omip.Δt = 15minutes +omip.Δt = 40minutes omip.stop_time = 58 * 365days run!(omip) From 988ec773e8415791286cdcc3d5614ad7d3af648f Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Wed, 20 Aug 2025 04:08:12 -0400 Subject: [PATCH 173/203] update one degree --- experiments/omip_prototype/one_degree_omip.jl | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/experiments/omip_prototype/one_degree_omip.jl b/experiments/omip_prototype/one_degree_omip.jl index 4a1ccf0a8..e93bc708f 100644 --- a/experiments/omip_prototype/one_degree_omip.jl +++ b/experiments/omip_prototype/one_degree_omip.jl @@ -15,15 +15,6 @@ using CUDA import Oceananigans.OutputWriters: checkpointer_address -function synch!(clock1::Clock, clock2) - # Synchronize the clocks - clock1.time = clock2.time - clock1.iteration = clock2.iteration - clock1.last_Δt = clock2.last_Δt -end - -synch!(model1, model2) = synch!(model1.clock, model2.clock) - arch = GPU() Nx = 360 # longitudinal direction @@ -54,7 +45,7 @@ tracer_advection = WENO(order=5) free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=45minutes) eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=1e3, κ_symmetric=1e3) -catke_closure = ClimaOcean.OceanSimulations.default_ocean_closure() # RiBasedVerticalDiffusivity() # +catke_closure = ClimaOcean.OceanSimulations.default_ocean_closure() closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4), eddy_closure) dataset = EN4Monthly() From 34190227d69800144e53410624cef658c1c9baff Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Wed, 20 Aug 2025 05:28:02 -0400 Subject: [PATCH 174/203] use the correct value --- experiments/omip_prototype/one_degree_omip.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/experiments/omip_prototype/one_degree_omip.jl b/experiments/omip_prototype/one_degree_omip.jl index e93bc708f..f2bae0dd2 100644 --- a/experiments/omip_prototype/one_degree_omip.jl +++ b/experiments/omip_prototype/one_degree_omip.jl @@ -24,6 +24,8 @@ Nz = 60 z_faces = ExponentialCoordinate(Nz, -6000, 0) # z_faces = MutableVerticalDiscretization(z_faces) +const z_surf = z_faces(Nz) + grid = TripolarGrid(arch; size = (Nx, Ny, Nz), z = z_faces, From b1430e2d93a251308f0b7ab47ac828e278f8e0ff Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 20 Aug 2025 12:01:15 +0200 Subject: [PATCH 175/203] remove this for the moment --- docs/src/interface_fluxes.md | 635 ----------------------------------- 1 file changed, 635 deletions(-) diff --git a/docs/src/interface_fluxes.md b/docs/src/interface_fluxes.md index 047ccce2e..7d1a89e98 100644 --- a/docs/src/interface_fluxes.md +++ b/docs/src/interface_fluxes.md @@ -76,638 +76,3 @@ In both cases, computing turbulent fluxes requires: 5. Possibly, additional "bulk" properties of the surface media and radiation fluxes in order to compute an equilibrium "skin" surface temperature that differs from the bulk temperature below the surface. - -!!! note - In general, the surface specific humidity is typically related to the saturation specific humidity - at the the surface temperature ``T_s``, according to the Clausius-Claperyon relation. - For example, for ocean surfaces, the surface specific humidity is computed - according to via [Raoult's law](https://en.wikipedia.org/wiki/Raoult%27s_law) as - - ```math - q^\dagger(\rho, S, T) = x_{H_2O}(S) \frac{p_v^\dagger}{\rho R_v T} - ``` - - where ``x_{H_2O}(S)`` is the mole fraction of pure water in seawater with salinity ``S``, - and ``p_v^\dagger`` is the saturation vapor pressure, - - ```math - p_v^\dagger(T) = p_{tr} \left ( \frac{T}{T_{tr}} \right )^{\Delta c_p / R_v} \exp \left [ \frac{ℒ_{v0} - Δc_p T₀}{R_v} \left (\frac{1}{T_{tr}} - \frac{1}{T} \right ) \right ] - \quad \text{where} \quad - Δc_p = c_{p \ell} - c_{pv} \, . - ``` - - Many flux solvers (and the OMIP protocol) use a constant ``x_{H_2O} = 0.98``, which is equivalent to assuming - that the surface salinity is ``S \approx 35 \, \mathrm{g \, kg^{-1}}``, along with a reference seawater salinity composition. - Other surface specific humidity models may be used that take into account, for example, the microscopic structure - of snow, or the presence of a "dry skin" that buffers saturated soil from the atmosphere in a land model. - - Default values for the atmosphere thermodynamic parameters used to compute the saturation vapor pressure - and atmospheric equation of state are - - ```@example interface_fluxes - using ClimaOcean.OceanSeaIceModels.PrescribedAtmospheres: AtmosphereThermodynamicsParameters - AtmosphereThermodynamicsParameters() - ``` - -### Coefficient-based fluxes - -Turbulent fluxes may be computed by prescribing "transfer coefficients" that relate differences -between the near-surface atmosphere and the ocean surface to fluxes, - -```math -\overline{\bm{u}' w'} ≈ C_D \, Δ \bm{u} \, U \\ -\overline{w' \theta'} ≈ C_\theta \, Δ \theta \, U \\ -\overline{w' q'} ≈ C_q \, Δ q \, U -``` - -The variable ``U`` is a characteristic velocity scale, which is most simply formulated as ``U = | Δ \bm{u}|``. -However, some parameterizations use formulations for ``U`` that -produce non-vanishing heat and moisture fluxes in zero-mean-wind conditions. -Usually these parameterizations are formulated as models for "gustiness" associated with atmospheric convection; -but more generally a common thread is that ``U`` may include contributions from unresolved turbulent motions -in addition to the relative mean velocity, ``Δ \bm{u}``. - -The variable ``C_D`` is often called the drag coefficient, while ``C_\theta`` and ``C_q`` are the heat transfer -coefficient and vapor flux coefficient. -The simplest method for computing fluxes is merely to prescribe ``C_D``, ``C_\theta``, and ``C_q`` -as constants -- typically with a magnitude around ``5 × 10^{-4}``--``2 × 10^{-3}``. -A comprehensive example is given below, but we note briefly here that -`ClimaOcean` supports the computation of turbulent fluxes with constant coefficients via - -```@example interface_fluxes -using ClimaOcean - -coefficient_fluxes = CoefficientBasedFluxes(drag_coefficient=2e-3, - heat_transfer_coefficient=2e-3, - vapor_flux_coefficient=1e-3) -``` - -### Similarity theory for neutral boundary layers - -The standard method for computing fluxes in realistic Earth system modeling contexts -uses a model for the structure of the near-surface atmosphere based on Monin--Obukhov similarity theory. -Similarity theory is essentially a dimensional argument and begins with the definition of "characteristic scales" -which are related to momentum, heat, and vapor fluxes through - -```math -u_\star^2 ≡ | \overline{\bm{u}' w'} | \\ -u_\star \theta_\star ≡ \overline{w' \theta'} \\ -u_\star q_\star ≡ \overline{w' q'} -``` - -where ``u_\star``, often called the "friction velocity", is the characteristic scale for velocity, -``\theta_\star`` is the characteristic scale for temperature, and ``q_\star`` is the characteristic scale -for water vapor. - -To introduce similarity theory, we first consider momentum fluxes in "neutral" conditions, -or with zero buoyancy flux. -We further simplify the situation by considering unidirectional flow with ``\bm{u} = u \, \bm{\hat x}``. -(To generalize our results to any flow direction, we simply rotate fluxes into the direction of the -relative velocity ``Δ \bm{u}``.) -The fundamental supposition of similarity theory is that the vertical shear depends only on -height above the boundary, such that by dimensional analysis, - -```math -\partial_z u \sim \frac{u_\star}{z} \, , -\qquad \text{and thus} \qquad -\partial_z u = \frac{u_\star}{\kappa z} \, , -``` - -where the second expression forms an equality by introducing the "Von Karman constant" ``\kappa``, -which is placed in the denominator by convention. -We can then integrate this expression from an inner scale ``z=\ell`` up to ``z=h`` to obtain - -```math -u_a(h) - u_a(\ell_u) = \frac{u_⋆}{\kappa} \log \left ( \frac{h}{\ell_u} \right ) -``` - -The inner length scale ``\ell_u``, which is called the "momentum roughness length", -can be interpreted as producing a characteristic upper value for the boundary layer shear, ``u_⋆ / \ell_u`` -in the region where similarity theory must be matched with the inner boundary layer (such as a viscous sublayer) -below. -Note that we take the inner velocity scale ``u_a(\ell_u)`` as being equal to the velocity of the surface, -so ``u_a(\ell_u) = u_s``. - -!!! note - We currently assume that the input to the surface flux computation is the - atmospheric velocity at ``z=h``. However, in coupled modeling context we are typically - instead given the atmosphere velocity _averaged_ over the height of the first layer, - or ``⟨u_a⟩_h = \frac{1}{h} \int_0^h \, u_a \, \mathrm{d} z``. - Formulating the flux computation in terms of ``⟨u_a⟩_h`` rather than ``u_a(h)`` - (e.g. [nishizawa2018surface](@citet)) - is a minor modification to the algorithm and an important avenue for future work. - -The roughness length in general depends on the physical nature of the surface. -For smooth, no-slip walls, experiments (cite) found agreement with a viscous sublayer model - -```math -\ell_ν = \mathbb{C}_\nu \frac{\nu}{u_\star} \, , -``` - -where ``\nu`` is the kinematic viscosity of the fluid (the air in our case) and ``\mathbb{C}_\nu`` is a free -parameter which was found to be around ``0.11``. -For air-water interfaces that develop a wind-forced spectrum of surface gravity waves, the alternative scaling - -```math -\ell_g = \mathbb{C}_g \frac{u_\star^2}{g} \, , -``` - -where ``g`` is gravitational acceleration, has been repeatedly (and perhaps shockingly due to its simplicity) confirmed by field campaigns. -The free parameter ``\mathbb{C}_g`` is often called - the "Charnock parameter" and takes typical values -between ``0`` and ``0.03`` [edson2013exchange](@citep). - -```@example -using ClimaOcean -using CairoMakie -set_theme!(Theme(fontsize=14, linewidth=4)) - -charnock_length = MomentumRoughnessLength(wave_formulation = 0.02, - smooth_wall_parameter = 0, - maximum_roughness_length = Inf) - -smooth_wall_length = MomentumRoughnessLength(wave_formulation = 0, - smooth_wall_parameter = 0.11) - -default_roughness_length = MomentumRoughnessLength() -modified_default_length = MomentumRoughnessLength(wave_formulation = 0.011) - -u★ = 1e-2:5e-3:3e-1 -ℓg = charnock_length.(u★) -ℓν = smooth_wall_length.(u★) -ℓd = default_roughness_length.(u★) -ℓ2 = modified_default_length.(u★) - -fig = Figure(size=(800, 400)) -ax1 = Axis(fig[1, 1], xlabel="Friction velocity, u★ (m s⁻¹)", ylabel="Momentum roughness length ℓᵤ (m)") -lines!(ax1, u★, ℓd, label="ClimaOcean default") -lines!(ax1, u★, ℓg, label="Charnock") -lines!(ax1, u★, ℓν, label="Smooth wall") -lines!(ax1, u★, ℓ2, color=:black, label="ClimaOcean default with ℂg = 0.011") - -ax2 = Axis(fig[1, 2], xlabel="Friction velocity, u★ (m s⁻¹)", ylabel="Momentum roughness length, ℓᵤ (m)") -u★ = 0.1:0.1:10 -ℓd = default_roughness_length.(u★) -ℓ2 = modified_default_length.(u★) -lines!(ax2, u★, ℓd) -lines!(ax2, u★, ℓ2, color=:black) - -Legend(fig[0, 1:2], ax1, orientation=:horizontal) - -fig -``` - -!!! note - The roughness length ``\ell`` should not be interpreted as a physical length scale, - a fact made clear by its submillimeter magnitude under (albeit calm) air-sea flux conditions. - -## Computing fluxes and the effective similarity drag coefficient - -ClimaOcean's default roughness length for air-sea fluxes is a function of the -friction velocity ``u_\star``. -This formulation produces a nonlinear equation for ``u_\star``, in terms of ``Δ u = u_a(h) - u_o``, -which we emphasize by rearranging the similarity profile - -```math -u_\star = \frac{\kappa \, Δ u}{\log \left [ h / \ell_u(u_\star) \right ]} \, . -``` - -The above equation is solved for ``u_\star`` using fixed-point iteration initialized with a reasonable -guess for ``u_\star``. -Once ``u_\star`` is obtained, the similarity drag coefficient may then be computed via - -```math -C_D(h) ≡ \frac{u_\star^2}{|Δ u(h)|^2} = \frac{\kappa^2}{\left ( \log \left [ h / \ell_u \right ] \right )^2} \, -``` - -where we have used the simple bulk velocity scale ``U = Δ u``. -We have also indicated that, the effective similarity drag "coefficient" depends on the height ``z=h`` -at which the atmospheric velocity is computed to form the relative velocity ``Δ u = u_a(h) - u_o``. -Most observational campaigns use ``h = 10 \, \mathrm{m}`` and most drag coefficients reported in the -literature pertain to ``h=10 \, \mathrm{m}``. - -To compute fluxes with ClimaOcean, we build an `OceanSeaIceModel` with an atmosphere and ocean state -concocted such that we can evaluate fluxes over a range of relative atmosphere and oceanic conditions. -For this we use a ``200 × 200`` horizontal grid and start with atmospheric winds that vary from -the relatively calm ``u_a(10 \, \mathrm{m}) = 0.5 \, \mathrm{m \, s^{-1}}`` to a -blustery ``u_a(10 \, \mathrm{m}) = 40 \, \mathrm{m \, s^{-1}}``. -We also initialize the ocean at rest with surface temperature ``T_o = 20 \, \mathrm{{}^∘ C}`` and -surface salinity ``S_o = 35 \, \mathrm{g \, kg^{-1}}`` -- but the surface temperature and salinity won't matter until later. - -```@example interface_fluxes -using Oceananigans -using ClimaOcean - -# Atmosphere velocities -Nx = Ny = 200 -uₐ = range(0.5, stop=40, length=Nx) # winds at 10 m, m/s - -# Ocean state parameters -T₀ = 20 # Surface temperature, ᵒC -S₀ = 35 # Surface salinity - -x = y = (0, 1) -z = (-1, 0) -atmos_grid = RectilinearGrid(size=(Nx, Ny); x, y, topology=(Periodic, Periodic, Flat)) -ocean_grid = RectilinearGrid(size=(Nx, Ny, 1); x, y, z, topology=(Periodic, Periodic, Bounded)) - -# Build the atmosphere -atmosphere = PrescribedAtmosphere(atmos_grid, surface_layer_height=10) -interior(atmosphere.tracers.T) .= 273.15 + T₀ # K -interior(atmosphere.velocities.u, :, :, 1, 1) .= uₐ # m/s - -kw = (momentum_advection=nothing, tracer_advection=nothing, closure=nothing) -ocean = ocean_simulation(ocean_grid; kw...) -set!(ocean.model, T=T₀, S=S₀) -``` - -Next we build two models with different flux formulations -- the default "similarity model" -that uses similarity theory with "Charnock" gravity wave parameter ``\mathbb{C}_g = 0.02``, -and a "coefficient model" with a constant drag coefficient ``C_D = 2 × 10^{-3}``: - -```@example interface_fluxes -neutral_similarity_fluxes = SimilarityTheoryFluxes(stability_functions=nothing) -interfaces = ComponentInterfaces(atmosphere, ocean; atmosphere_ocean_fluxes=neutral_similarity_fluxes) -default_model = OceanSeaIceModel(ocean; atmosphere, interfaces) - -momentum_roughness_length = MomentumRoughnessLength(wave_formulation=0.04) -neutral_similarity_fluxes = SimilarityTheoryFluxes(stability_functions=nothing; momentum_roughness_length) -interfaces = ComponentInterfaces(atmosphere, ocean; atmosphere_ocean_fluxes=neutral_similarity_fluxes) -increased_roughness_model = OceanSeaIceModel(ocean; atmosphere, interfaces) - -coefficient_fluxes = CoefficientBasedFluxes(drag_coefficient=2e-3) -interfaces = ComponentInterfaces(atmosphere, ocean; atmosphere_ocean_fluxes=coefficient_fluxes) -coefficient_model = OceanSeaIceModel(ocean; atmosphere, interfaces) -``` - -Note that `OceanSeaIceModel` computes fluxes upon instantiation, so after constructing -the two models we are ready to analyze the results. -We first verify that the similarity model friction velocity has been computed successfully, - -```@example interface_fluxes -u★ = default_model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity -u★ = interior(u★, :, 1, 1) -extrema(u★) -``` - -and it seems that we've obtained a range of friction velocities, which is expected -given that our atmospheric winds varied from ``0.5`` to ``40 \, \mathrm{m \, s^{-1}}``. -Computing the drag coefficient for the similarity model is as easy as - -```@example interface_fluxes -Cᴰ_default = @. (u★ / uₐ)^2 -extrema(Cᴰ_default) -``` - -We'll also re-compute the drag coefficient for the coefficient model -(which we specified as constant), which verifies that the coefficient was correctly -specified: - -```@example interface_fluxes -u★_coeff = coefficient_model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity -u★_coeff = interior(u★_coeff, :, 1, 1) -Cᴰ_coeff = @. (u★_coeff / uₐ)^2 -extrema(Cᴰ_coeff) -``` - -We'll compare the computed fluxes and drag coefficients from our two models with -a polynomial expression due to [large2009global](@citet), and -an expression reported by [edson2013exchange](@citet) that was developed at ECMWF, - -```@example interface_fluxes -# From Large and Yeager (2009), equation 10 -c₁ = 0.0027 -c₂ = 0.000142 -c₃ = 0.0000764 -u★_LY = @. sqrt(c₁ * uₐ + c₂ * uₐ^2 + c₃ * uₐ^3) -Cᴰ_LY = @. (u★_LY / uₐ)^2 - -# From Edson et al. (2013), equation 20 -c₁ = 1.03e-3 -c₂ = 4e-5 -p₁ = 1.48 -p₂ = 0.21 -Cᴰ_EC = @. (c₁ + c₂ * uₐ^p₁) / uₐ^p₂ -u★_EC = @. sqrt(Cᴰ_EC) * uₐ -extrema(u★_EC) -``` - -Finally, we plot the results to compare the estimated friction velocity and effective -drag coefficient from the polynomials expressions with the two `OceanSeaIceModel`s: - -```@example interface_fluxes -using CairoMakie -set_theme!(Theme(fontsize=14, linewidth=4)) - -# Extract u★ and compute Cᴰ for increased roughness model -u★_rough = increased_roughness_model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity -u★_rough = interior(u★_rough, :, 1, 1) -Cᴰ_rough = @. (u★_rough / uₐ)^2 - -fig = Figure(size=(800, 400)) -axu = Axis(fig[1:2, 1], xlabel="uₐ (m s⁻¹) at 10 m", ylabel="u★ (m s⁻¹)") -lines!(axu, uₐ, u★, label="ClimaOcean default") -lines!(axu, uₐ, u★_rough, label="Increased roughness model") -lines!(axu, uₐ, u★_LY, label="Large and Yeager (2009) polynomial fit") -lines!(axu, uₐ, u★_EC, label="ECMWF polynomial fit (Edson et al. 2013)") - -axd = Axis(fig[1:2, 2], xlabel="uₐ (m s⁻¹) at 10 m", ylabel="1000 × Cᴰ") -lines!(axd, uₐ, 1000 .* Cᴰ_default, label="ClimaOcean default") -lines!(axd, uₐ, 1000 .* Cᴰ_rough, label="Increased roughness model") -lines!(axd, uₐ, 1000 .* Cᴰ_LY, label="Large and Yeager (2009) polynomial fit") -lines!(axd, uₐ, 1000 .* Cᴰ_EC, label="ECMWF polynomial fit (Edson et al. 2013)") - -Legend(fig[3, 1:2], axd, nbanks = 2) - -fig -``` - -## Non-neutral boundary layers and stability functions - -The relationship between the relative air-sea state and turbulent fluxes -is modified by the presence of buoyancy fluxes -- "destabilizing" fluxes, which stimulate convection, -tend to increase turbulent exchange, while stabilizing fluxes suppress turbulence and turbulent exchange. -Monin--Obhukhov stability theory provides a scaling-argument-based framework -for modeling the effect of buoyancy fluxes on turbulent exchange. - -### Buoyancy flux and stability of the near-surface atmosphere - -Our next objective is to characterize the atmospheric statbility in terms of the buoyancy flux, ``\overline{w' b'}``, -which requires a bit of thermodynamics background to define the buoyancy perturbation, ``b'``. - -#### Buoyancy for a non-condensing mixture of dry air and water vapor - -The atmosphere is generally a mix of dry air, water vapor, non-vapor forms of water such as liquid droplets, -ice particles, rain, snow, hail, sleet, graupel, and more, and trace gases. -In the definition of buoyancy that follows, we neglect both the mass and volume of non-vapor water, -so that the specific humidity may be written - -```math -q \approx \frac{\rho_v}{\rho_v + \rho_d} \approx \frac{\rho_v}{\rho} \, , -``` - -where ``\rho_v`` is the density of water vapor, ``\rho_d`` is the density of dry air, and ``\rho \approx \rho_v + \rho_d`` -is the total density neglecting the mass of hypothetical condensed water species. - -!!! note - We endeavor to provide more information about the impact of this approximation. - Also, note that atmospheric data products like JRA55 do not explicitly provide - the mass ratio of condensed water, so the approximation is required in at least - some situations (such as simulations following the protocol of the Ocean Model - Intercomparison Project, OMIP). - On the other hand, generalizing the buoyancy formula that follow below to account - for the mass of condensed water is straightforward. - -The ideal gas law for a mixture of dry air and water vapor is then - -```math -p = \rho R_m(q) T \, -\qquad \text{where} \qquad -R_m(q) ≈ R_d \left (1 - q \right ) + R_v q = R_d \left ( 1 - \mathscr{M} q \right ) \, , -``` - -where ``\mathscr{M} = R_v/R_d - 1`` and ``R_m(q)`` is the effective mixture gas "constant" which varies with specific humidity ``q``, -and the ``\approx`` indicates that its form neglects the mass of condensed species. - -The buoyant perturbation experienced by air parcels advected by subgrid turbulent motions is then - -```math -b' ≡ - g \frac{\rho - \bar{\rho}}{\rho} = g \frac{\alpha - \bar{\alpha}}{\bar{\alpha}} -\qquad \text{where} \qquad -α = \frac{1}{\rho} = \frac{R_m T}{p} \, . -``` - -We neglect the effect of pressure perturbations to compute the buoyancy flux, so that ``p = \bar{p}`` and - -```math -\alpha - \bar{\alpha} = \frac{R_d}{p} \left [ T' - \mathscr{M} \left ( q' \bar{T} + \bar{q} T' + q' T' - \overline{q' T'} \right ) \right ] \, . -``` - -#### Buoyancy flux and the characteristic buoyancy scale - -In a computation whose details are reserved for an appendix, and which neglects ``\overline{q'T'}`` and the triple correlation ``\overline{w' q' T'}``, -we find that the buoyancy flux is approximately - -```math -\overline{w' b'} \approx g \frac{\overline{w'T'} - \mathscr{M} \left ( \overline{w' q'} \bar{T} + \bar{q} \overline{w' T'} \right )}{\bar{T} \left ( 1 - \mathscr{M} \bar q \right )} \, . -``` - -The characteristic buoyancy scale ``b_\star``, defined via ``u_\star b_\star \equiv \overline{w'b'}|_0``, is defined analogously to the temperature and vapor scales ``u_\star \theta_\star \equiv \overline{w' T'}`` and ``u_\star q_\star \equiv \overline{w' q'}``. -We therefore find - -```math -b_⋆ ≡ g \frac{\theta_\star - \mathscr{M} \left ( q_\star T_s + q_s \theta_\star \right ) }{ T_s \left (1 + \mathscr{M} q_s \right )} \, . -``` - -##### Stability of the near-surface atmosphere - -We use the ratio between the buoyancy flux and shear production at ``z=h`` -- which oceanographers often call -the "flux Richardson number", ``Ri_f`` -- to diagnose the stability of the atmosphere, - -```math -Ri_f(z) ≡ ζ(z) \equiv - \frac{\overline{w' b'}}{\partial_z \bar{\bm{u}} \, ⋅ \, \overline{\bm{u}' w'}} = - \frac{\kappa \, z}{u_\star^2} b_⋆ = \frac{z}{L_\star} -\qquad \text{where} \qquad -L_\star ≡ - \frac{u_\star^2}{\kappa b_\star} \, , -``` - -``\zeta`` is called the "stability parameter" and ``L_\star`` is called the "Monin--Obhukhov length scale". - -### The Monin--Obhukhov "stability functions" - -The fundamental premise of Monin--Obhkhov stability theory is that shear within a similarity layer affected by buoyancy fluxes may written - -```math -\frac{\kappa \, z}{u_\star} \partial_z \bar{u} = \tilde{\psi}_u(\zeta) \, , -``` - -where ``\tilde{\psi}_u(\zeta)`` is called the "stability function" (aka "dimensionless shear", and often denoted ``\phi``). -Comparing the Monin--Obukhov scaling to the neutral case expounded above, we find that ``\tilde{\psi}(0) = 1`` in neutral conditions with ``\zeta=0``. -In the presence of destabilizing fluxes, when ``ζ < 0``, observations show that ``\tilde{\psi}_u(\zeta) < 1`` (e.g. Businger 1971) -- representing an enhancement of turbulent exchange between the surface and atmosphere. -Conversely, ``\tilde{\psi}_u > 1`` when ``ζ > 0``, representing a suppression of turbulent fluxes by stable density stratification, or alternatively, an increase in the shear required to sustain a given friction velocity ``u_\star``. - -Monin and Obhukov's dimensional argument is also extended to potential temperature, so that for example - -```math -\frac{κ \, z}{\theta_\star} \partial_z \bar{\theta} = \tilde{\psi}_\theta (\zeta) \, . -``` - -Within the context of Monin--Obukhov stabilty theory, it can be shown that the neutral value ``\tilde{\psi}_\theta(0)`` is equal to the neutral turbulent Prandtl number, - -```math -Pr(\zeta=0) \equiv \frac{\tilde{\psi}_\theta(0)}{\tilde{\psi}_u(0)} = \tilde{\psi}_\theta(0) \, , -``` - -and observations suggest that ``\tilde{\psi}_θ(0) ≈ 0.7``. -Otherwise, the interpretation of variations in ``\tilde{\psi}_\theta`` (increased by stability, decreased by instability)is similar as for momentum. -We typically use the same "scalar" stability function to scale the vertical profiles of both temperature and water vapor, but neverthless ClimaOcean retains the possibility of an independent ``\tilde{\psi}_q``. - -### The Monin--Obhukhov self-similar vertical profiles - -To determine the implications of Monin--Obukhov similarity theory on the vertical profiles -of ``u``, ``\theta``, and ``q``, and therefore the implications for computing fluxes based on -the given differences ``Δ\bm{u}``, ``Δ \theta``, and ``Δ q``, we introduce "auxiliary stability functions" ``\psi_u(\zeta)``, which have derivatives ``\psi_u'(\zeta)`` and are related to ``\tilde{\psi}_u`` via - -```math -\tilde{ψ}_u(ζ) \equiv 1 - ζ ψ_u'(ζ) \, . -``` - -Inserting this transformation into the Monin--Obukhov scaling argument and rearranging terms yields - -```math -\partial_z u = \frac{u_\star}{\kappa \, z} + \frac{b_\star}{u_⋆} ψ' \left ( \frac{z}{L_⋆} \right ) \, , -``` - -which when integrated from ``z=\ell_u`` to ``z=h``, as for the neutral case, then produces - -```math -u_a(h) - u_a(\ell_u) = Δ u = \frac{u_\star}{\kappa} - \left [ \log \left (\frac{h}{\ell_u} \right ) - ψ_u \left ( \frac{h}{L_\star} \right ) + ψ_u \left (\frac{\ell_u}{L_\star} \right ) \right ] \, . -``` - -The term ``\psi_u(\ell_u / L_\star)`` is often neglected because ``\ell_u / L_\star`` is miniscule and because by definition, ``\psi_u(0) = 0``. -Similar formulas hold for temperature and water vapor, - -```math -Δ \theta = \frac{\theta_\star}{\kappa} \left [ \log \left (\frac{h}{\ell_\theta} \right ) - ψ_\theta \left ( \frac{h}{L_\star} \right ) + ψ_\theta \left (\frac{\ell_\theta}{L_\star} \right ) \right ] \, , \\[2ex] -Δ q = \frac{q_\star}{\kappa} \left [ \log \left (\frac{h}{\ell_q} \right ) - ψ_q \left ( \frac{h}{L_\star} \right ) + ψ_q \left (\frac{\ell_q}{L_\star} \right ) \right ] \, . -``` - -Let's plot some stability functions: - -```@example interface_fluxes -using ClimaOcean.OceanSeaIceModels.InterfaceComputations: - EdsonMomentumStabilityFunction, # Edson et al. 2013 - EdsonScalarStabilityFunction, # Edson et al. 2013 - ShebaMomentumStabilityFunction, # Grachev et al. 2007 - ShebaScalarStabilityFunction, # Grachev et al. 2007 - PaulsonMomentumStabilityFunction, # Paulson 1970 - PaulsonScalarStabilityFunction # Paulson 1970 - -edson_momentum = EdsonMomentumStabilityFunction() -edson_scalar = EdsonScalarStabilityFunction() -sheba_momentum = ShebaMomentumStabilityFunction() -sheba_scalar = ShebaScalarStabilityFunction() -paulson_momentum = PaulsonMomentumStabilityFunction() -paulson_scalar = PaulsonScalarStabilityFunction() - -ζstep = 0.01 -ζ = -4:ζstep:4 -ζ⁺ = first(ζ[ζ .≥ 0]):ζstep:last(ζ) -ζ⁻ = first(ζ):ζstep:last(ζ[ζ .≤ 0]) - -fig = Figure(size=(800, 400)) - -axm = Axis(fig[1, 1], xlabel="Stability parameter ζ", ylabel="Momentum auxiliary stability function ψₘ") -axs = Axis(fig[1, 2], xlabel="Stability parameter ζ", ylabel="Scalar auxiliary stability function ψₛ") - -lines!(axm, ζ, edson_momentum.(ζ), label="Edson et al. (2013)", alpha=0.7) -lines!(axm, ζ⁺, sheba_momentum.(ζ⁺), label="Grachev et al. (2007)", alpha=0.7) -lines!(axm, ζ⁻, paulson_momentum.(ζ⁻), label="Paulson (1970)", alpha=0.7) -axislegend(axm, position=:lb) - -lines!(axs, ζ, edson_scalar.(ζ), label="Edson et al. (2013)", alpha=0.7) -lines!(axs, ζ⁺, sheba_scalar.(ζ⁺), label="Grachev et al. (2007)", alpha=0.7) -lines!(axs, ζ⁻, paulson_scalar.(ζ⁻), label="Paulson (1970)", alpha=0.7) - -for ax in (axm, axs) - ylims!(ax, -14, 4) -end - -fig -``` - -#### Computing fluxes given atmopshere, surface, and bulk interior states - -We compute surface fluxes by solving the nonlinear set of equations for ``u_\star``, ``\theta_\star``. -We use fixed point iteration of the following three-variable system, - -```math -u_⋆^{n+1} = \, Δ u \, \, Ξ_u \left (h, \ell_u^n, L_⋆^n \right ) \\[2ex] -θ_⋆^{n+1} = \, Δ θ \, \, Ξ_θ \left (h, \ell_θ^n, L_⋆^n \right ) \\[2ex] -q_⋆^{n+1} = \, Δ q \, \, Ξ_q \left (h, \ell_q^n, L_⋆^n \right ) -``` - -where, for example, - -```math -\Xi_u \left ( h, \ell_u, L_⋆ \right ) ≡ \frac{κ}{\log \left ( \frac{h}{\ell_u} \right ) - \psi_u \left ( \frac{h}{L_\star} \right ) + \psi_u \left ( \frac{\ell_u}{L_\star} \right )} \, , -``` - -The above equations indicate how ``\ell_u``, ``\ell_\theta``, ``\ell_q``, and ``L_⋆ = - u_\star^2 / κ b_\star`` are all functions of ``u_\star, \theta_\star, q_\star``;\ -estimating the right-hand side requires using values at the previous iterate ``n``. -Note that if a skin temperature model is used, then we obtain a four-variable system, - -```math -u_⋆^{n+1} = \, Δ u \, \, Ξ_u \left (h, \ell_u^n, L_⋆^n \right ) \\[2ex] -θ_⋆^{n+1} = \, Δ θ^n \, \, Ξ_θ \left (h, \ell_θ^n, L_⋆^n \right ) \\[2ex] -q_⋆^{n+1} = \, Δ q^n \, \, Ξ_q \left (h, \ell_q^n, L_⋆^n \right ) \\[2ex] -T_s^{n+1} = F_T \left (θ_⋆, q_⋆, I_{sw}, I_{lw}, \cdots \right ) -``` - -where ``F_T`` denotes an estimate of the surface temperature that, in general, requires all incoming heat fluxes -including shortwave and longwave radiation ``I_{sw}`` and ``I_{lw}``. -In the skin temperature case, the air-surface temperature difference ``Δ \theta`` and the saturation specific humidity -that enters into the air-surface specific humidity difference ``Δ q`` also change each iterate. - -```@example interface_fluxes -using ClimaOcean.OceanSeaIceModels.InterfaceComputations: surface_specific_humidity - -ρₐ = 1.2 # guess -Tₒ = 273.15 + 20 # in Kelvin -Sₒ = 35 -interfaces = default_model.interfaces -ℂₐ = interfaces.atmosphere_properties -q_formulation = interfaces.atmosphere_ocean_interface.properties.specific_humidity_formulation -qₛ = surface_specific_humidity(q_formulation, ℂₐ, ρₐ, Tₒ, Sₒ) -@show qₛ -``` - -We then set the atmospheric state: - -```@example interface_fluxes -interior(atmosphere.pressure) .= 101352 -interior(atmosphere.tracers.q) .= qₛ - -Tₐ = 273.15 .+ range(-40, stop=40, length=Ny) -Tₐ = reshape(Tₐ, 1, Ny) -interior(atmosphere.tracers.T) .= Tₐ - -Oceananigans.TimeSteppers.update_state!(default_model) -u★ = default_model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity -θ★ = default_model.interfaces.atmosphere_ocean_interface.fluxes.temperature_scale - -fig = Figure(size=(800, 600)) -axu = Axis(fig[2, 1], xlabel="Wind speed uₐ (m s⁻¹)", ylabel="Air-sea temperature difference (K)") -axθ = Axis(fig[2, 2], xlabel="Wind speed uₐ (m s⁻¹)", ylabel="Air-sea temperature difference (K)") -axC = Axis(fig[3, 1:2], xlabel="Wind speed uₐ (m s⁻¹)", ylabel="Cᴰ / neutral Cᴰ") - -ΔT = Tₐ .- Tₒ -ΔT = dropdims(ΔT, dims=1) - -hmu = heatmap!(axu, uₐ, ΔT, u★, colormap=:speed) -hmθ = heatmap!(axθ, uₐ, ΔT, θ★, colormap=:balance) - -Colorbar(fig[1, 1], hmu, label="u★ (m s⁻¹)", vertical=false) -Colorbar(fig[1, 2], hmθ, label="θ★ (K)", vertical=false) - -Cᴰ = [(u★[i, j] / uₐ[i])^2 for i in 1:Nx, j in 1:Ny] - -for j in (1, 20, 50, 100, 150, 200) - lines!(axC, uₐ, Cᴰ[:, j] ./ Cᴰ_default, label="ΔT = $(round(ΔT[j], digits=1)) K", alpha=0.8) -end - -axislegend(axC, orientation=:horizontal, nbanks=2, label="navid") - -xlims!(axC, 0, 10) -ylims!(axC, 0, 4) - -fig -``` - -The coefficient-based formula then takes the form - -```math -u_\star = \sqrt{C_D | Δ \bm{u} | \, U} \\ -\theta_\star = \frac{C_θ}{\sqrt{C_D}} \, Δ θ \, \sqrt{\frac{U}{|Δ \bm{u} |}} \\ -q_\star = \frac{C_q}{\sqrt{C_D}} \, Δ q \, \sqrt{\frac{U}{| Δ \bm{u} |}} \\ -``` From 78de681a31db942db8e4f63e851d97f3c566b36a Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 20 Aug 2025 19:21:54 +0200 Subject: [PATCH 176/203] start with adapting --- CondaPkg.toml | 4 +- Manifest.toml | 10 +- anderson_acceleration.jl | 40 +++++ experiments/veros_forced_simulation.jl | 14 ++ .../ClimaOceanPythonCallExt.jl | 14 ++ .../clima_ocean_copernicus.jl} | 13 +- .../clima_ocean_veros.jl | 144 ++++++++++++++++++ .../veros_state_exchanger.jl | 84 ++++++++++ .../assemble_net_fluxes.jl | 16 +- .../atmosphere_ocean_fluxes.jl | 20 +-- .../component_interfaces.jl | 97 ++++++------ .../sea_ice_ocean_fluxes.jl | 23 ++- 12 files changed, 389 insertions(+), 90 deletions(-) create mode 100644 anderson_acceleration.jl create mode 100644 experiments/veros_forced_simulation.jl create mode 100644 ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl rename ext/{ClimaOceanPythonCallExt.jl => ClimaOceanPythonCallExt/clima_ocean_copernicus.jl} (93%) create mode 100644 ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl create mode 100644 ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl diff --git a/CondaPkg.toml b/CondaPkg.toml index dde757656..5bc3f6e47 100644 --- a/CondaPkg.toml +++ b/CondaPkg.toml @@ -1,7 +1,7 @@ [pip.deps] -copernicusmarine = ">=2.0.0" xarray = ">=2024.7.0" -numpy = ">=2.0.0" jax = ">=0.6" +copernicusmarine = ">=2.0.0" +numpy = "==2.3.1" tensorflow = ">=2.17" diff --git a/Manifest.toml b/Manifest.toml index e31e9c89a..a311a2040 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1164,9 +1164,9 @@ version = "0.4.6" [[deps.Roots]] deps = ["Accessors", "CommonSolve", "Printf"] -git-tree-sha1 = "668e411c0616a70860249b4c96e5d35296631a1d" +git-tree-sha1 = "dc84d966d3f6240657501da6d43b8448da19f71e" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.2.8" +version = "2.2.9" [deps.Roots.extensions] RootsChainRulesCoreExt = "ChainRulesCore" @@ -1174,6 +1174,7 @@ version = "2.2.8" RootsIntervalRootFindingExt = "IntervalRootFinding" RootsSymPyExt = "SymPy" RootsSymPyPythonCallExt = "SymPyPythonCall" + RootsUnitfulExt = "Unitful" [deps.Roots.weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" @@ -1181,6 +1182,7 @@ version = "2.2.8" 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"] @@ -1524,9 +1526,9 @@ version = "1.3.0+0" [[deps.libaec_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f5733a5a9047722470b95a81e1b172383971105c" +git-tree-sha1 = "1aa23f01927b2dac46db77a56b31088feee0a491" uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.1.3+0" +version = "1.1.4+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] diff --git a/anderson_acceleration.jl b/anderson_acceleration.jl new file mode 100644 index 000000000..5a916c46f --- /dev/null +++ b/anderson_acceleration.jl @@ -0,0 +1,40 @@ +f(x) = sin(x) + atan(x) +x0 = 1 + +k_max = 100 # Maximum number of iterations. +tol_res = 1e-6 # Tolerance on the residual. +m = 3 # Parameter m. + +x = [x0, f(x0)] # Vector of iterates x. +g = f(x) - x # Vector of residuals. + +G_k = g[2] - g[1] # Matrix of increments in residuals. +X_k = x[2] - x[1] # Matrix of increments in x. + +k = 2 +while k < k_max && abs(g[k]) > tol_res + m_k = min(k, m); + + # Solve the optimization problem by QR decomposition. + [Q, R] = qr(G_k) + gamma_k = R \ (Q' * g(k)) + + # Compute new iterate and new residual. + push!(x, x[k] + g[k] - (X_k + G_k) * gamma_k); + push!(g, f(x[k + 1]) - x[k + 1]); + + # Update increment matrices with new elements. + X_k = [X_k..., x[k + 1] - x[k]] + G_k = [G_k..., g[k + 1] - g[k]] + + n = size(X_k, 2) + if n > m_k + X_k = X_k[:, n - m_k + 1:end]; + G_k = G_k[:, n - m_k + 1:end]; + end + + k = k + 1; +end + +% Prints result: Computed fixed point 2.013444 after 9 iterations +fprintf("Computed fixed point %f after %d iterations\n", x(end), k); diff --git a/experiments/veros_forced_simulation.jl b/experiments/veros_forced_simulation.jl new file mode 100644 index 000000000..9b8e075eb --- /dev/null +++ b/experiments/veros_forced_simulation.jl @@ -0,0 +1,14 @@ +using ClimaOcean +using PythonCall +using Oceananigans + +VerosModule = Base.get_extension(ClimaOcean, :ClimaOceanPythonCallExt) +VerosModule.remove_outputs(:global_4deg) + +ocean = VerosModule.veros_ocean_simulation("global_4deg", :GlobalFourDegreeSetup) +VerosModule.veros_settings_set!(ocean, "dt_tracer", 1800.0) + +atmos = JRA55PrescribedAtmosphere(; backend = JRA55NetCDFBackend(10)) +radiation = Radiation() +coupled_model = OceanSeaIceModel(ocean, nothing; atmosphere=atmos, radiation) + diff --git a/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl b/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl new file mode 100644 index 000000000..ba0c007bf --- /dev/null +++ b/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl @@ -0,0 +1,14 @@ +module ClimaOceanPythonCallExt + +using ClimaOcean +using CondaPkg +using PythonCall +using Oceananigans +using Oceananigans.DistributedComputations: @root + +using Dates: DateTime + +include("clima_ocean_copernicus.jl") +include("clima_ocean_veros.jl") + +end # module ClimaOceanPythonCallExt diff --git a/ext/ClimaOceanPythonCallExt.jl b/ext/ClimaOceanPythonCallExt/clima_ocean_copernicus.jl similarity index 93% rename from ext/ClimaOceanPythonCallExt.jl rename to ext/ClimaOceanPythonCallExt/clima_ocean_copernicus.jl index 6d365bc87..d89ba3d67 100644 --- a/ext/ClimaOceanPythonCallExt.jl +++ b/ext/ClimaOceanPythonCallExt/clima_ocean_copernicus.jl @@ -1,12 +1,3 @@ -module ClimaOceanPythonCallExt - -using ClimaOcean -using CondaPkg -using PythonCall -using Oceananigans -using Oceananigans.DistributedComputations: @root - -using Dates: DateTime using ClimaOcean.DataWrangling.Copernicus: CopernicusMetadata import ClimaOcean.DataWrangling: download_dataset @@ -95,6 +86,4 @@ function depth_bounds_kw(z) minimum_depth = - z[2] maximum_depth = - z[1] return (; minimum_depth, maximum_depth) -end - -end # module ClimaOceanPythonCallExt +end \ No newline at end of file diff --git a/ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl b/ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl new file mode 100644 index 000000000..ccf386c95 --- /dev/null +++ b/ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl @@ -0,0 +1,144 @@ +using CondaPkg + +using ClimaOcean.OceanSeaIceModels: reference_density, heat_capacity, SeaIceSimulation + +import Oceananigans.Fields: set! +import Oceananigans.TimeSteppers: time_step! + +import ClimaOcean.OceanSeaIceModels: OceanSeaIceModel + +""" + install_veros() + +Install the Copernicus Marine CLI using CondaPkg. +Returns a NamedTuple containing package information if successful. +""" +function install_veros() + CondaPkg.add("veros"; channel = "conda-forge") + cli = CondaPkg.which("veros") + @info "... the veros CLI has been installed at $(cli)." + return cli +end + +struct VerosOceanSimulation{S} + setup :: S +end + +time_step!(sim::VerosOceanSimulation, Δt) = sim.setup.step() + +function remove_outputs(setup::Symbol) + rm("$(setup).averages.nc", force=true) + rm("$(setup).energy.nc", force=true) + rm("$(setup).overturning.nc", force=true) + rm("$(setup).snapshot.nc", force=true) + return nothing +end + +const Field2D = Field{<:Any, <:Any, <:Nothing} + +function set!(field::Field2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) + array = PyArray(pyarray) + Nx, Ny, Nz = size(array) + set!(field, view(array, 3:Nx-2, 3:Ny-2, k, 1)) + return field +end + +function veros_ocean_simulation(setup, setup_name) + setups = pyimport("veros.setups." * setup) + setup = @eval $setups.$setup_name() + + # instantiate the setup + setup.setup() + + return VerosOceanSimulation(setup) +end + +function surface_grid(setup::VerosOceanSimulation) + + xf = Array(PyArray(setup.state.variables.xu)) + yf = Array(PyArray(setup.state.variables.yu)) + + xc = Array(PyArray(setup.state.variables.xt)) + yc = Array(PyArray(setup.state.variables.yt)) + + xf = xf[2:end-2] + yf = yf[2:end-2] + + xc = xc[3:end-2] + yc = yc[3:end-2] + + xf[1] = xf[2] - 2xc[1] + yf[1] = sign(yf[2]) * (yf[2] - 2yc[1]) + + TX = if xf[1] == 0 && xf[end] == 360 + Periodic + else + Bounded + end + + Nx = length(xc) + Ny = length(yc) + + return LatitudeLongitudeGrid(size=(Nx, Ny), longitude=xf, latitude=yf, topology=(TX, Bounded, Flat)) +end + +function veros_set!(ocean::VerosOceanSimulation, v, x) + s = ocean.setup + pyexec(""" + with setup.state.variables.unlock(): + setup.state.variables.__setattr__(y, t) + """, Main, (y=v, t=x, setup=s)) +end + +function veros_settings_set!(ocean::VerosOceanSimulation, v, x) + s = ocean.setup + pyexec(""" + with setup.state.settings.unlock(): + setup.state.settings.__setattr__(y, t) + """, Main, (y=v, t=x, setup=s)) +end + +function OceanSeaIceModel(ocean::VerosOceanSimulation, sea_ice=nothing; + atmosphere = nothing, + radiation = Radiation(), + clock = Clock(time=0), + ocean_reference_density = 1020.0, + ocean_heat_capacity = 3998.0, + sea_ice_reference_density = reference_density(sea_ice), + sea_ice_heat_capacity = heat_capacity(sea_ice), + interfaces = nothing) + + if sea_ice isa SeaIceSimulation + if !isnothing(sea_ice.callbacks) + pop!(sea_ice.callbacks, :stop_time_exceeded, nothing) + pop!(sea_ice.callbacks, :stop_iteration_exceeded, nothing) + pop!(sea_ice.callbacks, :wall_time_limit_exceeded, nothing) + pop!(sea_ice.callbacks, :nan_checker, nothing) + end + end + + # Contains information about flux contributions: bulk formula, prescribed fluxes, etc. + if isnothing(interfaces) && !(isnothing(atmosphere) && isnothing(sea_ice)) + interfaces = ComponentInterfaces(atmosphere, ocean, sea_ice; + ocean_reference_density, + ocean_heat_capacity, + sea_ice_reference_density, + sea_ice_heat_capacity, + radiation) + end + + arch = CPU() + + ocean_sea_ice_model = OceanSeaIceModel(arch, + clock, + atmosphere, + sea_ice, + ocean, + interfaces) + + # Make sure the initial temperature of the ocean + # is not below freezing and above melting near the surface + initialization_update_state!(ocean_sea_ice_model) + + return ocean_sea_ice_model +end \ No newline at end of file diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl new file mode 100644 index 000000000..8cdf450f1 --- /dev/null +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -0,0 +1,84 @@ +import ClimaOcean.OceanSeaIceModels.InterfaceComputations: + state_exchanger, + sea_ice_ocean_interface, + atmosphere_ocean_interface, + initialize!, + get_ocean_state, + ocean_surface_fluxes, + get_radiative_forcing, + fill_up_net_fluxes! + + +mutable struct VerosStateExchanger{G, OST, AST, AEX} + exchange_grid :: G + exchange_ocean_state :: OST + exchange_atmosphere_state :: AST + atmosphere_exchanger :: AEX +end + +mutable struct ExchangeOceanState{FC, CF, CC} + u :: FC + v :: CF + T :: CC + S :: CC +end + +ExchangeOceanState(grid) = ExchangeOceanState(Field{Face, Center, Nothing}(grid), + Field{Center, Face, Nothing}(grid), + Field{Center, Center, Nothing}(grid), + Field{Center, Center, Nothing}(grid)) + +function state_exchanger(ocean::VerosOceanSimulation, atmosphere) + exchange_grid = surface_grid(ocean) + exchange_ocean_state = ExchangeOceanState(exchange_grid) + exchange_atmosphere_state = ExchangeAtmosphereState(exchange_grid) + + atmosphere_exchanger = AtmosphereExchanger(atmosphere, exchange_grid) + + return VerosStateExchanger(exchange_grid, + exchange_ocean_state, + exchange_atmosphere_state, + atmosphere_exchanger) +end + +atmosphere_ocean_interface(ocean::VerosOceanSimulation, args...) = + atmosphere_ocean_interface(surface_grid(ocean), args...) + +sea_ice_ocean_interface(ocean::VerosOceanSimulation, args...) = + sea_ice_ocean_interface(surface_grid(ocean), args...) + +initialize!(exchanger::VerosStateExchanger, atmosphere) = + initialize!(exchanger.atmosphere_exchanger, exchanger.exchange_grid, atmosphere) + +@inline function get_ocean_state(ocean::VerosOceanSimulation, exchanger::VerosStateExchanger) + u = exchanger.exchange_ocean_state.u + v = exchanger.exchange_ocean_state.v + T = exchanger.exchange_ocean_state.T + S = exchanger.exchange_ocean_state.S + + set!(u, ocean.setup.state.variables.u) + set!(v, ocean.setup.state.variables.v) + set!(T, ocean.setup.state.variables.temp) + set!(S, ocean.setup.state.variables.salt) + + return (; u, v, T, S) +end + +@inline function ocean_surface_fluxes(ocean::VerosOceanSimulation) + grid = surface_grid(ocean) + u = Field{Face, Center, Nothing}(grid) + v = Field{Center, Face, Nothing}(grid) + T = Field{Center, Center, Nothing}(grid) + S = Field{Center, Center, Nothing}(grid) + + return (; u, v, T, S) +end + +@inline get_radiative_forcing(ocean::VerosOceanSimulation) = nothing + +function fill_up_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) + veros_set!(ocean, "surface_taux", net_ocean_fluxes.u) + veros_set!(ocean, "surface_tauy", net_ocean_fluxes.v) + + return nothing +end \ No newline at end of file diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index dff50271b..69516f72b 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -21,18 +21,22 @@ using ClimaOcean.OceanSeaIceModels: sea_ice_concentration return zero(Iˢʷ) end -get_radiative_forcing(FT) = FT -function get_radiative_forcing(FT::MultipleForcings) +@inline get_radiative_forcing(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) = get_radiative_forcing(ocean.model.forcing.T) +@inline get_radiative_forcing(FT) = FT + +@inline function get_radiative_forcing(FT::MultipleForcings) for forcing in FT.forcings forcing isa TwoColorRadiation && return forcing end return nothing end +# No need to do this for an Oceananigans Simulation +fill_up_net_fluxes!(ocean, net_ocean_fluxes) = nothing + function compute_net_ocean_fluxes!(coupled_model) - ocean = coupled_model.ocean sea_ice = coupled_model.sea_ice - grid = ocean.model.grid + grid = coupled_model.exchanger.exchange_grid arch = architecture(grid) clock = coupled_model.clock @@ -62,7 +66,7 @@ function compute_net_ocean_fluxes!(coupled_model) kernel_parameters = interface_kernel_parameters(grid) ocean_surface_temperature = coupled_model.interfaces.atmosphere_ocean_interface.temperature - penetrating_radiation = get_radiative_forcing(ocean.model.forcing.T) + penetrating_radiation = get_radiative_forcing(ocean) launch!(arch, grid, kernel_parameters, _assemble_net_ocean_fluxes!, @@ -80,6 +84,8 @@ function compute_net_ocean_fluxes!(coupled_model) atmos_ocean_properties, ocean_properties) + fill_up_net_fluxes!(ocean, net_ocean_fluxes) + return nothing end diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl index 319ba5366..e082b14e1 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl @@ -4,19 +4,21 @@ using ClimaOcean.OceanSeaIceModels.PrescribedAtmospheres: thermodynamics_paramet surface_layer_height, boundary_layer_height -function compute_atmosphere_ocean_fluxes!(coupled_model) - ocean = coupled_model.ocean - atmosphere = coupled_model.atmosphere - grid = ocean.model.grid - arch = architecture(grid) - clock = coupled_model.clock - - ocean_state = (u = ocean.model.velocities.u, +@inline get_ocean_state(ocean::Simulation{<:HydrostaticFreeSurfaceModel}, coupled_model) = + (u = ocean.model.velocities.u, v = ocean.model.velocities.v, T = ocean.model.tracers.T, S = ocean.model.tracers.S) - atmosphere_fields = coupled_model.interfaces.exchanger.exchange_atmosphere_state +function compute_atmosphere_ocean_fluxes!(coupled_model) + ocean = coupled_model.ocean + atmosphere = coupled_model.atmosphere + exchanger = coupled_model.interfaces.exchanger + grid = exchanger.exchange_grid + arch = architecture(grid) + clock = coupled_model.clock + ocean_state = get_ocean_state(ocean, exchanger) + atmosphere_fields = exchanger.exchange_atmosphere_state # Simplify NamedTuple to reduce parameter space consumption. # See https://github.com/CliMA/ClimaOcean.jl/issues/116. diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index d32f21093..250e223fe 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -19,7 +19,7 @@ using ClimaSeaIce: SeaIceModel using Oceananigans.BuoyancyFormulations: g_Earth using Oceananigans: HydrostaticFreeSurfaceModel, architecture -using Oceananigans.Grids: inactive_node, node, topology +using Oceananigans.Grids: inactive_node, node, topology, AbstractGrid using Oceananigans.BoundaryConditions: fill_halo_regions! using Oceananigans.Fields: ConstantField, interpolate, FractionalIndices @@ -90,10 +90,9 @@ ExchangeAtmosphereState(grid) = ExchangeAtmosphereState(Field{Center, Center, No fractional_index_type(FT, Topo) = FT fractional_index_type(FT, ::Flat) = Nothing +state_exchanger(ocean::Simulation, ::Nothing) = nothing -StateExchanger(ocean::Simulation, ::Nothing) = nothing - -function StateExchanger(ocean::Simulation, atmosphere) +function state_exchanger(ocean::Simulation, atmosphere) # TODO: generalize this exchange_grid = ocean.model.grid exchange_atmosphere_state = ExchangeAtmosphereState(exchange_grid) @@ -120,12 +119,11 @@ function atmosphere_exchanger(atmosphere::PrescribedAtmosphere, exchange_grid) end initialize!(exchanger::StateExchanger, ::Nothing) = nothing +initialize!(exchanger::StateExchanger, atmosphere) = initialize!(exchanger.atmosphere_exchanger, exchanger.exchange_grid, atmosphere) -function initialize!(exchanger::StateExchanger, atmosphere) +function initialize!(frac_indices, exchange_grid::AbstractGrid, atmosphere) atmos_grid = atmosphere.grid - exchange_grid = exchanger.exchange_grid arch = architecture(exchange_grid) - frac_indices = exchanger.atmosphere_exchanger kernel_parameters = interface_kernel_parameters(exchange_grid) launch!(arch, exchange_grid, kernel_parameters, _compute_fractional_indices!, frac_indices, exchange_grid, atmos_grid) @@ -169,26 +167,28 @@ Base.summary(crf::ComponentInterfaces) = "ComponentInterfaces" Base.show(io::IO, crf::ComponentInterfaces) = print(io, summary(crf)) atmosphere_ocean_interface(::Nothing, args...) = nothing +atmosphere_ocean_interface(ocean::Simulation{<:HydrostaticFreeSurfaceModel}, args...) = + atmosphere_ocean_interface(ocean.model.grid, args...) -function atmosphere_ocean_interface(atmos, - ocean, +function atmosphere_ocean_interface(grid::AbstractGrid, + atmos, radiation, ao_flux_formulation, temperature_formulation, velocity_formulation, specific_humidity_formulation) - water_vapor = Field{Center, Center, Nothing}(ocean.model.grid) - latent_heat = Field{Center, Center, Nothing}(ocean.model.grid) - sensible_heat = Field{Center, Center, Nothing}(ocean.model.grid) - x_momentum = Field{Center, Center, Nothing}(ocean.model.grid) - y_momentum = Field{Center, Center, Nothing}(ocean.model.grid) - friction_velocity = Field{Center, Center, Nothing}(ocean.model.grid) - temperature_scale = Field{Center, Center, Nothing}(ocean.model.grid) - water_vapor_scale = Field{Center, Center, Nothing}(ocean.model.grid) - upwelling_longwave = Field{Center, Center, Nothing}(ocean.model.grid) - downwelling_longwave = Field{Center, Center, Nothing}(ocean.model.grid) - downwelling_shortwave = Field{Center, Center, Nothing}(ocean.model.grid) + water_vapor = Field{Center, Center, Nothing}(grid) + latent_heat = Field{Center, Center, Nothing}(grid) + sensible_heat = Field{Center, Center, Nothing}(grid) + x_momentum = Field{Center, Center, Nothing}(grid) + y_momentum = Field{Center, Center, Nothing}(grid) + friction_velocity = Field{Center, Center, Nothing}(grid) + temperature_scale = Field{Center, Center, Nothing}(grid) + water_vapor_scale = Field{Center, Center, Nothing}(grid) + upwelling_longwave = Field{Center, Center, Nothing}(grid) + downwelling_longwave = Field{Center, Center, Nothing}(grid) + downwelling_shortwave = Field{Center, Center, Nothing}(grid) ao_fluxes = (; latent_heat, sensible_heat, @@ -212,7 +212,7 @@ function atmosphere_ocean_interface(atmos, temperature_formulation, velocity_formulation) - interface_temperature = Field{Center, Center, Nothing}(ocean.model.grid) + interface_temperature = Field{Center, Center, Nothing}(grid) return AtmosphereInterface(ao_fluxes, ao_flux_formulation, interface_temperature, ao_properties) end @@ -254,16 +254,18 @@ function atmosphere_sea_ice_interface(atmos, return AtmosphereInterface(fluxes, ai_flux_formulation, interface_temperature, properties) end -sea_ice_ocean_interface(sea_ice, ocean) = nothing +sea_ice_ocean_interface(ocean, sea_ice) = nothing +sea_ice_ocean_interface(ocean, sea_ice::SeaIceSimulation; kw...) = + sea_ice_ocean_interface(ocean.grid, sea_ice; kw...) -function sea_ice_ocean_interface(sea_ice::SeaIceSimulation, ocean; +function sea_ice_ocean_interface(grid::AbstractGrid, sea_ice::SeaIceSimulation; characteristic_melting_speed = 1e-5) - io_bottom_heat_flux = Field{Center, Center, Nothing}(ocean.model.grid) - io_frazil_heat_flux = Field{Center, Center, Nothing}(ocean.model.grid) - io_salt_flux = Field{Center, Center, Nothing}(ocean.model.grid) - x_momentum = Field{Face, Center, Nothing}(ocean.model.grid) - y_momentum = Field{Center, Face, Nothing}(ocean.model.grid) + io_bottom_heat_flux = Field{Center, Center, Nothing}(grid) + io_frazil_heat_flux = Field{Center, Center, Nothing}(grid) + io_salt_flux = Field{Center, Center, Nothing}(grid) + x_momentum = Field{Face, Center, Nothing}(grid) + y_momentum = Field{Center, Face, Nothing}(grid) @assert io_frazil_heat_flux isa Field{Center, Center, Nothing} @assert io_bottom_heat_flux isa Field{Center, Center, Nothing} @@ -288,12 +290,25 @@ function default_ai_temperature(sea_ice::SeaIceSimulation) end function default_ao_specific_humidity(ocean) - FT = eltype(ocean.model.grid) + FT = Float64 phase = AtmosphericThermodynamics.Liquid() x_H₂O = convert(FT, 0.98) return ImpureSaturationSpecificHumidity(phase, x_H₂O) end +function ocean_surface_fluxes(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) + τx = surface_flux(ocean.model.velocities.u) + τy = surface_flux(ocean.model.velocities.v) + tracers = ocean.model.tracers + ρₒ = ocean_reference_density + cₒ = ocean_heat_capacity + Qₒ = ρₒ * cₒ * surface_flux(ocean.model.tracers.T) + net_ocean_surface_fluxes = (u=τx, v=τy, Q=Qₒ) + + ocean_surface_tracer_fluxes = NamedTuple(name => surface_flux(tracers[name]) for name in keys(tracers)) + return merge(ocean_surface_tracer_fluxes, net_ocean_surface_fluxes) +end + """ ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; radiation = Radiation(), @@ -314,8 +329,8 @@ end function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; radiation = Radiation(), freshwater_density = 1000, - atmosphere_ocean_fluxes = SimilarityTheoryFluxes(eltype(ocean.model.grid)), - atmosphere_sea_ice_fluxes = SimilarityTheoryFluxes(eltype(ocean.model.grid)), + atmosphere_ocean_fluxes = SimilarityTheoryFluxes(), + atmosphere_sea_ice_fluxes = SimilarityTheoryFluxes(), atmosphere_ocean_interface_temperature = BulkTemperature(), atmosphere_ocean_velocity_difference = RelativeVelocity(), atmosphere_ocean_interface_specific_humidity = default_ao_specific_humidity(ocean), @@ -329,8 +344,7 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; sea_ice_heat_capacity = heat_capacity(sea_ice), gravitational_acceleration = g_Earth) - ocean_grid = ocean.model.grid - FT = eltype(ocean_grid) + FT = Float64 ocean_reference_density = convert(FT, ocean_reference_density) ocean_heat_capacity = convert(FT, ocean_heat_capacity) @@ -346,8 +360,8 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; freshwater_density = freshwater_density, temperature_units = ocean_temperature_units) - ao_interface = atmosphere_ocean_interface(atmosphere, - ocean, + ao_interface = atmosphere_ocean_interface(ocean, + atmosphere, radiation, atmosphere_ocean_fluxes, atmosphere_ocean_interface_temperature, @@ -388,23 +402,14 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; net_bottom_sea_ice_fluxes = nothing end - τx = surface_flux(ocean.model.velocities.u) - τy = surface_flux(ocean.model.velocities.v) - tracers = ocean.model.tracers - ρₒ = ocean_reference_density - cₒ = ocean_heat_capacity - Qₒ = ρₒ * cₒ * surface_flux(ocean.model.tracers.T) - net_ocean_surface_fluxes = (u=τx, v=τy, Q=Qₒ) - - ocean_surface_tracer_fluxes = NamedTuple(name => surface_flux(tracers[name]) for name in keys(tracers)) - net_ocean_surface_fluxes = merge(ocean_surface_tracer_fluxes, net_ocean_surface_fluxes) + net_ocean_surface_fluxes = ocean_surface_fluxes(ocean) # Total interface fluxes net_fluxes = (ocean_surface = net_ocean_surface_fluxes, sea_ice_top = net_top_sea_ice_fluxes, sea_ice_bottom = net_bottom_sea_ice_fluxes) - exchanger = StateExchanger(ocean, atmosphere) + exchanger = state_exchanger(ocean, atmosphere) properties = (; gravitational_acceleration) diff --git a/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl index 8c0680963..3bcf2d545 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/sea_ice_ocean_fluxes.jl @@ -3,15 +3,15 @@ using ClimaSeaIce.SeaIceThermodynamics: melting_temperature using ClimaSeaIce.SeaIceDynamics: x_momentum_stress, y_momentum_stress function compute_sea_ice_ocean_fluxes!(coupled_model) - ocean = coupled_model.ocean - sea_ice = coupled_model.sea_ice + ocean = coupled_model.ocean + sea_ice = coupled_model.sea_ice + exchanger = coupled_model.interfaces.exchanger + ocean_state = get_ocean_state(ocean, coupled_model) sea_ice_ocean_fluxes = coupled_model.interfaces.sea_ice_ocean_interface.fluxes interface_properties = coupled_model.interfaces.sea_ice_ocean_interface.properties - Δt = ocean.Δt - Tₒ = ocean.model.tracers.T - Sₒ = ocean.model.tracers.S + Δt = sea_ice.Δt Sᵢ = sea_ice.model.tracers.S ℵᵢ = sea_ice.model.ice_concentration hᵢ = sea_ice.model.ice_thickness @@ -19,8 +19,8 @@ function compute_sea_ice_ocean_fluxes!(coupled_model) ocean_properties = coupled_model.interfaces.ocean_properties liquidus = sea_ice.model.ice_thermodynamics.phase_transitions.liquidus - grid = ocean.model.grid - clock = ocean.model.clock + grid = sea_ice.model.grid + clock = sea_ice.model.clock arch = architecture(grid) uᵢ, vᵢ = sea_ice.model.velocities @@ -35,7 +35,7 @@ function compute_sea_ice_ocean_fluxes!(coupled_model) # What about the latent heat removed from the ocean when ice forms? # Is it immediately removed from the ocean? Or is it stored in the ice? launch!(arch, grid, :xy, _compute_sea_ice_ocean_fluxes!, - sea_ice_ocean_fluxes, grid, clock, hᵢ, ℵᵢ, Sᵢ, Gh, Tₒ, Sₒ, uᵢ, vᵢ, + sea_ice_ocean_fluxes, grid, clock, hᵢ, ℵᵢ, Sᵢ, Gh, ocean_state, uᵢ, vᵢ, τs, liquidus, ocean_properties, interface_properties, Δt) return nothing @@ -48,8 +48,7 @@ end ice_concentration, ice_salinity, thermodynamic_tendency, - ocean_temperature, - ocean_salinity, + ocean_state, sea_ice_u_velocity, sea_ice_v_velocity, sea_ice_ocean_stresses, @@ -68,8 +67,8 @@ end τy = sea_ice_ocean_fluxes.y_momentum uᵢ = sea_ice_u_velocity vᵢ = sea_ice_v_velocity - Tₒ = ocean_temperature - Sₒ = ocean_salinity + Tₒ = ocean_state.T + Sₒ = ocean_state.S Sᵢ = ice_salinity hᵢ = ice_thickness ℵᵢ = ice_concentration From 3772b2c32b9b47c678aeeb1ac8fb353eeb231467 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 08:06:26 +0200 Subject: [PATCH 177/203] fill it in --- experiments/veros_forced_simulation.jl | 26 +++++++++++ .../ClimaOceanPythonCallExt.jl | 1 + .../clima_ocean_veros.jl | 46 ++++++++++++++----- .../veros_state_exchanger.jl | 29 +++++++++--- .../assemble_net_fluxes.jl | 8 ++-- .../interpolate_atmospheric_state.jl | 6 +-- src/OceanSeaIceModels/ocean_sea_ice_model.jl | 2 +- 7 files changed, 93 insertions(+), 25 deletions(-) diff --git a/experiments/veros_forced_simulation.jl b/experiments/veros_forced_simulation.jl index 9b8e075eb..53b190b0b 100644 --- a/experiments/veros_forced_simulation.jl +++ b/experiments/veros_forced_simulation.jl @@ -1,6 +1,7 @@ using ClimaOcean using PythonCall using Oceananigans +using Printf VerosModule = Base.get_extension(ClimaOcean, :ClimaOceanPythonCallExt) VerosModule.remove_outputs(:global_4deg) @@ -11,4 +12,29 @@ VerosModule.veros_settings_set!(ocean, "dt_tracer", 1800.0) atmos = JRA55PrescribedAtmosphere(; backend = JRA55NetCDFBackend(10)) radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, nothing; atmosphere=atmos, radiation) +simulation = Simulation(coupled_model; Δt = 1800, stop_iteration = 100) +wall_time = Ref(time_ns()) + +function progress(sim) + ocean = sim.model.ocean + umax = maximum(PyArray(ocean.setup.state.variables.u)) + vmax = maximum(PyArray(ocean.setup.state.variables.v)) + wmax = maximum(PyArray(ocean.setup.state.variables.w)) + + step_time = 1e-9 * (time_ns() - wall_time[]) + + msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) + msg5 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) + msg6 = @sprintf("wall time: %s \n", prettytime(step_time)) + + @info msg1 * msg5 * msg6 + + wall_time[] = time_ns() + + return nothing +end + +add_callback!(simulation, progress, IterationInterval(10)) + +run!(simulation) diff --git a/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl b/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl index ba0c007bf..b6bbb7844 100644 --- a/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl +++ b/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl @@ -10,5 +10,6 @@ using Dates: DateTime include("clima_ocean_copernicus.jl") include("clima_ocean_veros.jl") +include("veros_state_exchanger.jl") end # module ClimaOceanPythonCallExt diff --git a/ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl b/ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl index ccf386c95..8aabcc368 100644 --- a/ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl +++ b/ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl @@ -3,9 +3,12 @@ using CondaPkg using ClimaOcean.OceanSeaIceModels: reference_density, heat_capacity, SeaIceSimulation import Oceananigans.Fields: set! -import Oceananigans.TimeSteppers: time_step! +import Oceananigans.TimeSteppers: time_step!, initialize! -import ClimaOcean.OceanSeaIceModels: OceanSeaIceModel +import ClimaOcean.OceanSeaIceModels: OceanSeaIceModel, default_nan_checker +import Oceananigans.Architectures: architecture + +import Base: eltype """ install_veros() @@ -24,7 +27,12 @@ struct VerosOceanSimulation{S} setup :: S end -time_step!(sim::VerosOceanSimulation, Δt) = sim.setup.step() +default_nan_checker(model::OceanSeaIceModel{<:Any, <:Any, <:VerosOceanSimulation}) = nothing + +initialize!(::ClimaOceanPythonCallExt.VerosOceanSimulation{Py}) = nothing +time_step!(ocean::VerosOceanSimulation, Δt) = ocean.setup.step(ocean.setup.state) +architecture(model::OceanSeaIceModel{<:Any, <:Any, <:VerosOceanSimulation}) = CPU() +eltype(model::OceanSeaIceModel{<:Any, <:Any, <:VerosOceanSimulation}) = Float64 function remove_outputs(setup::Symbol) rm("$(setup).averages.nc", force=true) @@ -34,15 +42,31 @@ function remove_outputs(setup::Symbol) return nothing end -const Field2D = Field{<:Any, <:Any, <:Nothing} +const CCField2D = Field{<:Center, <:Center, <:Nothing} +const FCField2D = Field{<:Face, <:Center, <:Nothing} +const CFField2D = Field{<:Center, <:Face, <:Nothing} -function set!(field::Field2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) +function set!(field::CCField2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) array = PyArray(pyarray) Nx, Ny, Nz = size(array) set!(field, view(array, 3:Nx-2, 3:Ny-2, k, 1)) return field end +function set!(field::FCField2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) + array = PyArray(pyarray) + Nx, Ny, Nz = size(array) + set!(field, view(array, 3:Nx-2, 3:Ny-2, k, 1)) + return field +end + +function set!(field::CFField2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) + array = PyArray(pyarray) + Nx, Ny, Nz = size(array) + set!(field, view(array, 3:Nx-2, 2:Ny-2, k, 1)) + return field +end + function veros_ocean_simulation(setup, setup_name) setups = pyimport("veros.setups." * setup) setup = @eval $setups.$setup_name() @@ -53,13 +77,13 @@ function veros_ocean_simulation(setup, setup_name) return VerosOceanSimulation(setup) end -function surface_grid(setup::VerosOceanSimulation) +function surface_grid(ocean::VerosOceanSimulation) - xf = Array(PyArray(setup.state.variables.xu)) - yf = Array(PyArray(setup.state.variables.yu)) + xf = Array(PyArray(ocean.setup.state.variables.xu)) + yf = Array(PyArray(ocean.setup.state.variables.yu)) - xc = Array(PyArray(setup.state.variables.xt)) - yc = Array(PyArray(setup.state.variables.yt)) + xc = Array(PyArray(ocean.setup.state.variables.xt)) + yc = Array(PyArray(ocean.setup.state.variables.yt)) xf = xf[2:end-2] yf = yf[2:end-2] @@ -79,7 +103,7 @@ function surface_grid(setup::VerosOceanSimulation) Nx = length(xc) Ny = length(yc) - return LatitudeLongitudeGrid(size=(Nx, Ny), longitude=xf, latitude=yf, topology=(TX, Bounded, Flat)) + return LatitudeLongitudeGrid(size=(Nx, Ny), longitude=xf, latitude=yf, topology=(TX, Bounded, Flat), halo=(2, 2)) end function veros_set!(ocean::VerosOceanSimulation, v, x) diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index 8cdf450f1..ba62662b3 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -1,3 +1,10 @@ +using Oceananigans.Models: initialization_update_state! + +using ClimaOcean.OceanSeaIceModels.InterfaceComputations: ExchangeAtmosphereState, + atmosphere_exchanger, + SimilarityTheoryFluxes, + Radiation + import ClimaOcean.OceanSeaIceModels.InterfaceComputations: state_exchanger, sea_ice_ocean_interface, @@ -8,7 +15,6 @@ import ClimaOcean.OceanSeaIceModels.InterfaceComputations: get_radiative_forcing, fill_up_net_fluxes! - mutable struct VerosStateExchanger{G, OST, AST, AEX} exchange_grid :: G exchange_ocean_state :: OST @@ -33,12 +39,12 @@ function state_exchanger(ocean::VerosOceanSimulation, atmosphere) exchange_ocean_state = ExchangeOceanState(exchange_grid) exchange_atmosphere_state = ExchangeAtmosphereState(exchange_grid) - atmosphere_exchanger = AtmosphereExchanger(atmosphere, exchange_grid) + atmos_exchanger = atmosphere_exchanger(atmosphere, exchange_grid) return VerosStateExchanger(exchange_grid, exchange_ocean_state, exchange_atmosphere_state, - atmosphere_exchanger) + atmos_exchanger) end atmosphere_ocean_interface(ocean::VerosOceanSimulation, args...) = @@ -77,8 +83,19 @@ end @inline get_radiative_forcing(ocean::VerosOceanSimulation) = nothing function fill_up_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) - veros_set!(ocean, "surface_taux", net_ocean_fluxes.u) - veros_set!(ocean, "surface_tauy", net_ocean_fluxes.v) - + nx = pyconvert(Int, ocean.state.settings.nx) + ny = pyconvert(Int, ocean.state.settings.ny) + t1 = parent(net_ocean_fluxes.u)[:, 1:44, 1] + t2 = parent(net_ocean_fluxes.v)[:, 1:44, 1] + + ta = zeros(size(t1)..., 12) + tb = zeros(size(t2)..., 12) + for t in 1:12 + ta[:, :, t] .= t1 + tb[:, :, t] .= t2 + end + + veros_set!(ocean, "taux", ta) + veros_set!(ocean, "tauy", tb) return nothing end \ No newline at end of file diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index 69516f72b..b203ced62 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -36,7 +36,7 @@ fill_up_net_fluxes!(ocean, net_ocean_fluxes) = nothing function compute_net_ocean_fluxes!(coupled_model) sea_ice = coupled_model.sea_ice - grid = coupled_model.exchanger.exchange_grid + grid = coupled_model.interfaces.exchanger.exchange_grid arch = architecture(grid) clock = coupled_model.clock @@ -60,13 +60,13 @@ function compute_net_ocean_fluxes!(coupled_model) freshwater_flux = atmosphere_fields.Mp.data ice_concentration = sea_ice_concentration(sea_ice) - ocean_salinity = ocean.model.tracers.S + ocean_salinity = get_ocean_state(coupled_model.ocean, coupled_model.interfaces.exchanger).S atmos_ocean_properties = coupled_model.interfaces.atmosphere_ocean_interface.properties ocean_properties = coupled_model.interfaces.ocean_properties kernel_parameters = interface_kernel_parameters(grid) ocean_surface_temperature = coupled_model.interfaces.atmosphere_ocean_interface.temperature - penetrating_radiation = get_radiative_forcing(ocean) + penetrating_radiation = get_radiative_forcing(coupled_model.ocean) launch!(arch, grid, kernel_parameters, _assemble_net_ocean_fluxes!, @@ -84,7 +84,7 @@ function compute_net_ocean_fluxes!(coupled_model) atmos_ocean_properties, ocean_properties) - fill_up_net_fluxes!(ocean, net_ocean_fluxes) + fill_up_net_fluxes!(coupled_model.ocean, net_ocean_fluxes) return nothing end diff --git a/src/OceanSeaIceModels/InterfaceComputations/interpolate_atmospheric_state.jl b/src/OceanSeaIceModels/InterfaceComputations/interpolate_atmospheric_state.jl index 3c8ffa0b9..afd63817b 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/interpolate_atmospheric_state.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/interpolate_atmospheric_state.jl @@ -26,7 +26,7 @@ function interpolate_atmosphere_state!(interfaces, atmosphere::PrescribedAtmosph atmosphere_grid = atmosphere.grid # Basic model properties - grid = ocean.model.grid + grid = coupled_model.interfaces.exchanger.exchange_grid arch = architecture(grid) clock = coupled_model.clock @@ -125,8 +125,8 @@ function interpolate_atmosphere_state!(interfaces, atmosphere::PrescribedAtmosph # # TODO: find a better design for this that doesn't have redundant # arrays for the barotropic potential - u_potential = forcing_barotropic_potential(ocean.model.forcing.u) - v_potential = forcing_barotropic_potential(ocean.model.forcing.v) + u_potential = forcing_barotropic_potential(ocean) + v_potential = forcing_barotropic_potential(ocean) ρₒ = coupled_model.interfaces.ocean_properties.reference_density if !isnothing(u_potential) diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index 9a4cd0f7a..a99c3d550 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -45,7 +45,7 @@ function Base.show(io::IO, cm::OSIM) end print(io, summary(cm), "\n") - print(io, "├── ocean: ", summary(cm.ocean.model), "\n") + print(io, "├── ocean: ", summary(cm.ocean), "\n") print(io, "├── atmosphere: ", summary(cm.atmosphere), "\n") print(io, "├── sea_ice: ", sea_ice_summary, "\n") print(io, "└── interfaces: ", summary(cm.interfaces)) From b5befcd5c8eb8ee311c05b116e8cea025a18d3ac Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 08:07:11 +0200 Subject: [PATCH 178/203] remove manifest --- Manifest.toml | 1558 ------------------------------------------------- 1 file changed, 1558 deletions(-) delete mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index a311a2040..000000000 --- a/Manifest.toml +++ /dev/null @@ -1,1558 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.10.10" -manifest_format = "2.0" -project_hash = "f57e0b9bc9bbdd1cb6d317ebea00412e67510515" - -[[deps.AbstractFFTs]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" -uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.5.0" - - [deps.AbstractFFTs.extensions] - AbstractFFTsChainRulesCoreExt = "ChainRulesCore" - AbstractFFTsTestExt = "Test" - - [deps.AbstractFFTs.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "3b86719127f50670efe356bc11073d84b4ed7a5d" -uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.42" - - [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 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.3.0" -weakdeps = ["SparseArrays", "StaticArrays"] - - [deps.Adapt.extensions] - AdaptSparseArraysExt = "SparseArrays" - AdaptStaticArraysExt = "StaticArrays" - -[[deps.ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[deps.ArnoldiMethod]] -deps = ["LinearAlgebra", "Random", "StaticArrays"] -git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" -uuid = "ec485272-7323-5ecc-a04f-4719b315124d" -version = "0.4.0" - -[[deps.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.19.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = "CUDSS" - ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceSparseArraysExt = "SparseArrays" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - 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" - -[[deps.Atomix]] -deps = ["UnsafeAtomics"] -git-tree-sha1 = "29bb0eb6f578a587a49da16564705968667f5fa8" -uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" -version = "1.1.2" - - [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.BFloat16s]] -deps = ["LinearAlgebra", "Printf", "Random"] -git-tree-sha1 = "3b642331600250f592719140c60cf12372b82d66" -uuid = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" -version = "0.5.1" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[deps.BitFlags]] -git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.9" - -[[deps.BitTwiddlingConvenienceFunctions]] -deps = ["Static"] -git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" -uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" -version = "0.1.6" - -[[deps.Blosc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Lz4_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "535c80f1c0847a4c967ea945fca21becc9de1522" -uuid = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9" -version = "1.21.7+0" - -[[deps.Bzip2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" -uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.9+0" - -[[deps.CEnum]] -git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" -uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.5.0" - -[[deps.CFTime]] -deps = ["Dates", "Printf"] -git-tree-sha1 = "9b37e9e51aeea9763eea65b9b3aa1728fca94ffc" -uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.2.1" - -[[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", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "Requires", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] -git-tree-sha1 = "27f69b3923e58730f0a71396070e9114fc0bba40" -uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.8.3" - - [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", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "fdb9ddf3e08e2aca4c84b3252df2dea046caadee" -uuid = "d1e2174e-dfdc-576e-b43e-73b79eb1aca8" -version = "0.2.0+1" - -[[deps.CUDA_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "12621de83838b5ce6a185050db5a184f4540679b" -uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "13.0.0+0" - -[[deps.CUDA_Runtime_Discovery]] -deps = ["Libdl"] -git-tree-sha1 = "f9a521f52d236fe49f1028d69e549e7f2644bb72" -uuid = "1af6417a-86b4-443c-805f-a4643ffb695f" -version = "1.0.0" - -[[deps.CUDA_Runtime_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "cc727d90c9769db27945219f9ba149dbddc74f06" -uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.19.0+0" - -[[deps.ClimaSeaIce]] -deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "f5b45114d7c47faa799ac72cc0a07c1e86ac0e29" -repo-rev = "ss/omip-branch-2" -repo-url = "https://github.com/CliMA/ClimaSeaIce.jl.git" -uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.3.5" - -[[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" - - [deps.ColorTypes.extensions] - StyledStringsExt = "StyledStrings" - - [deps.ColorTypes.weakdeps] - StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" - -[[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", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "a4f9a314202585fcdce4f1a3c4b86ce988ce76b1" -uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.9" - -[[deps.CommonSolve]] -git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" -uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.4" - -[[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 = "0037835448781bb46feb39866934e243886d756a" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.18.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.1.1+0" - -[[deps.CompositionsBase]] -git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" -uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" -version = "0.1.2" -weakdeps = ["InverseFunctions"] - - [deps.CompositionsBase.extensions] - CompositionsBaseInverseFunctionsExt = "InverseFunctions" - -[[deps.ConcurrentUtilities]] -deps = ["Serialization", "Sockets"] -git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.5.0" - -[[deps.ConstructionBase]] -git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.6.0" - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseLinearAlgebraExt = "LinearAlgebra" - ConstructionBaseStaticArraysExt = "StaticArrays" - - [deps.ConstructionBase.weakdeps] - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.CpuId]] -deps = ["Markdown"] -git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" -uuid = "adafc99b-e345-5852-983c-f28acb93d879" -version = "0.3.1" - -[[deps.Crayons]] -git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" -uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" -version = "4.1.1" - -[[deps.CubedSphere]] -deps = ["TaylorSeries"] -git-tree-sha1 = "afe9e8c11bf816a6fee878ddfc661e0bd138b747" -uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.3.2" - -[[deps.CubicSplines]] -deps = ["Random", "Test"] -git-tree-sha1 = "4875023d456ea37c581f406b8b1bc35bea95ae67" -uuid = "9c784101-8907-5a6d-9be6-98f00873c89b" -version = "0.2.1" - -[[deps.DataAPI]] -git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.16.0" - -[[deps.DataDeps]] -deps = ["HTTP", "Libdl", "Reexport", "SHA", "Scratch", "p7zip_jll"] -git-tree-sha1 = "8ae085b71c462c2cb1cfedcb10c3c877ec6cf03f" -uuid = "124859b0-ceae-595e-8997-d05f6a7a8dfe" -version = "0.7.13" - -[[deps.DataFrames]] -deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "fb61b4812c49343d7ef0b533ba982c46021938a6" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.7.0" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.22" - -[[deps.DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[deps.DiffResults]] -deps = ["StaticArraysCore"] -git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "1.1.0" - -[[deps.DiffRules]] -deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.15.1" - -[[deps.DiskArrays]] -deps = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] -git-tree-sha1 = "bfde0790720fcac006a3d62149309a685fc3aa13" -uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.4.15" - -[[deps.Distances]] -deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.12" - - [deps.Distances.extensions] - DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesSparseArraysExt = "SparseArrays" - - [deps.Distances.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[deps.DocStringExtensions]] -git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.5" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.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 = "4a8c0a9eebf807ac42f0f6de758e60a20be25ffb" -uuid = "21656369-7473-754a-2065-74616d696c43" -version = "1.1.3" - -[[deps.FFTW]] -deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "797762812ed063b9b94f6cc7742bc8883bb5e69e" -uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.9.0" - -[[deps.FFTW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" -uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.11+0" - -[[deps.FileIO]] -deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "b66970a70db13f45b7e57fbda1736e1cf72174ea" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.17.0" -weakdeps = ["HTTP"] - - [deps.FileIO.extensions] - HTTPExt = "HTTP" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[deps.FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.5" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.0.1" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[deps.GPUArrays]] -deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "Statistics"] -git-tree-sha1 = "be941842a40b6daac98496994ea69054ba4c5144" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "11.2.3" - -[[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 = "eb1e212e12cc058fa16712082d44be499d23638c" -uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "1.6.1" - -[[deps.GPUToolbox]] -deps = ["LLVM"] -git-tree-sha1 = "5bfe837129bf49e2e049b4f1517546055cc16a93" -uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" -version = "0.3.0" - -[[deps.Glob]] -git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" -uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" -version = "1.3.1" - -[[deps.Graphs]] -deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "7a98c6502f4632dbe9fb1973a4244eaa3324e84d" -uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" -version = "1.13.1" - -[[deps.HDF5_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "OpenSSL_jll", "TOML", "Zlib_jll", "libaec_jll"] -git-tree-sha1 = "e94f84da9af7ce9c6be049e9067e511e17ff89ec" -uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" -version = "1.14.6+0" - -[[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "ed5e9c58612c4e081aecdb6e1a479e18462e041e" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.17" - -[[deps.HashArrayMappedTries]] -git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" -uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" -version = "0.2.0" - -[[deps.HostCPUFeatures]] -deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] -git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" -uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.17" - -[[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.12.1+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 = "cffa21df12f00ca1a365eb8ed107614b40e8c6da" -uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" -version = "0.4.6" - -[[deps.Inflate]] -git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.5" - -[[deps.InlineStrings]] -git-tree-sha1 = "8594fac023c5ce1ef78260f24d1ad18b4327b420" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.4" - - [deps.InlineStrings.extensions] - ArrowTypesExt = "ArrowTypes" - ParsersExt = "Parsers" - - [deps.InlineStrings.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" - -[[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "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" - -[[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 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.4" - -[[deps.IterativeSolvers]] -deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] -git-tree-sha1 = "59545b0a2b27208b0650df0a46b8e3019f85055b" -uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" -version = "0.9.4" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] -git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.5.15" -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.JuliaNVTXCallbacks_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "af433a10f3942e882d3c671aacb203e006a5808f" -uuid = "9c1d0b0a-7046-5b2e-a33f-ea22f176ac7e" -version = "0.2.1+0" - -[[deps.KernelAbstractions]] -deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] -git-tree-sha1 = "83c617e9e9b02306a7acab79e05ec10253db7c87" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.38" - - [deps.KernelAbstractions.extensions] - EnzymeExt = "EnzymeCore" - LinearAlgebraExt = "LinearAlgebra" - SparseArraysExt = "SparseArrays" - - [deps.KernelAbstractions.weakdeps] - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[deps.Krylov]] -deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "b94257a1a8737099ca40bc7271a8b374033473ed" -uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.10.1" - -[[deps.KrylovPreconditioners]] -deps = ["Adapt", "Graphs", "KernelAbstractions", "LinearAlgebra", "Metis", "SparseArrays"] -git-tree-sha1 = "77e0d2f1a250af347261c9aa89f74b0cfc530a71" -uuid = "45d422c2-293f-44ce-8315-2cb988662dec" -version = "0.3.6" - - [deps.KrylovPreconditioners.extensions] - KrylovPreconditionersAMDGPUExt = "AMDGPU" - KrylovPreconditionersCUDAExt = "CUDA" - KrylovPreconditionersOneAPIExt = "oneAPI" - - [deps.KrylovPreconditioners.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" - -[[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] -git-tree-sha1 = "9c7c721cfd800d87d48c745d8bfb65144f0a91df" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "9.4.2" -weakdeps = ["BFloat16s"] - - [deps.LLVM.extensions] - BFloat16sExt = "BFloat16s" - -[[deps.LLVMExtra_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "2ea068aac1e7f0337d381b0eae3110581e3f3216" -uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.37+2" - -[[deps.LLVMLoopInfo]] -git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" -uuid = "8b046642-f1f6-4319-8d3c-209ddc03c586" -version = "1.0.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" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.4.0+0" - -[[deps.LibGit2]] -deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.6.4+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" - -[[deps.LibTracyClient_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d2bc4e1034b2d43076b50f0e34ea094c2cb0a717" -uuid = "ad6e5548-8b26-5c9f-8ef3-ef0ad883f3a5" -version = "0.9.1+6" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[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" - -[[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" - -[[deps.LoggingExtras]] -deps = ["Dates", "Logging"] -git-tree-sha1 = "f02b56007b064fbfddb4c9cd60161b6dd0f40df3" -uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.1.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 = "e5afce7eaf5b5ca0d444bcb4dc4fd78c54cbbac0" -uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.172" - - [deps.LoopVectorization.extensions] - ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] - SpecialFunctionsExt = "SpecialFunctions" - - [deps.LoopVectorization.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.Lz4_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "191686b1ac1ea9c89fc52e996ad15d1d241d1e33" -uuid = "5ced341a-0733-55b8-9ab6-a4889d929147" -version = "1.10.1+0" - -[[deps.METIS_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2eefa8baa858871ae7770c98c3c2a7e46daba5b4" -uuid = "d00139f3-1899-568f-a2f0-47f597d42d70" -version = "5.1.3+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", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "PkgVersion", "PrecompileTools", "Requires", "Serialization", "Sockets"] -git-tree-sha1 = "a61ecf714d71064b766d481ef43c094d4c6e3c52" -uuid = "da04e1cc-30fd-572f-bb4f-1f8673147195" -version = "0.20.23" - - [deps.MPI.extensions] - AMDGPUExt = "AMDGPU" - CUDAExt = "CUDA" - - [deps.MPI.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - -[[deps.MPICH_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "d72d0ecc3f76998aac04e446547259b9ae4c265f" -uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4" -version = "4.3.1+0" - -[[deps.MPIPreferences]] -deps = ["Libdl", "Preferences"] -git-tree-sha1 = "c105fe467859e7f6e9a852cb15cb4301126fac07" -uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" -version = "0.1.11" - -[[deps.MPItrampoline_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML"] -git-tree-sha1 = "e214f2a20bdd64c04cd3e4ff62d3c9be7e969a59" -uuid = "f1f71cc9-e9ae-5b93-9b94-4fe0e1ad3748" -version = "5.5.4+0" - -[[deps.MacroTools]] -git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.16" - -[[deps.ManualMemory]] -git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" -uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" -version = "0.1.8" - -[[deps.MappedArrays]] -git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" -uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" -version = "0.4.2" - -[[deps.Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.9" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+1" - -[[deps.Metis]] -deps = ["CEnum", "LinearAlgebra", "METIS_jll", "SparseArrays"] -git-tree-sha1 = "54aca4fd53d39dcd2c3f1bef367b6921e8178628" -uuid = "2679e427-3c69-5b7f-982b-ece356f1e94b" -version = "1.5.0" - - [deps.Metis.extensions] - MetisGraphs = "Graphs" - MetisLightGraphs = "LightGraphs" - MetisSimpleWeightedGraphs = ["SimpleWeightedGraphs", "Graphs"] - - [deps.Metis.weakdeps] - Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" - LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" - SimpleWeightedGraphs = "47aef6b3-ad0c-573a-a1e2-d07658019622" - -[[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" - -[[deps.MosaicViews]] -deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] -git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" -uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" -version = "0.3.4" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.1.10" - -[[deps.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 = "be1095e2b767c19529409ec670bcfb01b825d717" -uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.8" - -[[deps.NVTX]] -deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] -git-tree-sha1 = "6b573a3e66decc7fc747afd1edbf083ff78c813a" -uuid = "5da4648a-3479-48b8-97b9-01cb529c0a1f" -version = "1.0.1" - -[[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.NetCDF_jll]] -deps = ["Artifacts", "Blosc_jll", "Bzip2_jll", "HDF5_jll", "JLLWrappers", "LazyArtifacts", "LibCURL_jll", "Libdl", "MPICH_jll", "MPIPreferences", "MPItrampoline_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "TOML", "XML2_jll", "Zlib_jll", "Zstd_jll", "libaec_jll", "libzip_jll"] -git-tree-sha1 = "d574803b6055116af212434460adf654ce98e345" -uuid = "7243133f-43d8-5620-bbf4-c2c921802cf3" -version = "401.900.300+0" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[deps.Oceananigans]] -deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "IterativeSolvers", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "e5f3d3ec8343b3e0f7434f8d7b590a7d7f94fde8" -repo-rev = "ss/omip-branch-2" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" -uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.97.7" - - [deps.Oceananigans.extensions] - OceananigansAMDGPUExt = "AMDGPU" - OceananigansCUDAExt = "CUDA" - OceananigansEnzymeExt = "Enzyme" - OceananigansMakieExt = ["MakieCore", "Makie"] - OceananigansMetalExt = "Metal" - OceananigansNCDatasetsExt = "NCDatasets" - OceananigansOneAPIExt = "oneAPI" - OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase"] - - [deps.Oceananigans.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" - Metal = "dde4c033-4e86-420c-a63e-0dd931031962" - NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" - Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" - 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.23+4" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.5+0" - -[[deps.OpenMPI_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] -git-tree-sha1 = "ec764453819f802fc1e144bfe750c454181bd66d" -uuid = "fe0851c0-eecd-5654-98d4-656369965a5c" -version = "5.0.8+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.5.0" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2ae7d4ddec2e13ad3bddf5c0796f7547cf682391" -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.2+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.PaddedViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" -uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" -version = "0.5.12" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.10.0" - -[[deps.PkgVersion]] -deps = ["Pkg"] -git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" -uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" -version = "0.3.3" - -[[deps.PolyesterWeave]] -deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] -git-tree-sha1 = "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 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.1" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.5.0" - -[[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34" -uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.4.0" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[deps.Quaternions]] -deps = ["LinearAlgebra", "Random", "RealDot"] -git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" -uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" -version = "0.7.6" - -[[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[deps.Random123]] -deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "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.ReactantCore]] -deps = ["ExpressionExplorer", "MacroTools"] -git-tree-sha1 = "120feaf6a97738e3a63902644a0afb3b69cc7b98" -uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" -version = "0.1.15" - -[[deps.RealDot]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" -uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" -version = "0.1.0" - -[[deps.RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.1" - -[[deps.RootSolvers]] -deps = ["ForwardDiff", "Printf"] -git-tree-sha1 = "769388dbf7656e70f6ee250f35bb6cbca8f43203" -uuid = "7181ea78-2dcb-4de3-ab41-2b8ab5a31e74" -version = "0.4.6" - -[[deps.Roots]] -deps = ["Accessors", "CommonSolve", "Printf"] -git-tree-sha1 = "dc84d966d3f6240657501da6d43b8448da19f71e" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.2.9" - - [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" -weakdeps = ["RecipesBase"] - - [deps.Rotations.extensions] - RotationsRecipesBaseExt = "RecipesBase" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.SIMDTypes]] -git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" -uuid = "94e857df-77ce-4151-89e5-788b33177be4" -version = "0.1.0" - -[[deps.SLEEFPirates]] -deps = ["IfElse", "Static", "VectorizationBase"] -git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" -uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" -version = "0.6.43" - -[[deps.ScopedValues]] -deps = ["HashArrayMappedTries", "Logging"] -git-tree-sha1 = "7f44eef6b1d284465fafc66baf4d9bdcc239a15b" -uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" -version = "1.4.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 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" -uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.8" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[deps.SimpleBufferStream]] -git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.2.0" - -[[deps.SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "be8eeac05ec97d379347584fa9fe2f5f76795bcb" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.5" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[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.10.0" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.5.1" - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - - [deps.SpecialFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - -[[deps.StackViews]] -deps = ["OffsetArrays"] -git-tree-sha1 = "be1cf4eb0ac528d96f5115b4ed80c26a8d8ae621" -uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" -version = "0.1.2" - -[[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] -git-tree-sha1 = "f737d444cb0ad07e61b3c1bef8eb91203c321eff" -uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.2.0" - -[[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] -git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" -uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.8.0" -weakdeps = ["OffsetArrays", "StaticArrays"] - - [deps.StaticArrayInterface.extensions] - StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" - StaticArrayInterfaceStaticArraysExt = "StaticArrays" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "cbea8a6bd7bed51b1619658dec70035e07b8502f" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.14" - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - - [deps.StaticArrays.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.3" - -[[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.1" - -[[deps.StringManipulation]] -deps = ["PrecompileTools"] -git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023" -uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.4.1" - -[[deps.StructArrays]] -deps = ["ConstructionBase", "DataAPI", "Tables"] -git-tree-sha1 = "8ad2e38cbb812e29348719cc63580ec1dfeb9de4" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.7.1" -weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"] - - [deps.StructArrays.extensions] - StructArraysAdaptExt = "Adapt" - StructArraysGPUArraysCoreExt = ["GPUArraysCore", "KernelAbstractions"] - StructArraysLinearAlgebraExt = "LinearAlgebra" - StructArraysSparseArraysExt = "SparseArrays" - StructArraysStaticArraysExt = "StaticArrays" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" - -[[deps.SurfaceFluxes]] -deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "eb96fea9de18a3935a836ee8634af3c126d6b77f" -uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.12.1" - - [deps.SurfaceFluxes.extensions] - CreateParametersExt = "ClimaParams" - - [deps.SurfaceFluxes.weakdeps] - ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "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 = "2c308aab2e14b399e4b8d6af7c486a241c8ca87a" -uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.19.1" - - [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" - -[[deps.Thermodynamics]] -deps = ["DocStringExtensions", "ForwardDiff", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "edce99e94489c25f5c7f5b4065c06ffb5adb1317" -uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.13.1" - - [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 = "91dbaee0f50faa4357f7e9fc69442c7b6364dfe5" -uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" -version = "0.1.5" - - [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" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[deps.UnsafeAtomics]] -git-tree-sha1 = "b13c4edda90890e5b04ba24e20a310fbe6f249ff" -uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" -version = "0.3.0" -weakdeps = ["LLVM"] - - [deps.UnsafeAtomics.extensions] - UnsafeAtomicsLLVM = ["LLVM"] - -[[deps.VectorizationBase]] -deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "4ab62a49f1d8d9548a1c8d1a75e5f55cf196f64e" -uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.71" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "b8b243e47228b4a3877f1dd6aee0c5d56db7fcf4" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.6+1" - -[[deps.XZ_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" -uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.8.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.2.13+1" - -[[deps.Zstd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.7+1" - -[[deps.demumble_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6498e3581023f8e530f34760d18f75a69e3a4ea8" -uuid = "1e29f10c-031c-5a83-9565-69cddfc27673" -version = "1.3.0+0" - -[[deps.libaec_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1aa23f01927b2dac46db77a56b31088feee0a491" -uuid = "477f73a3-ac25-53e9-8cc3-50b2fa2566f0" -version = "1.1.4+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.11.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.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" - -[[deps.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2022.0.0+0" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+2" From 1a404289acc431bf502704c48115134ab6aaa040 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 08:07:47 +0200 Subject: [PATCH 179/203] remove vestigial code --- anderson_acceleration.jl | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 anderson_acceleration.jl diff --git a/anderson_acceleration.jl b/anderson_acceleration.jl deleted file mode 100644 index 5a916c46f..000000000 --- a/anderson_acceleration.jl +++ /dev/null @@ -1,40 +0,0 @@ -f(x) = sin(x) + atan(x) -x0 = 1 - -k_max = 100 # Maximum number of iterations. -tol_res = 1e-6 # Tolerance on the residual. -m = 3 # Parameter m. - -x = [x0, f(x0)] # Vector of iterates x. -g = f(x) - x # Vector of residuals. - -G_k = g[2] - g[1] # Matrix of increments in residuals. -X_k = x[2] - x[1] # Matrix of increments in x. - -k = 2 -while k < k_max && abs(g[k]) > tol_res - m_k = min(k, m); - - # Solve the optimization problem by QR decomposition. - [Q, R] = qr(G_k) - gamma_k = R \ (Q' * g(k)) - - # Compute new iterate and new residual. - push!(x, x[k] + g[k] - (X_k + G_k) * gamma_k); - push!(g, f(x[k + 1]) - x[k + 1]); - - # Update increment matrices with new elements. - X_k = [X_k..., x[k + 1] - x[k]] - G_k = [G_k..., g[k + 1] - g[k]] - - n = size(X_k, 2) - if n > m_k - X_k = X_k[:, n - m_k + 1:end]; - G_k = G_k[:, n - m_k + 1:end]; - end - - k = k + 1; -end - -% Prints result: Computed fixed point 2.013444 after 9 iterations -fprintf("Computed fixed point %f after %d iterations\n", x(end), k); From 0876b41562cdf59914daa1c2fab4d15ee64224de Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 08:11:31 +0200 Subject: [PATCH 180/203] add a simulation --- .../InterfaceComputations/assemble_net_fluxes.jl | 2 +- .../InterfaceComputations/atmosphere_ocean_fluxes.jl | 2 +- .../InterfaceComputations/component_interfaces.jl | 4 ++-- src/OceanSeaIceModels/OceanSeaIceModels.jl | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index b203ced62..fca4ad5ec 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -21,7 +21,7 @@ using ClimaOcean.OceanSeaIceModels: sea_ice_concentration return zero(Iˢʷ) end -@inline get_radiative_forcing(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) = get_radiative_forcing(ocean.model.forcing.T) +@inline get_radiative_forcing(ocean::OceananigansSimulation) = get_radiative_forcing(ocean.model.forcing.T) @inline get_radiative_forcing(FT) = FT @inline function get_radiative_forcing(FT::MultipleForcings) diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl index e082b14e1..041e81a43 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl @@ -4,7 +4,7 @@ using ClimaOcean.OceanSeaIceModels.PrescribedAtmospheres: thermodynamics_paramet surface_layer_height, boundary_layer_height -@inline get_ocean_state(ocean::Simulation{<:HydrostaticFreeSurfaceModel}, coupled_model) = +@inline get_ocean_state(ocean::OceananigansSimulation, coupled_model) = (u = ocean.model.velocities.u, v = ocean.model.velocities.v, T = ocean.model.tracers.T, diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index 250e223fe..8a043fc83 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -167,7 +167,7 @@ Base.summary(crf::ComponentInterfaces) = "ComponentInterfaces" Base.show(io::IO, crf::ComponentInterfaces) = print(io, summary(crf)) atmosphere_ocean_interface(::Nothing, args...) = nothing -atmosphere_ocean_interface(ocean::Simulation{<:HydrostaticFreeSurfaceModel}, args...) = +atmosphere_ocean_interface(ocean::OceananigansSimulation, args...) = atmosphere_ocean_interface(ocean.model.grid, args...) function atmosphere_ocean_interface(grid::AbstractGrid, @@ -296,7 +296,7 @@ function default_ao_specific_humidity(ocean) return ImpureSaturationSpecificHumidity(phase, x_H₂O) end -function ocean_surface_fluxes(ocean::Simulation{<:HydrostaticFreeSurfaceModel}) +function ocean_surface_fluxes(ocean::OceananigansSimulation) τx = surface_flux(ocean.model.velocities.u) τy = surface_flux(ocean.model.velocities.v) tracers = ocean.model.tracers diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index d44f7429d..2edbf3dc1 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -41,6 +41,7 @@ const default_gravitational_acceleration = 9.80665 const default_freshwater_density = 1000 const SeaIceSimulation = Simulation{<:SeaIceModel} +const OceananigansSimulation = Simulation{<:HydrostaticFreeSurfaceModel} sea_ice_thickness(::Nothing) = ZeroField() sea_ice_thickness(sea_ice::SeaIceSimulation) = sea_ice.model.ice_thickness From dc79dc0677a875a4387ac015f67dea7fd52b1d73 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 08:15:34 +0200 Subject: [PATCH 181/203] add an OceananigansSimulation --- .../InterfaceComputations/component_interfaces.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index 8a043fc83..76ce1797a 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -9,7 +9,8 @@ using ..OceanSeaIceModels: reference_density, sea_ice_thickness, downwelling_radiation, freshwater_flux, - SeaIceSimulation + SeaIceSimulation, + OceananigansSimulation using ..OceanSeaIceModels.PrescribedAtmospheres: PrescribedAtmosphere, From adb839305a1d24ffcf3f44d8d2b77c6c7d8a6d08 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 08:21:11 +0200 Subject: [PATCH 182/203] ok this works --- ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index ba62662b3..f696c5193 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -83,8 +83,8 @@ end @inline get_radiative_forcing(ocean::VerosOceanSimulation) = nothing function fill_up_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) - nx = pyconvert(Int, ocean.state.settings.nx) - ny = pyconvert(Int, ocean.state.settings.ny) + nx = pyconvert(Int, ocean.setup.state.settings.nx) + ny = pyconvert(Int, ocean.setup.state.settings.ny) t1 = parent(net_ocean_fluxes.u)[:, 1:44, 1] t2 = parent(net_ocean_fluxes.v)[:, 1:44, 1] From ff570904b3d9f2a5c7ff2c3b6f13add0c4bdcfc3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 08:44:06 +0200 Subject: [PATCH 183/203] add a forced simulation --- experiments/veros_forced_simulation.jl | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/experiments/veros_forced_simulation.jl b/experiments/veros_forced_simulation.jl index 53b190b0b..3a6cc7403 100644 --- a/experiments/veros_forced_simulation.jl +++ b/experiments/veros_forced_simulation.jl @@ -12,10 +12,19 @@ VerosModule.veros_settings_set!(ocean, "dt_tracer", 1800.0) atmos = JRA55PrescribedAtmosphere(; backend = JRA55NetCDFBackend(10)) radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, nothing; atmosphere=atmos, radiation) -simulation = Simulation(coupled_model; Δt = 1800, stop_iteration = 100) +simulation = Simulation(coupled_model; Δt = 1800, stop_iteration = 100000) wall_time = Ref(time_ns()) +s = [] +tx = [] +ty = [] + +us = coupled_model.interfaces.exchanger.exchange_ocean_state.u +vs = coupled_model.interfaces.exchanger.exchange_ocean_state.v + +stmp = Field(sqrt(us^2 + vs^2)) + function progress(sim) ocean = sim.model.ocean umax = maximum(PyArray(ocean.setup.state.variables.u)) @@ -30,11 +39,16 @@ function progress(sim) @info msg1 * msg5 * msg6 - wall_time[] = time_ns() + wall_time[] = time_ns() + + compute!(stmp) + push!(s, deepcopy(interior(stmp, :, :, 1))) + push!(tx, deepcopy(interior(coupled_model.interfaces.net_fluxes.ocean_surface.u, :, :, 1) .* 1020)) + push!(ty, deepcopy(interior(coupled_model.interfaces.net_fluxes.ocean_surface.v, :, :, 1) .* 1020)) - return nothing + return nothing end -add_callback!(simulation, progress, IterationInterval(10)) +add_callback!(simulation, progress, IterationInterval(5)) run!(simulation) From 2460b14699d54f623fa61857b3a28e181880df59 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 08:46:58 +0200 Subject: [PATCH 184/203] update --- ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl | 2 +- .../{clima_ocean_veros.jl => veros_ocean_simulation.jl} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename ext/ClimaOceanPythonCallExt/{clima_ocean_veros.jl => veros_ocean_simulation.jl} (100%) diff --git a/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl b/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl index b6bbb7844..0d0feabae 100644 --- a/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl +++ b/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl @@ -9,7 +9,7 @@ using Oceananigans.DistributedComputations: @root using Dates: DateTime include("clima_ocean_copernicus.jl") -include("clima_ocean_veros.jl") +include("veros_ocean_simulation.jl") include("veros_state_exchanger.jl") end # module ClimaOceanPythonCallExt diff --git a/ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl similarity index 100% rename from ext/ClimaOceanPythonCallExt/clima_ocean_veros.jl rename to ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl From b74450f57e7daa16c2f3405325c6f61f8768ef57 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 08:56:04 +0200 Subject: [PATCH 185/203] coupled --- .../veros_ocean_simulation.jl | 9 +++++--- .../veros_state_exchanger.jl | 21 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl index 8aabcc368..0b5c9f66a 100644 --- a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl +++ b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl @@ -1,5 +1,6 @@ using CondaPkg +using Oceananigans.Grids: topology using ClimaOcean.OceanSeaIceModels: reference_density, heat_capacity, SeaIceSimulation import Oceananigans.Fields: set! @@ -43,10 +44,10 @@ function remove_outputs(setup::Symbol) end const CCField2D = Field{<:Center, <:Center, <:Nothing} -const FCField2D = Field{<:Face, <:Center, <:Nothing} +const FCField2D = Field{<:Face, <:Center, <:Nothing} const CFField2D = Field{<:Center, <:Face, <:Nothing} -function set!(field::CCField2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) +function set!(field::Field2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) array = PyArray(pyarray) Nx, Ny, Nz = size(array) set!(field, view(array, 3:Nx-2, 3:Ny-2, k, 1)) @@ -56,7 +57,9 @@ end function set!(field::FCField2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) array = PyArray(pyarray) Nx, Ny, Nz = size(array) - set!(field, view(array, 3:Nx-2, 3:Ny-2, k, 1)) + TX, TY, _ = topology(field.grid) + i_indices = TX == Periodic ? UnitRange(3, Nx-2) : UnitRange(2, Nx-2) + set!(field, view(array, i_indices, 3:Ny-2, k, 1)) return field end diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index f696c5193..989f7432a 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -83,11 +83,13 @@ end @inline get_radiative_forcing(ocean::VerosOceanSimulation) = nothing function fill_up_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) - nx = pyconvert(Int, ocean.setup.state.settings.nx) - ny = pyconvert(Int, ocean.setup.state.settings.ny) - t1 = parent(net_ocean_fluxes.u)[:, 1:44, 1] - t2 = parent(net_ocean_fluxes.v)[:, 1:44, 1] + nx = pyconvert(Int, ocean.setup.state.settings.nx) + 4 + ny = pyconvert(Int, ocean.setup.state.settings.ny) + 4 + t1 = view(parent(net_ocean_fluxes.u), 1:nx, 1:ny, 1) + t2 = view(parent(net_ocean_fluxes.v), 1:nx, 1:ny, 1) + # TODO: Remove this when they fix veros to + # be able to force with an array instead of Climatology ta = zeros(size(t1)..., 12) tb = zeros(size(t2)..., 12) for t in 1:12 @@ -97,5 +99,16 @@ function fill_up_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) veros_set!(ocean, "taux", ta) veros_set!(ocean, "tauy", tb) + + # TODO: Add heat flux and salinity flux when they + # fix veros to be able to force with prescribed boundary + # conditions rather than restoring + + # t1 = view(parent(net_ocean_fluxes.T), 1:nx, 2:ny+1, 1) + # t2 = view(parent(net_ocean_fluxes.S), 1:nx, 2:ny+1, 1) + + # veros_set!(ocean, "temp_flux", t1) + # veros_set!(ocean, "salt_flux", t2) + return nothing end \ No newline at end of file From 779299043c7178dc913f42240658afc8e519736c Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 09:00:55 +0200 Subject: [PATCH 186/203] some corrections --- .../JRA55/JRA55_field_time_series.jl | 3 +- src/InitialConditions/InitialConditions.jl | 40 ++++++++++++++++++- .../atmosphere_sea_ice_fluxes.jl | 4 +- .../component_interfaces.jl | 4 +- src/OceanSeaIceModels/OceanSeaIceModels.jl | 2 + src/OceanSeaIceModels/ocean_sea_ice_model.jl | 2 + 6 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/DataWrangling/JRA55/JRA55_field_time_series.jl b/src/DataWrangling/JRA55/JRA55_field_time_series.jl index 3a5ca820f..2def6129f 100644 --- a/src/DataWrangling/JRA55/JRA55_field_time_series.jl +++ b/src/DataWrangling/JRA55/JRA55_field_time_series.jl @@ -189,6 +189,7 @@ function set!(fts::JRA55NetCDFFTSMultipleYears, backend=fts.backend) LX, LY, LZ = location(fts) i₁, i₂, j₁, j₂, TX = compute_bounding_indices(nothing, nothing, fts.grid, LX, LY, λc, φc) + if issorted(nn) data = ds[name][i₁:i₂, j₁:j₂, nn] else @@ -457,7 +458,7 @@ function JRA55FieldTimeSeries(metadata::JRA55Metadata, architecture=CPU(), FT=Fl ds = Dataset(filepath) data = ds[shortname][i₁:i₂, j₁:j₂, time_indices_in_memory] close(ds) - + copyto!(interior(fts, :, :, 1, :), data) fill_halo_regions!(fts) diff --git a/src/InitialConditions/InitialConditions.jl b/src/InitialConditions/InitialConditions.jl index a529e6046..6a815f056 100644 --- a/src/InitialConditions/InitialConditions.jl +++ b/src/InitialConditions/InitialConditions.jl @@ -18,7 +18,7 @@ using JLD2 # Implementation of 3-dimensional regridding # TODO: move all the following to Oceananigans! -using Oceananigans.Fields: interpolate! +using Oceananigans.Fields: regrid!, interpolate! using Oceananigans.Grids: cpu_face_constructor_x, cpu_face_constructor_y, cpu_face_constructor_z, @@ -31,6 +31,44 @@ construct_grid(::Type{<:RectilinearGrid}, arch, size, extent, topology) = construct_grid(::Type{<:LatitudeLongitudeGrid}, arch, size, extent, topology) = LatitudeLongitudeGrid(arch; size, longitude = extent[1], latitude = extent[2], z = extent[3], topology) +# Regrid a field in three dimensions +function three_dimensional_regrid!(a, b) + target_grid = a.grid isa ImmersedBoundaryGrid ? a.grid.underlying_grid : a.grid + source_grid = b.grid isa ImmersedBoundaryGrid ? b.grid.underlying_grid : b.grid + + topo = topology(target_grid) + arch = architecture(target_grid) + arch = child_architecture(arch) + + target_y = yt = cpu_face_constructor_y(target_grid) + target_z = zt = cpu_face_constructor_z(target_grid) + + target_size = Nt = size(target_grid) + + source_x = xs = cpu_face_constructor_x(source_grid) + source_y = ys = cpu_face_constructor_y(source_grid) + + source_size = Ns = size(source_grid) + + # Start by regridding in z + @debug "Regridding in z" + zgrid = construct_grid(typeof(target_grid), arch, (Ns[1], Ns[2], Nt[3]), (xs, ys, zt), topo) + field_z = Field(location(b), zgrid) + regrid!(field_z, zgrid, source_grid, b) + + # regrid in y + @debug "Regridding in y" + ygrid = construct_grid(typeof(target_grid), arch, (Ns[1], Nt[2], Nt[3]), (xs, yt, zt), topo) + field_y = Field(location(b), ygrid); + regrid!(field_y, ygrid, zgrid, field_z); + + # Finally regrid in x + @debug "Regridding in x" + regrid!(a, target_grid, ygrid, field_y) + + return a +end + include("diffuse_tracers.jl") end # module diff --git a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl index 9f0b3de73..d12ae69b3 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/atmosphere_sea_ice_fluxes.jl @@ -14,7 +14,6 @@ function compute_atmosphere_sea_ice_fluxes!(coupled_model) v = ZeroField(), h = sea_ice.model.ice_thickness, ℵ = sea_ice.model.ice_concentration, - hc = sea_ice.model.ice_consolidation_thickness, Tₒ = ocean.model.tracers.T, Sₒ = ocean.model.tracers.S) @@ -98,7 +97,6 @@ end uᵢ = zero(FT) # ℑxᶜᵃᵃ(i, j, 1, grid, interior_state.u) vᵢ = zero(FT) # ℑyᵃᶜᵃ(i, j, 1, grid, interior_state.v) hᵢ = interior_state.h[i, j, 1] - hc = interior_state.hc[i, j, 1] ℵᵢ = interior_state.ℵ[i, j, 1] Tₛ = interface_temperature[i, j, 1] Tₛ = convert_to_kelvin(sea_ice_properties.temperature_units, Tₛ) @@ -119,7 +117,7 @@ end h_bℓ = atmosphere_state.h_bℓ) downwelling_radiation = (; Qs, Qℓ) - local_interior_state = (u=uᵢ, v=vᵢ, T=Tᵢ, S=Sᵢ, h=hᵢ, hc=hc) + local_interior_state = (u=uᵢ, v=vᵢ, T=Tᵢ, S=Sᵢ, h=hᵢ) # Estimate initial interface state u★ = convert(FT, 1e-4) diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index 76ce1797a..581333c1a 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -291,7 +291,7 @@ function default_ai_temperature(sea_ice::SeaIceSimulation) end function default_ao_specific_humidity(ocean) - FT = Float64 + FT = eltype(ocean) phase = AtmosphericThermodynamics.Liquid() x_H₂O = convert(FT, 0.98) return ImpureSaturationSpecificHumidity(phase, x_H₂O) @@ -345,7 +345,7 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; sea_ice_heat_capacity = heat_capacity(sea_ice), gravitational_acceleration = g_Earth) - FT = Float64 + FT = eltype(ocean) ocean_reference_density = convert(FT, ocean_reference_density) ocean_heat_capacity = convert(FT, ocean_heat_capacity) diff --git a/src/OceanSeaIceModels/OceanSeaIceModels.jl b/src/OceanSeaIceModels/OceanSeaIceModels.jl index 2edbf3dc1..78f139a54 100644 --- a/src/OceanSeaIceModels/OceanSeaIceModels.jl +++ b/src/OceanSeaIceModels/OceanSeaIceModels.jl @@ -43,6 +43,8 @@ const default_freshwater_density = 1000 const SeaIceSimulation = Simulation{<:SeaIceModel} const OceananigansSimulation = Simulation{<:HydrostaticFreeSurfaceModel} +Base.eltype(ocean::OceananigansSimulation) = eltype(ocean.model.grid) + sea_ice_thickness(::Nothing) = ZeroField() sea_ice_thickness(sea_ice::SeaIceSimulation) = sea_ice.model.ice_thickness diff --git a/src/OceanSeaIceModels/ocean_sea_ice_model.jl b/src/OceanSeaIceModels/ocean_sea_ice_model.jl index a99c3d550..6a64aa10e 100644 --- a/src/OceanSeaIceModels/ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/ocean_sea_ice_model.jl @@ -19,6 +19,8 @@ import Oceananigans.TimeSteppers: time_step!, update_state!, time import Oceananigans.Utils: prettytime import Oceananigans.Models: timestepper, NaNChecker, default_nan_checker, initialization_update_state! +import Base + mutable struct OceanSeaIceModel{I, A, O, F, C, Arch} <: AbstractModel{Nothing, Arch} architecture :: Arch clock :: C From bf23df71b1a475eaf38d2dcac37642d8c5e4c075 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 11:40:03 +0200 Subject: [PATCH 187/203] back to previous stuff --- Project.toml | 2 +- docs/make.jl | 10 - docs/src/interface_fluxes.md | 635 ++++++++++++++++++ examples/one_degree_simulation.jl | 4 +- experiments/omip_prototype/download_data.jl | 8 - experiments/omip_prototype/one_degree_omip.jl | 155 ----- .../omip_prototype/sixth_degree_omip.jl | 153 ----- .../sixth_degree_omip_nodynamics.jl | 233 ------- .../clima_ocean_copernicus.jl | 2 +- .../veros_ocean_simulation.jl | 2 +- .../InterfaceComputations/interface_states.jl | 10 +- .../roughness_lengths.jl | 12 +- .../similarity_theory_turbulent_fluxes.jl | 9 +- .../time_step_ocean_sea_ice_model.jl | 29 +- src/SeaIceSimulations.jl | 20 +- test/test_jra55.jl | 1 - 16 files changed, 655 insertions(+), 630 deletions(-) delete mode 100644 experiments/omip_prototype/download_data.jl delete mode 100644 experiments/omip_prototype/one_degree_omip.jl delete mode 100644 experiments/omip_prototype/sixth_degree_omip.jl delete mode 100644 experiments/omip_prototype/sixth_degree_omip_nodynamics.jl diff --git a/Project.toml b/Project.toml index 3e55fb476..43907c994 100644 --- a/Project.toml +++ b/Project.toml @@ -76,4 +76,4 @@ MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Coverage", "Test", "MPIPreferences", "CUDA_Runtime_jll"] +test = ["Coverage", "Test", "MPIPreferences", "CUDA_Runtime_jll", "Reactant", "PythonCall", "CondaPkg"] diff --git a/docs/make.jl b/docs/make.jl index ffa9b171c..4103341e6 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -4,16 +4,6 @@ using DocumenterCitations, Literate -# temporary to enforce Oceananigans to use a specific branch -using Pkg -Pkg.add(PackageSpec( - name = "Oceananigans", - url = "https://github.com/CliMA/Oceananigans.jl", - rev = "ss/omip-branch-2" -)) -Pkg.resolve() -@show Pkg.status() - ENV["DATADEPS_ALWAYS_ACCEPT"] = "true" bib_filepath = joinpath(dirname(@__FILE__), "climaocean.bib") diff --git a/docs/src/interface_fluxes.md b/docs/src/interface_fluxes.md index 7d1a89e98..047ccce2e 100644 --- a/docs/src/interface_fluxes.md +++ b/docs/src/interface_fluxes.md @@ -76,3 +76,638 @@ In both cases, computing turbulent fluxes requires: 5. Possibly, additional "bulk" properties of the surface media and radiation fluxes in order to compute an equilibrium "skin" surface temperature that differs from the bulk temperature below the surface. + +!!! note + In general, the surface specific humidity is typically related to the saturation specific humidity + at the the surface temperature ``T_s``, according to the Clausius-Claperyon relation. + For example, for ocean surfaces, the surface specific humidity is computed + according to via [Raoult's law](https://en.wikipedia.org/wiki/Raoult%27s_law) as + + ```math + q^\dagger(\rho, S, T) = x_{H_2O}(S) \frac{p_v^\dagger}{\rho R_v T} + ``` + + where ``x_{H_2O}(S)`` is the mole fraction of pure water in seawater with salinity ``S``, + and ``p_v^\dagger`` is the saturation vapor pressure, + + ```math + p_v^\dagger(T) = p_{tr} \left ( \frac{T}{T_{tr}} \right )^{\Delta c_p / R_v} \exp \left [ \frac{ℒ_{v0} - Δc_p T₀}{R_v} \left (\frac{1}{T_{tr}} - \frac{1}{T} \right ) \right ] + \quad \text{where} \quad + Δc_p = c_{p \ell} - c_{pv} \, . + ``` + + Many flux solvers (and the OMIP protocol) use a constant ``x_{H_2O} = 0.98``, which is equivalent to assuming + that the surface salinity is ``S \approx 35 \, \mathrm{g \, kg^{-1}}``, along with a reference seawater salinity composition. + Other surface specific humidity models may be used that take into account, for example, the microscopic structure + of snow, or the presence of a "dry skin" that buffers saturated soil from the atmosphere in a land model. + + Default values for the atmosphere thermodynamic parameters used to compute the saturation vapor pressure + and atmospheric equation of state are + + ```@example interface_fluxes + using ClimaOcean.OceanSeaIceModels.PrescribedAtmospheres: AtmosphereThermodynamicsParameters + AtmosphereThermodynamicsParameters() + ``` + +### Coefficient-based fluxes + +Turbulent fluxes may be computed by prescribing "transfer coefficients" that relate differences +between the near-surface atmosphere and the ocean surface to fluxes, + +```math +\overline{\bm{u}' w'} ≈ C_D \, Δ \bm{u} \, U \\ +\overline{w' \theta'} ≈ C_\theta \, Δ \theta \, U \\ +\overline{w' q'} ≈ C_q \, Δ q \, U +``` + +The variable ``U`` is a characteristic velocity scale, which is most simply formulated as ``U = | Δ \bm{u}|``. +However, some parameterizations use formulations for ``U`` that +produce non-vanishing heat and moisture fluxes in zero-mean-wind conditions. +Usually these parameterizations are formulated as models for "gustiness" associated with atmospheric convection; +but more generally a common thread is that ``U`` may include contributions from unresolved turbulent motions +in addition to the relative mean velocity, ``Δ \bm{u}``. + +The variable ``C_D`` is often called the drag coefficient, while ``C_\theta`` and ``C_q`` are the heat transfer +coefficient and vapor flux coefficient. +The simplest method for computing fluxes is merely to prescribe ``C_D``, ``C_\theta``, and ``C_q`` +as constants -- typically with a magnitude around ``5 × 10^{-4}``--``2 × 10^{-3}``. +A comprehensive example is given below, but we note briefly here that +`ClimaOcean` supports the computation of turbulent fluxes with constant coefficients via + +```@example interface_fluxes +using ClimaOcean + +coefficient_fluxes = CoefficientBasedFluxes(drag_coefficient=2e-3, + heat_transfer_coefficient=2e-3, + vapor_flux_coefficient=1e-3) +``` + +### Similarity theory for neutral boundary layers + +The standard method for computing fluxes in realistic Earth system modeling contexts +uses a model for the structure of the near-surface atmosphere based on Monin--Obukhov similarity theory. +Similarity theory is essentially a dimensional argument and begins with the definition of "characteristic scales" +which are related to momentum, heat, and vapor fluxes through + +```math +u_\star^2 ≡ | \overline{\bm{u}' w'} | \\ +u_\star \theta_\star ≡ \overline{w' \theta'} \\ +u_\star q_\star ≡ \overline{w' q'} +``` + +where ``u_\star``, often called the "friction velocity", is the characteristic scale for velocity, +``\theta_\star`` is the characteristic scale for temperature, and ``q_\star`` is the characteristic scale +for water vapor. + +To introduce similarity theory, we first consider momentum fluxes in "neutral" conditions, +or with zero buoyancy flux. +We further simplify the situation by considering unidirectional flow with ``\bm{u} = u \, \bm{\hat x}``. +(To generalize our results to any flow direction, we simply rotate fluxes into the direction of the +relative velocity ``Δ \bm{u}``.) +The fundamental supposition of similarity theory is that the vertical shear depends only on +height above the boundary, such that by dimensional analysis, + +```math +\partial_z u \sim \frac{u_\star}{z} \, , +\qquad \text{and thus} \qquad +\partial_z u = \frac{u_\star}{\kappa z} \, , +``` + +where the second expression forms an equality by introducing the "Von Karman constant" ``\kappa``, +which is placed in the denominator by convention. +We can then integrate this expression from an inner scale ``z=\ell`` up to ``z=h`` to obtain + +```math +u_a(h) - u_a(\ell_u) = \frac{u_⋆}{\kappa} \log \left ( \frac{h}{\ell_u} \right ) +``` + +The inner length scale ``\ell_u``, which is called the "momentum roughness length", +can be interpreted as producing a characteristic upper value for the boundary layer shear, ``u_⋆ / \ell_u`` +in the region where similarity theory must be matched with the inner boundary layer (such as a viscous sublayer) +below. +Note that we take the inner velocity scale ``u_a(\ell_u)`` as being equal to the velocity of the surface, +so ``u_a(\ell_u) = u_s``. + +!!! note + We currently assume that the input to the surface flux computation is the + atmospheric velocity at ``z=h``. However, in coupled modeling context we are typically + instead given the atmosphere velocity _averaged_ over the height of the first layer, + or ``⟨u_a⟩_h = \frac{1}{h} \int_0^h \, u_a \, \mathrm{d} z``. + Formulating the flux computation in terms of ``⟨u_a⟩_h`` rather than ``u_a(h)`` + (e.g. [nishizawa2018surface](@citet)) + is a minor modification to the algorithm and an important avenue for future work. + +The roughness length in general depends on the physical nature of the surface. +For smooth, no-slip walls, experiments (cite) found agreement with a viscous sublayer model + +```math +\ell_ν = \mathbb{C}_\nu \frac{\nu}{u_\star} \, , +``` + +where ``\nu`` is the kinematic viscosity of the fluid (the air in our case) and ``\mathbb{C}_\nu`` is a free +parameter which was found to be around ``0.11``. +For air-water interfaces that develop a wind-forced spectrum of surface gravity waves, the alternative scaling + +```math +\ell_g = \mathbb{C}_g \frac{u_\star^2}{g} \, , +``` + +where ``g`` is gravitational acceleration, has been repeatedly (and perhaps shockingly due to its simplicity) confirmed by field campaigns. +The free parameter ``\mathbb{C}_g`` is often called + the "Charnock parameter" and takes typical values +between ``0`` and ``0.03`` [edson2013exchange](@citep). + +```@example +using ClimaOcean +using CairoMakie +set_theme!(Theme(fontsize=14, linewidth=4)) + +charnock_length = MomentumRoughnessLength(wave_formulation = 0.02, + smooth_wall_parameter = 0, + maximum_roughness_length = Inf) + +smooth_wall_length = MomentumRoughnessLength(wave_formulation = 0, + smooth_wall_parameter = 0.11) + +default_roughness_length = MomentumRoughnessLength() +modified_default_length = MomentumRoughnessLength(wave_formulation = 0.011) + +u★ = 1e-2:5e-3:3e-1 +ℓg = charnock_length.(u★) +ℓν = smooth_wall_length.(u★) +ℓd = default_roughness_length.(u★) +ℓ2 = modified_default_length.(u★) + +fig = Figure(size=(800, 400)) +ax1 = Axis(fig[1, 1], xlabel="Friction velocity, u★ (m s⁻¹)", ylabel="Momentum roughness length ℓᵤ (m)") +lines!(ax1, u★, ℓd, label="ClimaOcean default") +lines!(ax1, u★, ℓg, label="Charnock") +lines!(ax1, u★, ℓν, label="Smooth wall") +lines!(ax1, u★, ℓ2, color=:black, label="ClimaOcean default with ℂg = 0.011") + +ax2 = Axis(fig[1, 2], xlabel="Friction velocity, u★ (m s⁻¹)", ylabel="Momentum roughness length, ℓᵤ (m)") +u★ = 0.1:0.1:10 +ℓd = default_roughness_length.(u★) +ℓ2 = modified_default_length.(u★) +lines!(ax2, u★, ℓd) +lines!(ax2, u★, ℓ2, color=:black) + +Legend(fig[0, 1:2], ax1, orientation=:horizontal) + +fig +``` + +!!! note + The roughness length ``\ell`` should not be interpreted as a physical length scale, + a fact made clear by its submillimeter magnitude under (albeit calm) air-sea flux conditions. + +## Computing fluxes and the effective similarity drag coefficient + +ClimaOcean's default roughness length for air-sea fluxes is a function of the +friction velocity ``u_\star``. +This formulation produces a nonlinear equation for ``u_\star``, in terms of ``Δ u = u_a(h) - u_o``, +which we emphasize by rearranging the similarity profile + +```math +u_\star = \frac{\kappa \, Δ u}{\log \left [ h / \ell_u(u_\star) \right ]} \, . +``` + +The above equation is solved for ``u_\star`` using fixed-point iteration initialized with a reasonable +guess for ``u_\star``. +Once ``u_\star`` is obtained, the similarity drag coefficient may then be computed via + +```math +C_D(h) ≡ \frac{u_\star^2}{|Δ u(h)|^2} = \frac{\kappa^2}{\left ( \log \left [ h / \ell_u \right ] \right )^2} \, +``` + +where we have used the simple bulk velocity scale ``U = Δ u``. +We have also indicated that, the effective similarity drag "coefficient" depends on the height ``z=h`` +at which the atmospheric velocity is computed to form the relative velocity ``Δ u = u_a(h) - u_o``. +Most observational campaigns use ``h = 10 \, \mathrm{m}`` and most drag coefficients reported in the +literature pertain to ``h=10 \, \mathrm{m}``. + +To compute fluxes with ClimaOcean, we build an `OceanSeaIceModel` with an atmosphere and ocean state +concocted such that we can evaluate fluxes over a range of relative atmosphere and oceanic conditions. +For this we use a ``200 × 200`` horizontal grid and start with atmospheric winds that vary from +the relatively calm ``u_a(10 \, \mathrm{m}) = 0.5 \, \mathrm{m \, s^{-1}}`` to a +blustery ``u_a(10 \, \mathrm{m}) = 40 \, \mathrm{m \, s^{-1}}``. +We also initialize the ocean at rest with surface temperature ``T_o = 20 \, \mathrm{{}^∘ C}`` and +surface salinity ``S_o = 35 \, \mathrm{g \, kg^{-1}}`` -- but the surface temperature and salinity won't matter until later. + +```@example interface_fluxes +using Oceananigans +using ClimaOcean + +# Atmosphere velocities +Nx = Ny = 200 +uₐ = range(0.5, stop=40, length=Nx) # winds at 10 m, m/s + +# Ocean state parameters +T₀ = 20 # Surface temperature, ᵒC +S₀ = 35 # Surface salinity + +x = y = (0, 1) +z = (-1, 0) +atmos_grid = RectilinearGrid(size=(Nx, Ny); x, y, topology=(Periodic, Periodic, Flat)) +ocean_grid = RectilinearGrid(size=(Nx, Ny, 1); x, y, z, topology=(Periodic, Periodic, Bounded)) + +# Build the atmosphere +atmosphere = PrescribedAtmosphere(atmos_grid, surface_layer_height=10) +interior(atmosphere.tracers.T) .= 273.15 + T₀ # K +interior(atmosphere.velocities.u, :, :, 1, 1) .= uₐ # m/s + +kw = (momentum_advection=nothing, tracer_advection=nothing, closure=nothing) +ocean = ocean_simulation(ocean_grid; kw...) +set!(ocean.model, T=T₀, S=S₀) +``` + +Next we build two models with different flux formulations -- the default "similarity model" +that uses similarity theory with "Charnock" gravity wave parameter ``\mathbb{C}_g = 0.02``, +and a "coefficient model" with a constant drag coefficient ``C_D = 2 × 10^{-3}``: + +```@example interface_fluxes +neutral_similarity_fluxes = SimilarityTheoryFluxes(stability_functions=nothing) +interfaces = ComponentInterfaces(atmosphere, ocean; atmosphere_ocean_fluxes=neutral_similarity_fluxes) +default_model = OceanSeaIceModel(ocean; atmosphere, interfaces) + +momentum_roughness_length = MomentumRoughnessLength(wave_formulation=0.04) +neutral_similarity_fluxes = SimilarityTheoryFluxes(stability_functions=nothing; momentum_roughness_length) +interfaces = ComponentInterfaces(atmosphere, ocean; atmosphere_ocean_fluxes=neutral_similarity_fluxes) +increased_roughness_model = OceanSeaIceModel(ocean; atmosphere, interfaces) + +coefficient_fluxes = CoefficientBasedFluxes(drag_coefficient=2e-3) +interfaces = ComponentInterfaces(atmosphere, ocean; atmosphere_ocean_fluxes=coefficient_fluxes) +coefficient_model = OceanSeaIceModel(ocean; atmosphere, interfaces) +``` + +Note that `OceanSeaIceModel` computes fluxes upon instantiation, so after constructing +the two models we are ready to analyze the results. +We first verify that the similarity model friction velocity has been computed successfully, + +```@example interface_fluxes +u★ = default_model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity +u★ = interior(u★, :, 1, 1) +extrema(u★) +``` + +and it seems that we've obtained a range of friction velocities, which is expected +given that our atmospheric winds varied from ``0.5`` to ``40 \, \mathrm{m \, s^{-1}}``. +Computing the drag coefficient for the similarity model is as easy as + +```@example interface_fluxes +Cᴰ_default = @. (u★ / uₐ)^2 +extrema(Cᴰ_default) +``` + +We'll also re-compute the drag coefficient for the coefficient model +(which we specified as constant), which verifies that the coefficient was correctly +specified: + +```@example interface_fluxes +u★_coeff = coefficient_model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity +u★_coeff = interior(u★_coeff, :, 1, 1) +Cᴰ_coeff = @. (u★_coeff / uₐ)^2 +extrema(Cᴰ_coeff) +``` + +We'll compare the computed fluxes and drag coefficients from our two models with +a polynomial expression due to [large2009global](@citet), and +an expression reported by [edson2013exchange](@citet) that was developed at ECMWF, + +```@example interface_fluxes +# From Large and Yeager (2009), equation 10 +c₁ = 0.0027 +c₂ = 0.000142 +c₃ = 0.0000764 +u★_LY = @. sqrt(c₁ * uₐ + c₂ * uₐ^2 + c₃ * uₐ^3) +Cᴰ_LY = @. (u★_LY / uₐ)^2 + +# From Edson et al. (2013), equation 20 +c₁ = 1.03e-3 +c₂ = 4e-5 +p₁ = 1.48 +p₂ = 0.21 +Cᴰ_EC = @. (c₁ + c₂ * uₐ^p₁) / uₐ^p₂ +u★_EC = @. sqrt(Cᴰ_EC) * uₐ +extrema(u★_EC) +``` + +Finally, we plot the results to compare the estimated friction velocity and effective +drag coefficient from the polynomials expressions with the two `OceanSeaIceModel`s: + +```@example interface_fluxes +using CairoMakie +set_theme!(Theme(fontsize=14, linewidth=4)) + +# Extract u★ and compute Cᴰ for increased roughness model +u★_rough = increased_roughness_model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity +u★_rough = interior(u★_rough, :, 1, 1) +Cᴰ_rough = @. (u★_rough / uₐ)^2 + +fig = Figure(size=(800, 400)) +axu = Axis(fig[1:2, 1], xlabel="uₐ (m s⁻¹) at 10 m", ylabel="u★ (m s⁻¹)") +lines!(axu, uₐ, u★, label="ClimaOcean default") +lines!(axu, uₐ, u★_rough, label="Increased roughness model") +lines!(axu, uₐ, u★_LY, label="Large and Yeager (2009) polynomial fit") +lines!(axu, uₐ, u★_EC, label="ECMWF polynomial fit (Edson et al. 2013)") + +axd = Axis(fig[1:2, 2], xlabel="uₐ (m s⁻¹) at 10 m", ylabel="1000 × Cᴰ") +lines!(axd, uₐ, 1000 .* Cᴰ_default, label="ClimaOcean default") +lines!(axd, uₐ, 1000 .* Cᴰ_rough, label="Increased roughness model") +lines!(axd, uₐ, 1000 .* Cᴰ_LY, label="Large and Yeager (2009) polynomial fit") +lines!(axd, uₐ, 1000 .* Cᴰ_EC, label="ECMWF polynomial fit (Edson et al. 2013)") + +Legend(fig[3, 1:2], axd, nbanks = 2) + +fig +``` + +## Non-neutral boundary layers and stability functions + +The relationship between the relative air-sea state and turbulent fluxes +is modified by the presence of buoyancy fluxes -- "destabilizing" fluxes, which stimulate convection, +tend to increase turbulent exchange, while stabilizing fluxes suppress turbulence and turbulent exchange. +Monin--Obhukhov stability theory provides a scaling-argument-based framework +for modeling the effect of buoyancy fluxes on turbulent exchange. + +### Buoyancy flux and stability of the near-surface atmosphere + +Our next objective is to characterize the atmospheric statbility in terms of the buoyancy flux, ``\overline{w' b'}``, +which requires a bit of thermodynamics background to define the buoyancy perturbation, ``b'``. + +#### Buoyancy for a non-condensing mixture of dry air and water vapor + +The atmosphere is generally a mix of dry air, water vapor, non-vapor forms of water such as liquid droplets, +ice particles, rain, snow, hail, sleet, graupel, and more, and trace gases. +In the definition of buoyancy that follows, we neglect both the mass and volume of non-vapor water, +so that the specific humidity may be written + +```math +q \approx \frac{\rho_v}{\rho_v + \rho_d} \approx \frac{\rho_v}{\rho} \, , +``` + +where ``\rho_v`` is the density of water vapor, ``\rho_d`` is the density of dry air, and ``\rho \approx \rho_v + \rho_d`` +is the total density neglecting the mass of hypothetical condensed water species. + +!!! note + We endeavor to provide more information about the impact of this approximation. + Also, note that atmospheric data products like JRA55 do not explicitly provide + the mass ratio of condensed water, so the approximation is required in at least + some situations (such as simulations following the protocol of the Ocean Model + Intercomparison Project, OMIP). + On the other hand, generalizing the buoyancy formula that follow below to account + for the mass of condensed water is straightforward. + +The ideal gas law for a mixture of dry air and water vapor is then + +```math +p = \rho R_m(q) T \, +\qquad \text{where} \qquad +R_m(q) ≈ R_d \left (1 - q \right ) + R_v q = R_d \left ( 1 - \mathscr{M} q \right ) \, , +``` + +where ``\mathscr{M} = R_v/R_d - 1`` and ``R_m(q)`` is the effective mixture gas "constant" which varies with specific humidity ``q``, +and the ``\approx`` indicates that its form neglects the mass of condensed species. + +The buoyant perturbation experienced by air parcels advected by subgrid turbulent motions is then + +```math +b' ≡ - g \frac{\rho - \bar{\rho}}{\rho} = g \frac{\alpha - \bar{\alpha}}{\bar{\alpha}} +\qquad \text{where} \qquad +α = \frac{1}{\rho} = \frac{R_m T}{p} \, . +``` + +We neglect the effect of pressure perturbations to compute the buoyancy flux, so that ``p = \bar{p}`` and + +```math +\alpha - \bar{\alpha} = \frac{R_d}{p} \left [ T' - \mathscr{M} \left ( q' \bar{T} + \bar{q} T' + q' T' - \overline{q' T'} \right ) \right ] \, . +``` + +#### Buoyancy flux and the characteristic buoyancy scale + +In a computation whose details are reserved for an appendix, and which neglects ``\overline{q'T'}`` and the triple correlation ``\overline{w' q' T'}``, +we find that the buoyancy flux is approximately + +```math +\overline{w' b'} \approx g \frac{\overline{w'T'} - \mathscr{M} \left ( \overline{w' q'} \bar{T} + \bar{q} \overline{w' T'} \right )}{\bar{T} \left ( 1 - \mathscr{M} \bar q \right )} \, . +``` + +The characteristic buoyancy scale ``b_\star``, defined via ``u_\star b_\star \equiv \overline{w'b'}|_0``, is defined analogously to the temperature and vapor scales ``u_\star \theta_\star \equiv \overline{w' T'}`` and ``u_\star q_\star \equiv \overline{w' q'}``. +We therefore find + +```math +b_⋆ ≡ g \frac{\theta_\star - \mathscr{M} \left ( q_\star T_s + q_s \theta_\star \right ) }{ T_s \left (1 + \mathscr{M} q_s \right )} \, . +``` + +##### Stability of the near-surface atmosphere + +We use the ratio between the buoyancy flux and shear production at ``z=h`` -- which oceanographers often call +the "flux Richardson number", ``Ri_f`` -- to diagnose the stability of the atmosphere, + +```math +Ri_f(z) ≡ ζ(z) \equiv - \frac{\overline{w' b'}}{\partial_z \bar{\bm{u}} \, ⋅ \, \overline{\bm{u}' w'}} = - \frac{\kappa \, z}{u_\star^2} b_⋆ = \frac{z}{L_\star} +\qquad \text{where} \qquad +L_\star ≡ - \frac{u_\star^2}{\kappa b_\star} \, , +``` + +``\zeta`` is called the "stability parameter" and ``L_\star`` is called the "Monin--Obhukhov length scale". + +### The Monin--Obhukhov "stability functions" + +The fundamental premise of Monin--Obhkhov stability theory is that shear within a similarity layer affected by buoyancy fluxes may written + +```math +\frac{\kappa \, z}{u_\star} \partial_z \bar{u} = \tilde{\psi}_u(\zeta) \, , +``` + +where ``\tilde{\psi}_u(\zeta)`` is called the "stability function" (aka "dimensionless shear", and often denoted ``\phi``). +Comparing the Monin--Obukhov scaling to the neutral case expounded above, we find that ``\tilde{\psi}(0) = 1`` in neutral conditions with ``\zeta=0``. +In the presence of destabilizing fluxes, when ``ζ < 0``, observations show that ``\tilde{\psi}_u(\zeta) < 1`` (e.g. Businger 1971) -- representing an enhancement of turbulent exchange between the surface and atmosphere. +Conversely, ``\tilde{\psi}_u > 1`` when ``ζ > 0``, representing a suppression of turbulent fluxes by stable density stratification, or alternatively, an increase in the shear required to sustain a given friction velocity ``u_\star``. + +Monin and Obhukov's dimensional argument is also extended to potential temperature, so that for example + +```math +\frac{κ \, z}{\theta_\star} \partial_z \bar{\theta} = \tilde{\psi}_\theta (\zeta) \, . +``` + +Within the context of Monin--Obukhov stabilty theory, it can be shown that the neutral value ``\tilde{\psi}_\theta(0)`` is equal to the neutral turbulent Prandtl number, + +```math +Pr(\zeta=0) \equiv \frac{\tilde{\psi}_\theta(0)}{\tilde{\psi}_u(0)} = \tilde{\psi}_\theta(0) \, , +``` + +and observations suggest that ``\tilde{\psi}_θ(0) ≈ 0.7``. +Otherwise, the interpretation of variations in ``\tilde{\psi}_\theta`` (increased by stability, decreased by instability)is similar as for momentum. +We typically use the same "scalar" stability function to scale the vertical profiles of both temperature and water vapor, but neverthless ClimaOcean retains the possibility of an independent ``\tilde{\psi}_q``. + +### The Monin--Obhukhov self-similar vertical profiles + +To determine the implications of Monin--Obukhov similarity theory on the vertical profiles +of ``u``, ``\theta``, and ``q``, and therefore the implications for computing fluxes based on +the given differences ``Δ\bm{u}``, ``Δ \theta``, and ``Δ q``, we introduce "auxiliary stability functions" ``\psi_u(\zeta)``, which have derivatives ``\psi_u'(\zeta)`` and are related to ``\tilde{\psi}_u`` via + +```math +\tilde{ψ}_u(ζ) \equiv 1 - ζ ψ_u'(ζ) \, . +``` + +Inserting this transformation into the Monin--Obukhov scaling argument and rearranging terms yields + +```math +\partial_z u = \frac{u_\star}{\kappa \, z} + \frac{b_\star}{u_⋆} ψ' \left ( \frac{z}{L_⋆} \right ) \, , +``` + +which when integrated from ``z=\ell_u`` to ``z=h``, as for the neutral case, then produces + +```math +u_a(h) - u_a(\ell_u) = Δ u = \frac{u_\star}{\kappa} + \left [ \log \left (\frac{h}{\ell_u} \right ) - ψ_u \left ( \frac{h}{L_\star} \right ) + ψ_u \left (\frac{\ell_u}{L_\star} \right ) \right ] \, . +``` + +The term ``\psi_u(\ell_u / L_\star)`` is often neglected because ``\ell_u / L_\star`` is miniscule and because by definition, ``\psi_u(0) = 0``. +Similar formulas hold for temperature and water vapor, + +```math +Δ \theta = \frac{\theta_\star}{\kappa} \left [ \log \left (\frac{h}{\ell_\theta} \right ) - ψ_\theta \left ( \frac{h}{L_\star} \right ) + ψ_\theta \left (\frac{\ell_\theta}{L_\star} \right ) \right ] \, , \\[2ex] +Δ q = \frac{q_\star}{\kappa} \left [ \log \left (\frac{h}{\ell_q} \right ) - ψ_q \left ( \frac{h}{L_\star} \right ) + ψ_q \left (\frac{\ell_q}{L_\star} \right ) \right ] \, . +``` + +Let's plot some stability functions: + +```@example interface_fluxes +using ClimaOcean.OceanSeaIceModels.InterfaceComputations: + EdsonMomentumStabilityFunction, # Edson et al. 2013 + EdsonScalarStabilityFunction, # Edson et al. 2013 + ShebaMomentumStabilityFunction, # Grachev et al. 2007 + ShebaScalarStabilityFunction, # Grachev et al. 2007 + PaulsonMomentumStabilityFunction, # Paulson 1970 + PaulsonScalarStabilityFunction # Paulson 1970 + +edson_momentum = EdsonMomentumStabilityFunction() +edson_scalar = EdsonScalarStabilityFunction() +sheba_momentum = ShebaMomentumStabilityFunction() +sheba_scalar = ShebaScalarStabilityFunction() +paulson_momentum = PaulsonMomentumStabilityFunction() +paulson_scalar = PaulsonScalarStabilityFunction() + +ζstep = 0.01 +ζ = -4:ζstep:4 +ζ⁺ = first(ζ[ζ .≥ 0]):ζstep:last(ζ) +ζ⁻ = first(ζ):ζstep:last(ζ[ζ .≤ 0]) + +fig = Figure(size=(800, 400)) + +axm = Axis(fig[1, 1], xlabel="Stability parameter ζ", ylabel="Momentum auxiliary stability function ψₘ") +axs = Axis(fig[1, 2], xlabel="Stability parameter ζ", ylabel="Scalar auxiliary stability function ψₛ") + +lines!(axm, ζ, edson_momentum.(ζ), label="Edson et al. (2013)", alpha=0.7) +lines!(axm, ζ⁺, sheba_momentum.(ζ⁺), label="Grachev et al. (2007)", alpha=0.7) +lines!(axm, ζ⁻, paulson_momentum.(ζ⁻), label="Paulson (1970)", alpha=0.7) +axislegend(axm, position=:lb) + +lines!(axs, ζ, edson_scalar.(ζ), label="Edson et al. (2013)", alpha=0.7) +lines!(axs, ζ⁺, sheba_scalar.(ζ⁺), label="Grachev et al. (2007)", alpha=0.7) +lines!(axs, ζ⁻, paulson_scalar.(ζ⁻), label="Paulson (1970)", alpha=0.7) + +for ax in (axm, axs) + ylims!(ax, -14, 4) +end + +fig +``` + +#### Computing fluxes given atmopshere, surface, and bulk interior states + +We compute surface fluxes by solving the nonlinear set of equations for ``u_\star``, ``\theta_\star``. +We use fixed point iteration of the following three-variable system, + +```math +u_⋆^{n+1} = \, Δ u \, \, Ξ_u \left (h, \ell_u^n, L_⋆^n \right ) \\[2ex] +θ_⋆^{n+1} = \, Δ θ \, \, Ξ_θ \left (h, \ell_θ^n, L_⋆^n \right ) \\[2ex] +q_⋆^{n+1} = \, Δ q \, \, Ξ_q \left (h, \ell_q^n, L_⋆^n \right ) +``` + +where, for example, + +```math +\Xi_u \left ( h, \ell_u, L_⋆ \right ) ≡ \frac{κ}{\log \left ( \frac{h}{\ell_u} \right ) - \psi_u \left ( \frac{h}{L_\star} \right ) + \psi_u \left ( \frac{\ell_u}{L_\star} \right )} \, , +``` + +The above equations indicate how ``\ell_u``, ``\ell_\theta``, ``\ell_q``, and ``L_⋆ = - u_\star^2 / κ b_\star`` are all functions of ``u_\star, \theta_\star, q_\star``;\ +estimating the right-hand side requires using values at the previous iterate ``n``. +Note that if a skin temperature model is used, then we obtain a four-variable system, + +```math +u_⋆^{n+1} = \, Δ u \, \, Ξ_u \left (h, \ell_u^n, L_⋆^n \right ) \\[2ex] +θ_⋆^{n+1} = \, Δ θ^n \, \, Ξ_θ \left (h, \ell_θ^n, L_⋆^n \right ) \\[2ex] +q_⋆^{n+1} = \, Δ q^n \, \, Ξ_q \left (h, \ell_q^n, L_⋆^n \right ) \\[2ex] +T_s^{n+1} = F_T \left (θ_⋆, q_⋆, I_{sw}, I_{lw}, \cdots \right ) +``` + +where ``F_T`` denotes an estimate of the surface temperature that, in general, requires all incoming heat fluxes +including shortwave and longwave radiation ``I_{sw}`` and ``I_{lw}``. +In the skin temperature case, the air-surface temperature difference ``Δ \theta`` and the saturation specific humidity +that enters into the air-surface specific humidity difference ``Δ q`` also change each iterate. + +```@example interface_fluxes +using ClimaOcean.OceanSeaIceModels.InterfaceComputations: surface_specific_humidity + +ρₐ = 1.2 # guess +Tₒ = 273.15 + 20 # in Kelvin +Sₒ = 35 +interfaces = default_model.interfaces +ℂₐ = interfaces.atmosphere_properties +q_formulation = interfaces.atmosphere_ocean_interface.properties.specific_humidity_formulation +qₛ = surface_specific_humidity(q_formulation, ℂₐ, ρₐ, Tₒ, Sₒ) +@show qₛ +``` + +We then set the atmospheric state: + +```@example interface_fluxes +interior(atmosphere.pressure) .= 101352 +interior(atmosphere.tracers.q) .= qₛ + +Tₐ = 273.15 .+ range(-40, stop=40, length=Ny) +Tₐ = reshape(Tₐ, 1, Ny) +interior(atmosphere.tracers.T) .= Tₐ + +Oceananigans.TimeSteppers.update_state!(default_model) +u★ = default_model.interfaces.atmosphere_ocean_interface.fluxes.friction_velocity +θ★ = default_model.interfaces.atmosphere_ocean_interface.fluxes.temperature_scale + +fig = Figure(size=(800, 600)) +axu = Axis(fig[2, 1], xlabel="Wind speed uₐ (m s⁻¹)", ylabel="Air-sea temperature difference (K)") +axθ = Axis(fig[2, 2], xlabel="Wind speed uₐ (m s⁻¹)", ylabel="Air-sea temperature difference (K)") +axC = Axis(fig[3, 1:2], xlabel="Wind speed uₐ (m s⁻¹)", ylabel="Cᴰ / neutral Cᴰ") + +ΔT = Tₐ .- Tₒ +ΔT = dropdims(ΔT, dims=1) + +hmu = heatmap!(axu, uₐ, ΔT, u★, colormap=:speed) +hmθ = heatmap!(axθ, uₐ, ΔT, θ★, colormap=:balance) + +Colorbar(fig[1, 1], hmu, label="u★ (m s⁻¹)", vertical=false) +Colorbar(fig[1, 2], hmθ, label="θ★ (K)", vertical=false) + +Cᴰ = [(u★[i, j] / uₐ[i])^2 for i in 1:Nx, j in 1:Ny] + +for j in (1, 20, 50, 100, 150, 200) + lines!(axC, uₐ, Cᴰ[:, j] ./ Cᴰ_default, label="ΔT = $(round(ΔT[j], digits=1)) K", alpha=0.8) +end + +axislegend(axC, orientation=:horizontal, nbanks=2, label="navid") + +xlims!(axC, 0, 10) +ylims!(axC, 0, 4) + +fig +``` + +The coefficient-based formula then takes the form + +```math +u_\star = \sqrt{C_D | Δ \bm{u} | \, U} \\ +\theta_\star = \frac{C_θ}{\sqrt{C_D}} \, Δ θ \, \sqrt{\frac{U}{|Δ \bm{u} |}} \\ +q_\star = \frac{C_q}{\sqrt{C_D}} \, Δ q \, \sqrt{\frac{U}{| Δ \bm{u} |}} \\ +``` diff --git a/examples/one_degree_simulation.jl b/examples/one_degree_simulation.jl index 7d1df91c3..8b109276f 100644 --- a/examples/one_degree_simulation.jl +++ b/examples/one_degree_simulation.jl @@ -52,9 +52,9 @@ grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(bottom_height); # parameterization. We also include some explicit horizontal diffusivity. eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=2e3, κ_symmetric=2e3) -horizontal_viscosity = HorizontalScalarDiffusivity(ν=4000) vertical_mixing = ClimaOcean.OceanSimulations.default_ocean_closure() - +horizontal_viscosity = HorizontalScalarDiffusivity(ν=4000) + # ### Ocean simulation # Now we bring everything together to construct the ocean simulation. # We use a split-explicit timestepping with 70 substeps for the barotropic diff --git a/experiments/omip_prototype/download_data.jl b/experiments/omip_prototype/download_data.jl deleted file mode 100644 index 2881bcd71..000000000 --- a/experiments/omip_prototype/download_data.jl +++ /dev/null @@ -1,8 +0,0 @@ -using ClimaOcean -using ClimaOcean.JRA55 -using ClimaOcean.DataWrangling: download_dataset - -atmosphere = JRA55PrescribedAtmosphere(; dir="forcing_data/", - dataset=JRA55MultipleYears(), - backend=JRA55NetCDFBackend(10), - include_rivers_and_icebergs=true) \ No newline at end of file diff --git a/experiments/omip_prototype/one_degree_omip.jl b/experiments/omip_prototype/one_degree_omip.jl deleted file mode 100644 index f2bae0dd2..000000000 --- a/experiments/omip_prototype/one_degree_omip.jl +++ /dev/null @@ -1,155 +0,0 @@ -using ClimaOcean -using ClimaSeaIce -using Oceananigans -using Oceananigans.Grids -using Oceananigans.Units -using Oceananigans.OrthogonalSphericalShellGrids -using ClimaOcean.OceanSimulations -using ClimaOcean.ECCO -using ClimaOcean.JRA55 -using ClimaOcean.DataWrangling -using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium -using Printf -using Dates -using CUDA - -import Oceananigans.OutputWriters: checkpointer_address - -arch = GPU() - -Nx = 360 # longitudinal direction -Ny = 180 # meridional direction -Nz = 60 - -z_faces = ExponentialCoordinate(Nz, -6000, 0) -# z_faces = MutableVerticalDiscretization(z_faces) - -const z_surf = z_faces(Nz) - -grid = TripolarGrid(arch; - size = (Nx, Ny, Nz), - z = z_faces, - halo = (7, 7, 7)) - -bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=75) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) - -##### -##### A Propgnostic Ocean model -##### - -using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization -using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation - -momentum_advection = WENOVectorInvariant(order=5) -tracer_advection = WENO(order=5) - -free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=45minutes) - -eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=1e3, κ_symmetric=1e3) -catke_closure = ClimaOcean.OceanSimulations.default_ocean_closure() -closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4), eddy_closure) - -dataset = EN4Monthly() -date = DateTime(1958, 1, 1) -@inline mask(x, y, z, t) = z ≥ z_surf - 1 -Smetadata = Metadata(:salinity; dataset) - -FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 10) - -ocean = ocean_simulation(grid; Δt=1minutes, - momentum_advection, - tracer_advection, - timestepper = :SplitRungeKutta3, - free_surface, - forcing = (; S = FS), - closure) - -dataset = EN4Monthly() -date = DateTime(1958, 1, 1) - -set!(ocean.model, T=Metadatum(:temperature; dataset, date), - S=Metadatum(:salinity; dataset, date)) - -@info ocean.model.clock - -##### -##### A Prognostic Sea-ice model -##### - -# Default sea-ice dynamics and salinity coupling are included in the defaults -sea_ice = sea_ice_simulation(grid, ocean; advection=WENO(order=7)) - -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly()), - ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly())) - -##### -##### A Prescribed Atmosphere model -##### - -dir = "./forcing_data" -dataset = MultiYearJRA55() -backend = JRA55NetCDFBackend(100) - -atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) -radiation = Radiation() - -##### -##### An ocean-sea ice coupled model -##### - -omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=30minutes, stop_time=60days) - -# Figure out the outputs.... -checkpointer_address(::SeaIceModel) = "SeaIceModel" - -ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, - schedule = IterationInterval(1000), - prefix = "ocean_checkpoint_onedegree", - overwrite_existing = true) - -sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, - schedule = IterationInterval(1000), - prefix = "sea_ice_checkpoint_onedegree", - overwrite_existing = true) - -wall_time = Ref(time_ns()) - -using Statistics - -function progress(sim) - sea_ice = sim.model.sea_ice - ocean = sim.model.ocean - hmax = maximum(sea_ice.model.ice_thickness) - ℵmax = maximum(sea_ice.model.ice_concentration) - Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) - Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) - umax = maximum(ocean.model.velocities.u) - vmax = maximum(ocean.model.velocities.v) - wmax = maximum(ocean.model.velocities.w) - - step_time = 1e-9 * (time_ns() - wall_time[]) - - msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) - msg2 = @sprintf("max(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) - msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) - msg5 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) - msg6 = @sprintf("wall time: %s \n", prettytime(step_time)) - - @info msg1 * msg2 * msg4 * msg5 * msg6 - - wall_time[] = time_ns() - - return nothing -end - -# And add it as a callback to the simulation. -add_callback!(omip, progress, IterationInterval(1)) - -run!(omip) - -omip.Δt = 40minutes -omip.stop_time = 58 * 365days - -run!(omip) diff --git a/experiments/omip_prototype/sixth_degree_omip.jl b/experiments/omip_prototype/sixth_degree_omip.jl deleted file mode 100644 index c1339d82c..000000000 --- a/experiments/omip_prototype/sixth_degree_omip.jl +++ /dev/null @@ -1,153 +0,0 @@ -using ClimaOcean -using ClimaSeaIce -using Oceananigans -using Oceananigans.Grids -using Oceananigans.Units -using Oceananigans.OrthogonalSphericalShellGrids -using ClimaOcean.OceanSimulations -using ClimaOcean.ECCO -using ClimaOcean.JRA55 -using ClimaOcean.DataWrangling -using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium -using Printf -using Dates -using CUDA - -import Oceananigans.OutputWriters: checkpointer_address - -function synch!(clock1::Clock, clock2) - # Synchronize the clocks - clock1.time = clock2.time - clock1.iteration = clock2.iteration - clock1.last_Δt = clock2.last_Δt -end - -synch!(model1, model2) = synch!(model1.clock, model2.clock) - -arch = GPU() - -Nx = 2160 # longitudinal direction -Ny = 1080 # meridional direction -Nz = 60 - -r_faces = ClimaOcean.ExponentialCoordinate(Nz, -6000) -z_faces = MutableVerticalDiscretization(r_faces) - -grid = TripolarGrid(arch; - size = (Nx, Ny, Nz), - z = z_faces, - halo = (7, 7, 7)) - -bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=15) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) - -##### -##### A Propgnostic Ocean model -##### - -using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization -using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation - -momentum_advection = WENOVectorInvariant() -tracer_advection = WENO(order=7) - -free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt=10minutes) - -mixing_length = CATKEMixingLength(Cᵇ=0.01) -turbulent_kinetic_energy_equation = CATKEEquation(Cᵂϵ=1.0) - -catke_closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) -closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) - -ocean = ocean_simulation(grid; Δt=1minutes, - momentum_advection, - tracer_advection, - free_surface, - closure) - -dataset = ECCO4Monthly() - -set!(ocean.model, T=Metadatum(:temperature; dataset), - S=Metadatum(:salinity; dataset)) - -##### -##### A Prognostic Sea-ice model -##### - -# Default sea-ice dynamics and salinity coupling are included in the defaults -sea_ice = sea_ice_simulation(grid; advection=WENO(order=7)) - -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), - ℵ=Metadatum(:sea_ice_concentration; dataset)) - -##### -##### A Prescribed Atmosphere model -##### - -dir = "./forcing_data" -dataset = MultiYearJRA55() -backend = JRA55NetCDFBackend(100) - -atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) -radiation = Radiation() - -##### -##### An ocean-sea ice coupled model -##### - -omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=20, stop_time=60days) - -# Figure out the outputs.... - -checkpointer_address(::SeaIceModel) = "SeaIceModel" - -ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, - schedule = IterationInterval(10000), - prefix = "ocean_checkpoint", - overwrite_existing = true) - -sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, - schedule = IterationInterval(10000), - prefix = "sea_ice_checkpoint", - overwrite_existing = true) - -wall_time = Ref(time_ns()) - -using Statistics - -function progress(sim) - sea_ice = sim.model.sea_ice - ocean = sim.model.ocean - hmax = maximum(sea_ice.model.ice_thickness) - ℵmax = maximum(sea_ice.model.ice_concentration) - Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) - Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) - umax = maximum(ocean.model.velocities.u) - vmax = maximum(ocean.model.velocities.v) - wmax = maximum(ocean.model.velocities.w) - - step_time = 1e-9 * (time_ns() - wall_time[]) - - msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) - msg2 = @sprintf("max(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) - msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) - msg5 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) - msg6 = @sprintf("wall time: %s \n", prettytime(step_time)) - - @info msg1 * msg2 * msg4 * msg5 * msg6 - - wall_time[] = time_ns() - - return nothing -end - -# And add it as a callback to the simulation. -add_callback!(omip, progress, IterationInterval(50)) - -run!(omip) - -omip.Δt = 6minutes -omip.stop_time = 58 * 365days - -run!(omip) diff --git a/experiments/omip_prototype/sixth_degree_omip_nodynamics.jl b/experiments/omip_prototype/sixth_degree_omip_nodynamics.jl deleted file mode 100644 index 6e6aa7a56..000000000 --- a/experiments/omip_prototype/sixth_degree_omip_nodynamics.jl +++ /dev/null @@ -1,233 +0,0 @@ -using Pkg -Pkg.update() -using ClimaOcean -using ClimaSeaIce -using Oceananigans -using Oceananigans.Grids -using Oceananigans.Grids: AbstractGrid -using Oceananigans.Units -using Oceananigans.OrthogonalSphericalShellGrids -using ClimaOcean.OceanSimulations -using ClimaOcean.ECCO -using ClimaOcean.JRA55 -using ClimaOcean.DataWrangling -using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium -using Printf -using Dates -using CUDA -using Oceananigans.Fields: ConstantField -using Oceananigans.Operators - -import Oceananigans.OutputWriters: checkpointer_address -import Oceananigans.OutputWriters: saveproperty! - -saveproperty!(file, address, p::ConstantField) = file[address] = p - -checkpointer_address(::SeaIceModel) = "SeaIceModel" - -function synch!(clock1::Clock, clock2) - # Synchronize the clocks - clock1.time = clock2.time - clock1.iteration = clock2.iteration - clock1.last_Δt = clock2.last_Δt -end - -synch!(model1, model2) = synch!(model1.clock, model2.clock) - -arch = GPU() -r_faces = ClimaOcean.exponential_z_faces(; Nz=60, depth=6200) -z_faces = MutableVerticalDiscretization(r_faces) - -Nx = 2160 # longitudinal direction -Ny = 1080 # meridional direction -Nz = length(r_faces) - 1 - -grid = TripolarGrid(arch; - size = (Nx, Ny, Nz), - z = z_faces, - halo = (7, 7, 7)) - -bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=10) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) - -##### -##### A Propgnostic Ocean model -##### - -using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization -using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation - -momentum_advection = WENOVectorInvariant() -tracer_advection = WENO(order=7) - -free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt=20minutes) - -# closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) -# closure = (ClimaOcean.OceanSimulations.default_ocean_closure(), VerticalScalarDiffusivity(κ=1e-5, ν=1e-5)) - -closure = RiBasedVerticalDiffusivity() - -ocean = ocean_simulation(grid; Δt=1minutes, - momentum_advection, - tracer_advection, - timestepper = :SplitRungeKutta3, - free_surface, - closure) - -dataset = ECCO4Monthly() - -set!(ocean.model, T=Metadatum(:temperature; dataset), - S=Metadatum(:salinity; dataset)) - -##### -##### A Prognostic Sea-ice model -##### - -sea_ice = sea_ice_simulation(grid, ocean; dynamics = nothing) #advection=WENO(order=7)) - -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), - ℵ=Metadatum(:sea_ice_concentration; dataset)) - -# using JLD2 -# file = jldopen("sea_ice_checkpoint_iteration10000.jld2") -# parent(sea_ice.model.ice_thickness) .= CuArray(file["SeaIceModel/h/data"]) -# parent(sea_ice.model.ice_concentration) .= CuArray(file["SeaIceModel/ℵ/data"]) -# parent(sea_ice.model.velocities.u) .= CuArray(file["SeaIceModel/u/data"]) -# parent(sea_ice.model.velocities.v) .= CuArray(file["SeaIceModel/v/data"]) - -##### -##### A Prescribed Atmosphere model -##### - -dir = "./forcing_data" -dataset = MultiYearJRA55() -backend = JRA55NetCDFBackend(40) - -atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) -radiation = Radiation(sea_ice_albedo=0.7) - -##### -##### An ocean-sea ice coupled model -##### - -omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=10, stop_time=Inf) - -synch!(sea_ice.model, ocean.model) -synch!(omip.model, ocean.model) - -# Figure out the outputs.... -ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, - schedule = IterationInterval(10000), - prefix = "ocean_checkpoint", - overwrite_existing = true) - -sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, - schedule = IterationInterval(10000), - prefix = "sea_ice_checkpoint", - overwrite_existing = true) - -uo = ocean.model.velocities.u -vo = ocean.model.velocities.v -wo = ocean.model.velocities.w -T, S = ocean.model.tracers -η = ocean.model.free_surface.η - -ui = sea_ice.model.velocities.u -vi = sea_ice.model.velocities.v -h = sea_ice.model.ice_thickness -ℵ = sea_ice.model.ice_concentration - -omip.output_writers[:ocean_free_surface] = JLD2Writer(ocean.model, (; η), - schedule = TimeInterval(1days), - filename = "ocean_free_surface", - overwrite_existing = true) - -omip.output_writers[:ocean_surface_fields] = JLD2Writer(ocean.model, (; uo, vo, wo, T, S), - schedule = TimeInterval(1days), - filename = "ocean_surface_fields", - indices = (:, :, grid.Nz), - overwrite_existing = true) - -omip.output_writers[:sea_ice_surface_fields] = JLD2Writer(sea_ice.model, (; ui, vi, h, ℵ), - schedule = TimeInterval(1days), - filename = "sea_ice_surface_fields", - overwrite_existing = true) - -wall_time = Ref(time_ns()) - -using Statistics - -function progress(sim) - sea_ice = sim.model.sea_ice - ocean = sim.model.ocean - hmax = maximum(sea_ice.model.ice_thickness) - ℵmax = maximum(sea_ice.model.ice_concentration) - Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) - Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) - umax = maximum(abs, ocean.model.velocities.u) - vmax = maximum(abs, ocean.model.velocities.v) - uimax = maximum(abs, sea_ice.model.velocities.u) - vimax = maximum(abs, sea_ice.model.velocities.v) - wmax = maximum(ocean.model.velocities.w) - - step_time = 1e-9 * (time_ns() - wall_time[]) - - msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) - msg2 = @sprintf("max(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) - msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) - msg5 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) - msg6 = @sprintf("wall time: %s \n", prettytime(step_time)) - - @info msg1 * msg2 * msg4 * msg5 * msg6 - - wall_time[] = time_ns() - - return nothing -end - -# And add it as a callback to the simulation. -add_callback!(omip, progress, IterationInterval(50)) -wizard = TimeStepWizard(cfl=0.7, max_change=1.1, max_Δt=20minutes) - -function sea_ice_cell_advection_timescale(grid, velocities) - u, v = velocities - τ = KernelFunctionOperation{Center, Center, Center}(cell_advection_timescaleᶜᶜ, grid, u, v) - return minimum(τ) -end - -@inline _inverse_timescale(i, j, k, Δ⁻¹, U, topo) = @inbounds abs(U[i, j, k]) * Δ⁻¹ -@inline _inverse_timescale(i, j, k, Δ⁻¹, U, topo::Flat) = 0 - -@inline function cell_advection_timescaleᶜᶜ(i, j, k, grid::AbstractGrid{FT, TX, TY}, u, v) where {FT, TX, TY} - Δx⁻¹ = Δx⁻¹ᶠᶜᶜ(i, j, k, grid) - Δy⁻¹ = Δy⁻¹ᶜᶠᶜ(i, j, k, grid) - - inverse_timescale_x = _inverse_timescale(i, j, k, Δx⁻¹, u, TX()) - inverse_timescale_y = _inverse_timescale(i, j, k, Δy⁻¹, v, TY()) - - inverse_timescale = inverse_timescale_x + inverse_timescale_y - - return 1 / inverse_timescale -end - -function add_wizard!(sim) - wizard(sim.model.ocean) - sea_ice = sim.model.sea_ice - Δti = 0.15 * sea_ice_cell_advection_timescale(sea_ice.model.grid, sea_ice.model.velocities) - @info "Wizard says: ocean Δt: $(ocean.Δt), sea ice Δt: $(Δti)" - iter = sea_ice.model.clock.iteration - Δtw = min(ocean.Δt, Δti) - - if iter < 5000 - sim.Δt = 60 - else - sim.Δt = Δtw - end - - @info "Final Δt is $(sim.Δt)" -end - -omip.callbacks[:wizard] = Callback(add_wizard!, IterationInterval(10)) - -run!(omip) diff --git a/ext/ClimaOceanPythonCallExt/clima_ocean_copernicus.jl b/ext/ClimaOceanPythonCallExt/clima_ocean_copernicus.jl index d89ba3d67..d3fd4689a 100644 --- a/ext/ClimaOceanPythonCallExt/clima_ocean_copernicus.jl +++ b/ext/ClimaOceanPythonCallExt/clima_ocean_copernicus.jl @@ -86,4 +86,4 @@ function depth_bounds_kw(z) minimum_depth = - z[2] maximum_depth = - z[1] return (; minimum_depth, maximum_depth) -end \ No newline at end of file +end diff --git a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl index 0b5c9f66a..a89dff53e 100644 --- a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl +++ b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl @@ -47,7 +47,7 @@ const CCField2D = Field{<:Center, <:Center, <:Nothing} const FCField2D = Field{<:Face, <:Center, <:Nothing} const CFField2D = Field{<:Center, <:Face, <:Nothing} -function set!(field::Field2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) +function set!(field::CCField2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) array = PyArray(pyarray) Nx, Ny, Nz = size(array) set!(field, view(array, 3:Nx-2, 3:Ny-2, k, 1)) diff --git a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl index 56954d6d9..05e172bab 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/interface_states.jl @@ -269,10 +269,9 @@ end # where Ωc (the sensible heat transfer coefficient) is given by Ωc = Qc / (Tₐ - Tˢ) # ⟹ Tₛ = (Tᵢ * k - (Qv + Qu + Qd + Ωc * Tₐ) * h / (k - Ωc * h) @inline function flux_balance_temperature(st::SkinTemperature{<:ClimaSeaIce.ConductiveFlux}, Ψₛ, ℙₛ, Qc, Qv, Qu, Qd, Ψᵢ, ℙᵢ, Ψₐ, ℙₐ) - F = st.internal_flux - k = F.conductivity - h = Ψᵢ.h - hc = Ψᵢ.hc # Critical thickness for ice consolidation + F = st.internal_flux + k = F.conductivity + h = Ψᵢ.h # Bottom temperature at the melting temperature Tᵢ = ClimaSeaIce.SeaIceThermodynamics.melting_temperature(ℙᵢ.liquidus, Ψᵢ.S) @@ -304,9 +303,6 @@ end Tₘ = convert_to_kelvin(ℙᵢ.temperature_units, Tₘ) Tₛ⁺ = min(Tₛ⁺, Tₘ) - # If the ice is not consolidated, use the bottom temperature - Tₛ⁺ = ifelse(h ≥ hc, Tₛ⁺, Tᵢ) - return Tₛ⁺ end diff --git a/src/OceanSeaIceModels/InterfaceComputations/roughness_lengths.jl b/src/OceanSeaIceModels/InterfaceComputations/roughness_lengths.jl index d7ca790a2..62845744a 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/roughness_lengths.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/roughness_lengths.jl @@ -20,25 +20,23 @@ Base.show(io::IO, ::ScalarRoughnessLength{FT}) where FT = print(io, "ScalarRough struct WindDependentWaveFormulation{FT} Umax :: FT - αmin :: FT ℂ₁ :: FT ℂ₂ :: FT end """ WindDependentWaveFormulation(FT = Oceananigans.defaults.FloatType; - Umax = 19, αmin = 0.011, ℂ₁ = 0.0017, ℂ₂ = -0.005) + Umax = 19, ℂ₁ = 0.0017, ℂ₂ = -0.005) -A gravity wave parameter based on the wind speed `ΔU` with the formula `max(αmin, ℂ₁ * min(ΔU, Umax) + ℂ₂`). +A gravity wave parameter based on the wind speed `ΔU` with the formula `ℂ₁ * max(ΔU, Umax) + ℂ₂`. """ -WindDependentWaveFormulation(FT=Oceananigans.defaults.FloatType; Umax = 19, αmin = 0.011, ℂ₁ = 0.0017, ℂ₂ = -0.005) = +WindDependentWaveFormulation(FT=Oceananigans.defaults.FloatType; Umax = 19, ℂ₁ = 0.0017, ℂ₂ = -0.005) = WindDependentWaveFormulation(convert(FT, Umax), - convert(FT, αmin), convert(FT, ℂ₁), convert(FT, ℂ₂)) gravity_wave_parameter(α::Number, args...) = α -gravity_wave_parameter(α::WindDependentWaveFormulation, ΔU) = max(α.αmin, α.ℂ₁ * min(ΔU, α.Umax) + α.ℂ₂) +gravity_wave_parameter(α::WindDependentWaveFormulation, ΔU) = α.ℂ₁ * max(ΔU, α.Umax) + α.ℂ₂ """ ScalarRoughnessLength(FT = Float64; @@ -90,7 +88,7 @@ function MomentumRoughnessLength(FT=Oceananigans.defaults.FloatType; gravitational_acceleration = default_gravitational_acceleration, maximum_roughness_length = 1, air_kinematic_viscosity = 1.5e-5, - wave_formulation = WindDependentWaveFormulation(FT), + wave_formulation = 0.02, smooth_wall_parameter = 0.11) if wave_formulation isa Number diff --git a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl index 537caae86..401e49fb1 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl @@ -24,7 +24,6 @@ struct SimilarityTheoryFluxes{FT, UF, R, B, S} von_karman_constant :: FT # parameter turbulent_prandtl_number :: FT # parameter gustiness_parameter :: FT # bulk velocity parameter - minimum_velocity_scale :: FT # minimum velocity scale stability_functions :: UF # functions for turbulent fluxes roughness_lengths :: R # parameterization for turbulent fluxes similarity_form :: B # similarity profile relating atmosphere to interface state @@ -35,7 +34,6 @@ Adapt.adapt_structure(to, fluxes::SimilarityTheoryFluxes) = SimilarityTheoryFluxes(adapt(to, fluxes.von_karman_constant), adapt(to, fluxes.turbulent_prandtl_number), adapt(to, fluxes.gustiness_parameter), - adapt(to, fluxes.minimum_velocity_scale), adapt(to, fluxes.stability_functions), adapt(to, fluxes.roughness_lengths), adapt(to, fluxes.similarity_form), @@ -89,12 +87,11 @@ Keyword Arguments function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; von_karman_constant = 0.4, turbulent_prandtl_number = 1, - gustiness_parameter = 2, + gustiness_parameter = 1, stability_functions = atmosphere_ocean_stability_functions(FT), momentum_roughness_length = MomentumRoughnessLength(FT), temperature_roughness_length = ScalarRoughnessLength(FT), water_vapor_roughness_length = ScalarRoughnessLength(FT), - minimum_velocity_scale = 0.5, similarity_form = LogarithmicSimilarityProfile(), solver_stop_criteria = nothing, solver_tolerance = 1e-8, @@ -117,7 +114,6 @@ function SimilarityTheoryFluxes(FT::DataType = Oceananigans.defaults.FloatType; return SimilarityTheoryFluxes(convert(FT, von_karman_constant), convert(FT, turbulent_prandtl_number), convert(FT, gustiness_parameter), - convert(FT, minimum_velocity_scale), stability_functions, roughness_lengths, similarity_form, @@ -207,8 +203,7 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes, approximate_interface_state) U = sqrt(Δu^2 + Δv^2 + Uᴳ^2) - U = max(U, flux_formulation.minimum_velocity_scale) - + # Compute roughness length scales ℓu₀ = roughness_length(ℓu, u★, U, 𝒬ₛ, ℂₐ) ℓq₀ = roughness_length(ℓq, ℓu₀, u★, U, 𝒬ₛ, ℂₐ) diff --git a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl index 937d11654..0c8d3cc47 100644 --- a/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl +++ b/src/OceanSeaIceModels/time_step_ocean_sea_ice_model.jl @@ -7,7 +7,6 @@ using .InterfaceComputations: using ClimaSeaIce: SeaIceModel, SeaIceThermodynamics using Oceananigans.Grids: φnode -using Oceananigans.Simulations: TimeStepWizard using Printf @@ -21,10 +20,10 @@ function time_step!(coupled_model::OceanSeaIceModel, Δt; callbacks=[], compute_ # TODO after ice time-step: # - Adjust ocean heat flux if the ice completely melts? - !isnothing(ocean) && time_step!(ocean, Δt) + time_step!(ocean, Δt) # Time step the atmosphere - !isnothing(atmosphere) && time_step!(atmosphere, Δt) + time_step!(atmosphere, Δt) # TODO: # - Store fractional ice-free / ice-covered _time_ for more @@ -52,27 +51,3 @@ function update_state!(coupled_model::OceanSeaIceModel, callbacks=[]; compute_te return nothing end - -function (wizard::TimeStepWizard)(simulation::Simulation{<:OceanSeaIceModel}) - model = simulation.model - ocean_Δt = wizard(model.ocean) - - sea_ice_Δt = if isnothing(model.sea_ice) - Inf - else - wizard(model.sea_ice) - end - - atmosphere_Δt = if isnothing(model.atmosphere) - Inf - else - wizard(model.atmosphere) - end - - Δt = min(ocean_Δt, sea_ice_Δt, atmosphere_Δt) - - simulation.Δt = Δt - - return nothing -end - diff --git a/src/SeaIceSimulations.jl b/src/SeaIceSimulations.jl index 809905097..41aaf9cda 100644 --- a/src/SeaIceSimulations.jl +++ b/src/SeaIceSimulations.jl @@ -17,11 +17,10 @@ using Oceananigans.Operators using ClimaSeaIce using ClimaSeaIce: SeaIceModel, SlabSeaIceThermodynamics, PhaseTransitions, ConductiveFlux using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium -using ClimaSeaIce.Rheologies using ClimaSeaIce.SeaIceDynamics: SplitExplicitSolver, SemiImplicitStress, SeaIceMomentumEquation, StressBalanceFreeDrift using ClimaSeaIce.Rheologies: IceStrength, ElastoViscoPlasticRheology -using ClimaOcean.OceanSimulations: Default, u_immersed_bottom_drag, v_immersed_bottom_drag +using ClimaOcean.OceanSimulations: Default function sea_ice_simulation(grid, ocean=nothing; Δt = 5minutes, @@ -63,14 +62,6 @@ function sea_ice_simulation(grid, ocean=nothing; bottom_heat_flux = Field{Center, Center, Nothing}(grid) top_heat_flux = Field{Center, Center, Nothing}(grid) - u_bc = FluxBoundaryCondition(u_immersed_bottom_drag, discrete_form=true, parameters=1e-1) - v_bc = FluxBoundaryCondition(v_immersed_bottom_drag, discrete_form=true, parameters=1e-1) - - # immersed_u_bc = ImmersedBoundaryConditions(top=nothing, bottom=nothing, west=nothing, east=nothing, south=u_bc, north=u_bc) - # immersed_v_bc = ImmersedBoundaryConditions(top=nothing, bottom=nothing, south=nothing, north=nothing, west=v_bc, east=v_bc) - # u_bcs = FieldBoundaryConditions(grid, (Face(), Center(), nothing); immersed = immersed_u_bc) - # v_bcs = FieldBoundaryConditions(grid, (Center(), Face(), nothing); immersed = immersed_v_bc) - # Build the sea ice model sea_ice_model = SeaIceModel(grid; ice_salinity, @@ -90,17 +81,12 @@ function sea_ice_simulation(grid, ocean=nothing; return sea_ice end -default_solver(::Nothing) = SplitExplicitSolver(120) -default_solver(ocean::Simulation) = default_solver(ocean.model.timestepper) -default_solver(::Oceananigans.TimeSteppers.QuasiAdamsBashforth2TimeStepper) = SplitExplicitSolver(120) -default_solver(::Oceananigans.TimeSteppers.SplitRungeKutta3TimeStepper) = SplitExplicitSolver(360) - function sea_ice_dynamics(grid, ocean=nothing; - sea_ice_ocean_drag_coefficient = 2.5e-3, + sea_ice_ocean_drag_coefficient = 5.5e-3, rheology = ElastoViscoPlasticRheology(), coriolis = nothing, free_drift = nothing, - solver = default_solver(ocean)) + solver = SplitExplicitSolver(120)) if isnothing(ocean) SSU = Oceananigans.Fields.ZeroField() diff --git a/test/test_jra55.jl b/test/test_jra55.jl index 481fdd05e..5d45ba471 100644 --- a/test/test_jra55.jl +++ b/test/test_jra55.jl @@ -1,6 +1,5 @@ include("runtests_setup.jl") -using ClimaOcean.JRA55 using ClimaOcean.JRA55: download_JRA55_cache using ClimaOcean.OceanSeaIceModels: PrescribedAtmosphere From 5b03a330efebe2e29cda78c064d568f8141c1e97 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 11:42:01 +0200 Subject: [PATCH 188/203] add veros --- CondaPkg.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/CondaPkg.toml b/CondaPkg.toml index 5bc3f6e47..f7b6a5d50 100644 --- a/CondaPkg.toml +++ b/CondaPkg.toml @@ -5,3 +5,4 @@ jax = ">=0.6" copernicusmarine = ">=2.0.0" numpy = "==2.3.1" tensorflow = ">=2.17" +veros = "" From 5843397565c484524b8cde3b72f87dd71725bde0 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 11:56:31 +0200 Subject: [PATCH 189/203] add the veros experiment --- experiments/veros_forced_simulation.jl | 40 +++++++++++++++- .../veros_ocean_simulation.jl | 48 ++++++++++++++++--- 2 files changed, 80 insertions(+), 8 deletions(-) diff --git a/experiments/veros_forced_simulation.jl b/experiments/veros_forced_simulation.jl index 3a6cc7403..9e2f38243 100644 --- a/experiments/veros_forced_simulation.jl +++ b/experiments/veros_forced_simulation.jl @@ -3,17 +3,51 @@ using PythonCall using Oceananigans using Printf +##### +##### A Prognostic Python Ocean (Veros) Simulation +##### + +# We import the Veros 4 degree ocean simulation setup, which consists of a near-global ocean +# with a uniform resolution of 4 degrees in both latitude and longitude and a latitude range spanning +# from 80S to 80N. The setup is defined in the `veros.setups.global_4deg` module. + +# Before importing the setup, we need to ensure that the Veros module is loaded +# and that every output is removed to avoid conflicts. + VerosModule = Base.get_extension(ClimaOcean, :ClimaOceanPythonCallExt) VerosModule.remove_outputs(:global_4deg) -ocean = VerosModule.veros_ocean_simulation("global_4deg", :GlobalFourDegreeSetup) +# Actually loading and instantiating the Veros setup in the variable `ocean`. +# This setup uses by default a different time-step for tracers and momentum, +# so we set it to the same value (1800 seconds) for both. + +ocean = VerosModule.VerosOceanSimulation("global_4deg", :GlobalFourDegreeSetup) + VerosModule.veros_settings_set!(ocean, "dt_tracer", 1800.0) +VerosModule.veros_settings_set!(ocean, "dt_momentum", 1800.0) + +##### +##### A Prescribed Atmosphere (JRA55) +##### atmos = JRA55PrescribedAtmosphere(; backend = JRA55NetCDFBackend(10)) + +##### +##### An ice-free ocean forced by a prescribed atmosphere +##### + radiation = Radiation() coupled_model = OceanSeaIceModel(ocean, nothing; atmosphere=atmos, radiation) simulation = Simulation(coupled_model; Δt = 1800, stop_iteration = 100000) +##### +##### A simple progress callback +##### + +# We set up a progress callback that will print the current time, iteration, and maximum velocities +# at every 5 iterations. It also collects the surface velocity fields and the net fluxes +# into the arrays `s`, `tx`, and `ty` for later visualization. + wall_time = Ref(time_ns()) s = [] @@ -51,4 +85,8 @@ end add_callback!(simulation, progress, IterationInterval(5)) +##### +##### Let's go!! +##### + run!(simulation) diff --git a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl index a89dff53e..86f0efe89 100644 --- a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl +++ b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl @@ -14,7 +14,7 @@ import Base: eltype """ install_veros() -Install the Copernicus Marine CLI using CondaPkg. +Install the Veros ocean model Marine CLI using CondaPkg. Returns a NamedTuple containing package information if successful. """ function install_veros() @@ -70,7 +70,18 @@ function set!(field::CFField2D, pyarray::Py, k=pyconvert(Int, pyarray.shape[2])) return field end -function veros_ocean_simulation(setup, setup_name) +""" + VerosOceanSimulation(setup, setup_name::Symbol) + +Creates and initializes a preconfigured Veros ocean simulation using the +specified setup module and setup name. + +Arguments +========== +- `setup::AbstractString`: The name of the Veros setup module to import (e.g., `"global_4deg"`). +- `setup_name::Symbol`: The name of the setup class or function within the module to instantiate (e.g., `:GlobalFourDegreeSetup`). +""" +function VerosOceanSimulation(setup, setup_name::Symbol) setups = pyimport("veros.setups." * setup) setup = @eval $setups.$setup_name() @@ -80,6 +91,18 @@ function veros_ocean_simulation(setup, setup_name) return VerosOceanSimulation(setup) end +""" + surface_grid(ocean::VerosOceanSimulation) + +Constructs a `LatitudeLongitudeGrid` representing the surface grid of the given `VerosOceanSimulation` object. +Notes: Veros always uses a LatitudeLongitudeGrid with 2 halos in both the latitude and longitude directions. +Both latitude and longitude can be either stretched or uniform, depending on the setup, and while the meridional +direction (latitude) is always Bounded, the zonal direction (longitude) can be either Periodic or Bounded. + +Arguments +========== +- `ocean::VerosOceanSimulation`: The ocean simulation object containing the grid state variables. +""" function surface_grid(ocean::VerosOceanSimulation) xf = Array(PyArray(ocean.setup.state.variables.xu)) @@ -109,20 +132,31 @@ function surface_grid(ocean::VerosOceanSimulation) return LatitudeLongitudeGrid(size=(Nx, Ny), longitude=xf, latitude=yf, topology=(TX, Bounded, Flat), halo=(2, 2)) end +""" + veros_set!(ocean, v, x) + +Set the `v` variable in the `ocean` model to the value of `x`. +""" function veros_set!(ocean::VerosOceanSimulation, v, x) - s = ocean.setup + setup = ocean.setup pyexec(""" with setup.state.variables.unlock(): setup.state.variables.__setattr__(y, t) - """, Main, (y=v, t=x, setup=s)) + """, Main, (y=v, t=x, setup=setup)) end -function veros_settings_set!(ocean::VerosOceanSimulation, v, x) - s = ocean.setup + +""" + veros_settings_set!(ocean, v, x) + +Set the `s` setting in the `ocean` model to the value of `x`. +""" +function veros_settings_set!(ocean::VerosOceanSimulation, s, x) + setup = ocean.setup pyexec(""" with setup.state.settings.unlock(): setup.state.settings.__setattr__(y, t) - """, Main, (y=v, t=x, setup=s)) + """, Main, (y=s, t=x, setup=setup)) end function OceanSeaIceModel(ocean::VerosOceanSimulation, sea_ice=nothing; From cc6ca112cd217e2d4ce6c2a962487aabe392b906 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 11:59:27 +0200 Subject: [PATCH 190/203] dt mom not dt tracer --- experiments/veros_forced_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/veros_forced_simulation.jl b/experiments/veros_forced_simulation.jl index 9e2f38243..811d12b90 100644 --- a/experiments/veros_forced_simulation.jl +++ b/experiments/veros_forced_simulation.jl @@ -24,7 +24,7 @@ VerosModule.remove_outputs(:global_4deg) ocean = VerosModule.VerosOceanSimulation("global_4deg", :GlobalFourDegreeSetup) VerosModule.veros_settings_set!(ocean, "dt_tracer", 1800.0) -VerosModule.veros_settings_set!(ocean, "dt_momentum", 1800.0) +VerosModule.veros_settings_set!(ocean, "dt_mom", 1800.0) ##### ##### A Prescribed Atmosphere (JRA55) From 267d985ca9de26f256f00ff13c76bbfe6548efdf Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 22 Aug 2025 10:47:58 +0200 Subject: [PATCH 191/203] Apply suggestion from @glwagner Co-authored-by: Gregory L. Wagner --- .../InterfaceComputations/assemble_net_fluxes.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index fca4ad5ec..9ddc59989 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -60,7 +60,8 @@ function compute_net_ocean_fluxes!(coupled_model) freshwater_flux = atmosphere_fields.Mp.data ice_concentration = sea_ice_concentration(sea_ice) - ocean_salinity = get_ocean_state(coupled_model.ocean, coupled_model.interfaces.exchanger).S + ocean_state = get_ocean_state(coupled_model.ocean, coupled_model.interfaces.exchanger) + ocean_salinity = ocean_state.S atmos_ocean_properties = coupled_model.interfaces.atmosphere_ocean_interface.properties ocean_properties = coupled_model.interfaces.ocean_properties kernel_parameters = interface_kernel_parameters(grid) From 86026841ae3c2cdce8f62c2c17a782ce868509c1 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 22 Aug 2025 10:48:25 +0200 Subject: [PATCH 192/203] Apply suggestion from @glwagner Co-authored-by: Gregory L. Wagner --- .../InterfaceComputations/assemble_net_fluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index 9ddc59989..60326e236 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -85,7 +85,7 @@ function compute_net_ocean_fluxes!(coupled_model) atmos_ocean_properties, ocean_properties) - fill_up_net_fluxes!(coupled_model.ocean, net_ocean_fluxes) + fill_net_fluxes!(coupled_model.ocean, net_ocean_fluxes) return nothing end From d45906be329c0a1a44097cdc037a13554a64978d Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 22 Aug 2025 10:49:11 +0200 Subject: [PATCH 193/203] Update assemble_net_fluxes.jl --- .../InterfaceComputations/assemble_net_fluxes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl index 60326e236..1fefa089f 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl @@ -32,7 +32,7 @@ end end # No need to do this for an Oceananigans Simulation -fill_up_net_fluxes!(ocean, net_ocean_fluxes) = nothing +fill_net_fluxes!(ocean, net_ocean_fluxes) = nothing function compute_net_ocean_fluxes!(coupled_model) sea_ice = coupled_model.sea_ice From 29c70ca5683fcbebe9bfaaddc5d06a8ff0594fcb Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 22 Aug 2025 10:49:28 +0200 Subject: [PATCH 194/203] Rename fill_up_net_fluxes! to fill_net_fluxes! --- ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index 989f7432a..0e33577c7 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -82,7 +82,7 @@ end @inline get_radiative_forcing(ocean::VerosOceanSimulation) = nothing -function fill_up_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) +function fill_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) nx = pyconvert(Int, ocean.setup.state.settings.nx) + 4 ny = pyconvert(Int, ocean.setup.state.settings.ny) + 4 t1 = view(parent(net_ocean_fluxes.u), 1:nx, 1:ny, 1) @@ -111,4 +111,4 @@ function fill_up_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) # veros_set!(ocean, "salt_flux", t2) return nothing -end \ No newline at end of file +end From c7ee9ade9f50787457dc3506ee2a3e975d07c658 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 22 Aug 2025 11:43:39 +0200 Subject: [PATCH 195/203] Update ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl Co-authored-by: Gregory L. Wagner --- ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl b/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl index 0d0feabae..d00b4b172 100644 --- a/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl +++ b/ext/ClimaOceanPythonCallExt/ClimaOceanPythonCallExt.jl @@ -8,7 +8,7 @@ using Oceananigans.DistributedComputations: @root using Dates: DateTime -include("clima_ocean_copernicus.jl") +include("copernicus.jl") include("veros_ocean_simulation.jl") include("veros_state_exchanger.jl") From c7dbcb0a52e2a8cab0d680b2f1f3c35f9573511d Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 22 Aug 2025 11:48:16 +0200 Subject: [PATCH 196/203] overload the set! function --- experiments/veros_forced_simulation.jl | 4 +-- ...lima_ocean_copernicus.jl => copernicus.jl} | 0 .../veros_ocean_simulation.jl | 27 +++++-------------- .../veros_state_exchanger.jl | 10 +++---- 4 files changed, 13 insertions(+), 28 deletions(-) rename ext/ClimaOceanPythonCallExt/{clima_ocean_copernicus.jl => copernicus.jl} (100%) diff --git a/experiments/veros_forced_simulation.jl b/experiments/veros_forced_simulation.jl index 811d12b90..6086a5a58 100644 --- a/experiments/veros_forced_simulation.jl +++ b/experiments/veros_forced_simulation.jl @@ -23,8 +23,8 @@ VerosModule.remove_outputs(:global_4deg) ocean = VerosModule.VerosOceanSimulation("global_4deg", :GlobalFourDegreeSetup) -VerosModule.veros_settings_set!(ocean, "dt_tracer", 1800.0) -VerosModule.veros_settings_set!(ocean, "dt_mom", 1800.0) +set!(ocean.setup.settings, "dt_tracer", 1800.0) +set!(ocean.setup.settings, "dt_mom", 1800.0) ##### ##### A Prescribed Atmosphere (JRA55) diff --git a/ext/ClimaOceanPythonCallExt/clima_ocean_copernicus.jl b/ext/ClimaOceanPythonCallExt/copernicus.jl similarity index 100% rename from ext/ClimaOceanPythonCallExt/clima_ocean_copernicus.jl rename to ext/ClimaOceanPythonCallExt/copernicus.jl diff --git a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl index 86f0efe89..655bdcc53 100644 --- a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl +++ b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl @@ -133,30 +133,15 @@ function surface_grid(ocean::VerosOceanSimulation) end """ - veros_set!(ocean, v, x) + set!(class::Py, v, x) -Set the `v` variable in the `ocean` model to the value of `x`. +Set the `s` property of a Python `class` to the value of `x`. """ -function veros_set!(ocean::VerosOceanSimulation, v, x) - setup = ocean.setup +function set!(class::Py, s, x) pyexec(""" - with setup.state.variables.unlock(): - setup.state.variables.__setattr__(y, t) - """, Main, (y=v, t=x, setup=setup)) -end - - -""" - veros_settings_set!(ocean, v, x) - -Set the `s` setting in the `ocean` model to the value of `x`. -""" -function veros_settings_set!(ocean::VerosOceanSimulation, s, x) - setup = ocean.setup - pyexec(""" - with setup.state.settings.unlock(): - setup.state.settings.__setattr__(y, t) - """, Main, (y=s, t=x, setup=setup)) + with class.unlock(): + class.__setattr__(y, t) + """, Main, (y=s, t=x, class=class)) end function OceanSeaIceModel(ocean::VerosOceanSimulation, sea_ice=nothing; diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index 0e33577c7..e206f4bbf 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -13,7 +13,7 @@ import ClimaOcean.OceanSeaIceModels.InterfaceComputations: get_ocean_state, ocean_surface_fluxes, get_radiative_forcing, - fill_up_net_fluxes! + fill_net_fluxes! mutable struct VerosStateExchanger{G, OST, AST, AEX} exchange_grid :: G @@ -97,8 +97,8 @@ function fill_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) tb[:, :, t] .= t2 end - veros_set!(ocean, "taux", ta) - veros_set!(ocean, "tauy", tb) + set!(ocean.state.variables, "taux", ta) + set!(ocean.state.variables, "tauy", tb) # TODO: Add heat flux and salinity flux when they # fix veros to be able to force with prescribed boundary @@ -107,8 +107,8 @@ function fill_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) # t1 = view(parent(net_ocean_fluxes.T), 1:nx, 2:ny+1, 1) # t2 = view(parent(net_ocean_fluxes.S), 1:nx, 2:ny+1, 1) - # veros_set!(ocean, "temp_flux", t1) - # veros_set!(ocean, "salt_flux", t2) + # set!(ocean, "temp_flux", t1) + # set!(ocean, "salt_flux", t2) return nothing end From ac8d821ba43989cecad78c7a4c2b310ab932c60e Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 22 Aug 2025 13:20:48 +0200 Subject: [PATCH 197/203] bugfix --- ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl | 5 +++-- .../InterfaceComputations/component_interfaces.jl | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index e206f4bbf..8344e20af 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -70,14 +70,15 @@ initialize!(exchanger::VerosStateExchanger, atmosphere) = return (; u, v, T, S) end -@inline function ocean_surface_fluxes(ocean::VerosOceanSimulation) +@inline function ocean_surface_fluxes(ocean::VerosOceanSimulation, ρₒ, cₒ) grid = surface_grid(ocean) u = Field{Face, Center, Nothing}(grid) v = Field{Center, Face, Nothing}(grid) T = Field{Center, Center, Nothing}(grid) S = Field{Center, Center, Nothing}(grid) + Q = ρₒ * cₒ * T - return (; u, v, T, S) + return (; u, v, T, S, Q) end @inline get_radiative_forcing(ocean::VerosOceanSimulation) = nothing diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index 581333c1a..08a2cb885 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -297,7 +297,7 @@ function default_ao_specific_humidity(ocean) return ImpureSaturationSpecificHumidity(phase, x_H₂O) end -function ocean_surface_fluxes(ocean::OceananigansSimulation) +function ocean_surface_fluxes(ocean::OceananigansSimulation, ρₒ, cₒ) τx = surface_flux(ocean.model.velocities.u) τy = surface_flux(ocean.model.velocities.v) tracers = ocean.model.tracers @@ -403,7 +403,7 @@ function ComponentInterfaces(atmosphere, ocean, sea_ice=nothing; net_bottom_sea_ice_fluxes = nothing end - net_ocean_surface_fluxes = ocean_surface_fluxes(ocean) + net_ocean_surface_fluxes = ocean_surface_fluxes(ocean, ocean_reference_density, ocean_heat_capacity) # Total interface fluxes net_fluxes = (ocean_surface = net_ocean_surface_fluxes, From 2d0c16be8b711cb625c6c7adf2c8c4cbeec58e80 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 22 Aug 2025 14:15:39 +0200 Subject: [PATCH 198/203] bugfix --- .../InterfaceComputations/component_interfaces.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl index 08a2cb885..0f188105c 100644 --- a/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl +++ b/src/OceanSeaIceModels/InterfaceComputations/component_interfaces.jl @@ -301,8 +301,6 @@ function ocean_surface_fluxes(ocean::OceananigansSimulation, ρₒ, cₒ) τx = surface_flux(ocean.model.velocities.u) τy = surface_flux(ocean.model.velocities.v) tracers = ocean.model.tracers - ρₒ = ocean_reference_density - cₒ = ocean_heat_capacity Qₒ = ρₒ * cₒ * surface_flux(ocean.model.tracers.T) net_ocean_surface_fluxes = (u=τx, v=τy, Q=Qₒ) From 2debe0e437a5e505279e3648c397ad99e4e53998 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Fri, 22 Aug 2025 22:14:49 +0200 Subject: [PATCH 199/203] bugfix --- .../veros_state_exchanger.jl | 37 +++++++------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index 8344e20af..535cfd79f 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -86,30 +86,19 @@ end function fill_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) nx = pyconvert(Int, ocean.setup.state.settings.nx) + 4 ny = pyconvert(Int, ocean.setup.state.settings.ny) + 4 - t1 = view(parent(net_ocean_fluxes.u), 1:nx, 1:ny, 1) - t2 = view(parent(net_ocean_fluxes.v), 1:nx, 1:ny, 1) - - # TODO: Remove this when they fix veros to - # be able to force with an array instead of Climatology - ta = zeros(size(t1)..., 12) - tb = zeros(size(t2)..., 12) - for t in 1:12 - ta[:, :, t] .= t1 - tb[:, :, t] .= t2 - end - - set!(ocean.state.variables, "taux", ta) - set!(ocean.state.variables, "tauy", tb) - - # TODO: Add heat flux and salinity flux when they - # fix veros to be able to force with prescribed boundary - # conditions rather than restoring - - # t1 = view(parent(net_ocean_fluxes.T), 1:nx, 2:ny+1, 1) - # t2 = view(parent(net_ocean_fluxes.S), 1:nx, 2:ny+1, 1) - - # set!(ocean, "temp_flux", t1) - # set!(ocean, "salt_flux", t2) + + ρₒ = pyconvert(eltype(ocean), ocean.state.variables.density) + taux = view(parent(net_ocean_fluxes.u), 1:nx, 1:ny, 1) .* ρₒ + tauy = view(parent(net_ocean_fluxes.v), 1:nx, 1:ny, 1) .* ρₒ + + set!(ocean.state.variables, "taux", taux) + set!(ocean.state.variables, "tauy", tauy) + + temp_flux = view(parent(net_ocean_fluxes.T), 1:nx, 1:ny, 1) + salt_flux = view(parent(net_ocean_fluxes.S), 1:nx, 1:ny, 1) + + set!(ocean.state.variables, "temp_flux", temp_flux) + set!(ocean.state.variables, "salt_flux", salt_flux) return nothing end From b3c6c4699e95ecffc8d4036b65a4a4ba86931487 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 26 Aug 2025 14:51:42 +0200 Subject: [PATCH 200/203] fixed it --- experiments/veros_forced_simulation.jl | 4 +-- .../veros_ocean_simulation.jl | 26 ++++++++++++++----- .../veros_state_exchanger.jl | 12 ++++----- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/experiments/veros_forced_simulation.jl b/experiments/veros_forced_simulation.jl index 6086a5a58..39d2d9749 100644 --- a/experiments/veros_forced_simulation.jl +++ b/experiments/veros_forced_simulation.jl @@ -23,8 +23,8 @@ VerosModule.remove_outputs(:global_4deg) ocean = VerosModule.VerosOceanSimulation("global_4deg", :GlobalFourDegreeSetup) -set!(ocean.setup.settings, "dt_tracer", 1800.0) -set!(ocean.setup.settings, "dt_mom", 1800.0) +set!(ocean, "dt_tracer", 1800.0; path=:settings) +set!(ocean, "dt_mom", 1800.0; path=:settings) ##### ##### A Prescribed Atmosphere (JRA55) diff --git a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl index 655bdcc53..2e6b99115 100644 --- a/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl +++ b/ext/ClimaOceanPythonCallExt/veros_ocean_simulation.jl @@ -133,15 +133,27 @@ function surface_grid(ocean::VerosOceanSimulation) end """ - set!(class::Py, v, x) + set!(ocean, v, x; path = :variable) -Set the `s` property of a Python `class` to the value of `x`. +Set the `v` variable in the `ocean` model to the value of `x`. +the path corresponds to the path inside the class where to locate the +variable `v` to set. It can be either `:variables` or `:settings`. """ -function set!(class::Py, s, x) - pyexec(""" - with class.unlock(): - class.__setattr__(y, t) - """, Main, (y=s, t=x, class=class)) +function set!(ocean::VerosOceanSimulation, v, x; path = :variables) + setup = ocean.setup + if path == :variables + pyexec(""" + with setup.state.variables.unlock(): + setup.state.variables.__setattr__(y, t) + """, Main, (y=v, t=x, setup=setup)) + elseif path == :settings + pyexec(""" + with setup.state.settings.unlock(): + setup.state.settings.__setattr__(y, t) + """, Main, (y=v, t=x, setup=setup)) + else + error("path must be either :variable or :settings.") + end end function OceanSeaIceModel(ocean::VerosOceanSimulation, sea_ice=nothing; diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index 535cfd79f..6f73befea 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -86,19 +86,19 @@ end function fill_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) nx = pyconvert(Int, ocean.setup.state.settings.nx) + 4 ny = pyconvert(Int, ocean.setup.state.settings.ny) + 4 - - ρₒ = pyconvert(eltype(ocean), ocean.state.variables.density) + + ρₒ = pyconvert(eltype(ocean), ocean.setup.state.settings.rho_0) taux = view(parent(net_ocean_fluxes.u), 1:nx, 1:ny, 1) .* ρₒ tauy = view(parent(net_ocean_fluxes.v), 1:nx, 1:ny, 1) .* ρₒ - set!(ocean.state.variables, "taux", taux) - set!(ocean.state.variables, "tauy", tauy) + set!(ocean, "taux", taux; path=:variables) + set!(ocean, "tauy", tauy; path=:variables) temp_flux = view(parent(net_ocean_fluxes.T), 1:nx, 1:ny, 1) salt_flux = view(parent(net_ocean_fluxes.S), 1:nx, 1:ny, 1) - set!(ocean.state.variables, "temp_flux", temp_flux) - set!(ocean.state.variables, "salt_flux", salt_flux) + set!(ocean, "temp_flux", temp_flux; path=:variables) + set!(ocean, "salt_flux", salt_flux; path=:variables) return nothing end From 8cfb21db7322ff396ca79ba2e370eca9285aa872 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 26 Aug 2025 14:56:17 +0200 Subject: [PATCH 201/203] let's go --- .../veros_state_exchanger.jl | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index 6f73befea..4447f7dc7 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -91,14 +91,24 @@ function fill_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) taux = view(parent(net_ocean_fluxes.u), 1:nx, 1:ny, 1) .* ρₒ tauy = view(parent(net_ocean_fluxes.v), 1:nx, 1:ny, 1) .* ρₒ - set!(ocean, "taux", taux; path=:variables) - set!(ocean, "tauy", tauy; path=:variables) - - temp_flux = view(parent(net_ocean_fluxes.T), 1:nx, 1:ny, 1) - salt_flux = view(parent(net_ocean_fluxes.S), 1:nx, 1:ny, 1) - - set!(ocean, "temp_flux", temp_flux; path=:variables) - set!(ocean, "salt_flux", salt_flux; path=:variables) + # TODO: Do not do this 12 thingy when we can make sure + # that veros supports it + tx = zeros(size(taux)..., 12) + ty = zeros(size(tauy)..., 12) + for t in 1:12 + tx[:, :, t] .= taux + ty[:, :, t] .= tauy + end + + set!(ocean, "taux", tx; path=:variables) + set!(ocean, "tauy", ty; path=:variables) + + # TODO: uncomment below when the new branch gets merged + # temp_flux = view(parent(net_ocean_fluxes.T), 1:nx, 1:ny, 1) + # salt_flux = view(parent(net_ocean_fluxes.S), 1:nx, 1:ny, 1) + + # set!(ocean, "temp_flux", temp_flux; path=:variables) + # set!(ocean, "salt_flux", salt_flux; path=:variables) return nothing end From 88e937ca21f06b29f7a16b971bd14ec3edb2f945 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Tue, 26 Aug 2025 15:55:13 +0200 Subject: [PATCH 202/203] add visualization --- experiments/veros_forced_simulation.jl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/experiments/veros_forced_simulation.jl b/experiments/veros_forced_simulation.jl index 39d2d9749..52d0ed853 100644 --- a/experiments/veros_forced_simulation.jl +++ b/experiments/veros_forced_simulation.jl @@ -90,3 +90,24 @@ add_callback!(simulation, progress, IterationInterval(5)) ##### run!(simulation) + +##### +##### Visualize +##### + +iter = Observable(1) +si = @lift(s[$iter]) +txi = @lift(tx[$iter]) +tyi = @lift(ty[$iter]) + +fig = Figure(resolution = (1200, 300)) +ax1 = Axis(fig[1, 1]; title = "Surface speed (m/s)", xlabel = "Longitude", ylabel = "Latitude") +ax2 = Axis(fig[1, 2]; title = "Zonal wind stress (N/m²)", xlabel = "Longitude") +ax3 = Axis(fig[1, 3]; title = "Meridional wind stress (N/m²)", xlabel = "Longitude") + +grid = coupled_model.interfaces.exchanger.exchange_grid +λ = λnodes(grid, Center()) +φ = φnodes(grid, Center()) +heatmap!(ax1, λ, φ, si, colormap = :ice, colorrange = (0, 0.15)) +heatmap!(ax2, λ, φ, txi, colormap = :bwr, colorrange = (-0.2, 0.2)) +heatmap!(ax3, λ, φ, tyi, colormap = :bwr, colorrange = (-0.2, 0.2)) \ No newline at end of file From 62a3cc82474f70221006913f35b3c2e2e1bcf963 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 13 Oct 2025 12:14:12 +0200 Subject: [PATCH 203/203] Update TODO comment for fluxes BC in veros --- ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl index 4447f7dc7..ab1a8ac34 100644 --- a/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl +++ b/ext/ClimaOceanPythonCallExt/veros_state_exchanger.jl @@ -103,7 +103,7 @@ function fill_net_fluxes!(ocean::VerosOceanSimulation, net_ocean_fluxes) set!(ocean, "taux", tx; path=:variables) set!(ocean, "tauy", ty; path=:variables) - # TODO: uncomment below when the new branch gets merged + # TODO: uncomment below when veros supports prescribed fluxes BC for tracers # temp_flux = view(parent(net_ocean_fluxes.T), 1:nx, 1:ny, 1) # salt_flux = view(parent(net_ocean_fluxes.S), 1:nx, 1:ny, 1)