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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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/258] 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 cf2e7351e261b56aee5039f3e17fd6144b249648 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 21 Aug 2025 09:42:04 +0200 Subject: [PATCH 176/258] Update make.jl --- docs/make.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/make.jl b/docs/make.jl index ffa9b171c..4e6a437bf 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -11,6 +11,12 @@ Pkg.add(PackageSpec( url = "https://github.com/CliMA/Oceananigans.jl", rev = "ss/omip-branch-2" )) + +Pkg.add(PackageSpec( + name = "ClimaSeaIce", + url = "https://github.com/CliMA/ClimaSeaIce.jl", + rev = "ss/omip-branch-2" +)) Pkg.resolve() @show Pkg.status() From d0b3bf9ccb0ebffd5bb2a198b10a9ef62c7ee520 Mon Sep 17 00:00:00 2001 From: simone-silvestri Date: Thu, 28 Aug 2025 04:23:32 -0400 Subject: [PATCH 177/258] reduced the timestep --- experiments/omip_prototype/one_degree_omip.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/experiments/omip_prototype/one_degree_omip.jl b/experiments/omip_prototype/one_degree_omip.jl index f2bae0dd2..1744af824 100644 --- a/experiments/omip_prototype/one_degree_omip.jl +++ b/experiments/omip_prototype/one_degree_omip.jl @@ -44,7 +44,7 @@ using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVertic momentum_advection = WENOVectorInvariant(order=5) tracer_advection = WENO(order=5) -free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=45minutes) +free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt=45minutes) eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=1e3, κ_symmetric=1e3) catke_closure = ClimaOcean.OceanSimulations.default_ocean_closure() @@ -99,7 +99,7 @@ radiation = Radiation() ##### omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=30minutes, stop_time=60days) +omip = Simulation(omip, Δt=20minutes, stop_time=60days) # Figure out the outputs.... checkpointer_address(::SeaIceModel) = "SeaIceModel" @@ -149,7 +149,7 @@ add_callback!(omip, progress, IterationInterval(1)) run!(omip) -omip.Δt = 40minutes +omip.Δt = 30minutes omip.stop_time = 58 * 365days run!(omip) From f9613d8e716723f7b1ebca01630aaede7d84d3cf Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Thu, 28 Aug 2025 15:31:47 +0200 Subject: [PATCH 178/258] enforce real minimum depth --- src/Bathymetry.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index a647ebe37..fc619d7d2 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -195,7 +195,8 @@ end # Fix active cells to be at least `-minimum_depth`. active = z < 0 # it's a wet cell - z = ifelse(active, min(z, -minimum_depth), z) + above_minimum_depth = z > -minimum_depth + z = ifelse(active, ifelse(above_minimum_depth, zero(z), z), z) @inbounds target_z[i, j, 1] = z end From 19b09fde3d83e3ed3ad85f881e0e72214d5f0781 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 29 Sep 2025 14:38:43 -0700 Subject: [PATCH 179/258] Add one-eighth degree ocean simulation model implementation --- .../oneeighth_degree_simulation.jl | 338 ++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100644 experiments/omip_prototype/oneeighth_degree_simulation.jl diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl new file mode 100644 index 000000000..88165da99 --- /dev/null +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -0,0 +1,338 @@ +using ClimaOcean +using ClimaSeaIce +using Oceananigans +using Oceananigans.Grids +using Oceananigans.Units +using Oceananigans.OrthogonalSphericalShellGrids +using ClimaOcean.OceanSimulations +using ClimaOcean.JRA55 +using ClimaOcean.DataWrangling +using ClimaOcean.DataWrangling: NearestNeighborInpainting +using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using Printf +using Dates +using CUDA +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency + +import Oceananigans.OutputWriters: checkpointer_address + +arch = GPU() + +Nx = 2880 # longitudinal direction +Ny = 1440 # 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 +using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity + +momentum_advection = WENOVectorInvariant(order=5) +tracer_advection = WENO(order=5) + +free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=45minutes) + +obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() # CATKE +# obl_closure = RiBasedVerticalDiffusivity() +closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4)) + +if obl_closure isa RiBasedVerticalDiffusivity + prefix = "RiBased" +else + prefix = "CATKE" +end + +prefix *= "oneeighth_degree" + +glorys_dir = joinpath(homedir(), "GLORYS_data") +mkpath(glorys_dir) + +glorys_dataset = GLORYSMonthly() +@inline mask(x, y, z, t) = z ≥ z_surf - 1 +Smetadata = Metadata(:salinity; dataset=glorys_dataset, dir=glorys_dir) + +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) + +start_date = DateTime(1993, 1, 1) +end_date = DateTime(2003, 4, 1) +simulation_period = Dates.value(Second(end_date - start_date)) + +set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir), + S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir)) + +@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)) +sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) + +inpainting = NearestNeighborInpainting(5000) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, inpainting), + ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, inpainting)) + +##### +##### A Prescribed Atmosphere model +##### + +jra55_dir = joinpath(homedir(), "JRA55_data") +mkpath(jra55_dir) +# dataset = MultiYearJRA55() +jra55_dataset = RepeatYearJRA55() +jra55_backend = JRA55NetCDFBackend(100) + +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_backend, backend=jra55_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=20minutes, stop_time=60days) + +# Figure out the outputs.... +checkpointer_address(::SeaIceModel) = "SeaIceModel" + +FILE_DIR = "./Data/$(prefix)/" +mkpath(FILE_DIR) + +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, + schedule = SpecifiedTimes([simulation_period]), + prefix = "$(FILE_DIR)/ocean_checkpoint_onedegree", + overwrite_existing = true) + +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = SpecifiedTimes([simulation_period]), + prefix = "$(FILE_DIR)/sea_ice_checkpoint_onedegree", + overwrite_existing = true) + +u, v, w = ocean.model.velocities +T, S = ocean.model.tracers +b = Field(buoyancy(ocean.model)) +N² = Field(buoyancy_frequency(ocean.model)) + +ocean_outputs = merge(ocean.model.tracers, ocean.model.velocities, (; b, N²)) + +sea_ice_outputs = merge((h = sea_ice.model.ice_thickness, + ℵ = sea_ice.model.ice_concentration, + T = sea_ice.model.ice_thermodynamics.top_surface_temperature), + sea_ice.model.velocities) + +ocean.output_writers[:surface] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(30days), + filename = "$(FILE_DIR)/ocean_surface_fields", + indices = (:, :, grid.Nz), + overwrite_existing = true) + +sea_ice.output_writers[:surface] = JLD2Writer(ocean.model, sea_ice_outputs; + schedule = TimeInterval(30days), + filename = "$(FILE_DIR)/sea_ice_surface_fields", + overwrite_existing = true) + +ocean.output_writers[:full] = JLD2Writer(ocean.model, ocean_outputs; + schedule = SpecifiedTimes([simulation_period]), + filename = "$(FILE_DIR)/ocean_complete_fields", + overwrite_existing = true) + +sea_ice.output_writers[:full] = JLD2Writer(sea_ice.model, sea_ice_outputs; + schedule = SpecifiedTimes([simulation_period]), + filename = "$(FILE_DIR)/sea_ice_complete_fields", + overwrite_existing = true) + +ocean.output_writers[:monthly_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(30days, window=30days), + filename = "$(FILE_DIR)/ocean_complete_fields_monthly_average", + overwrite_existing = true) + +sea_ice.output_writers[:monthly_average] = JLD2Writer(sea_ice.model, sea_ice_outputs; + schedule = AveragedTimeInterval(30days, window=30days), + filename = "$(FILE_DIR)/sea_ice_complete_fields_monthly_average", + overwrite_existing = true) + +ocean.output_writers[:yearly_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(365days, window=365days), + filename = "$(FILE_DIR)/ocean_complete_fields_yearly_average", + overwrite_existing = true) + +sea_ice.output_writers[:yearly_average] = JLD2Writer(sea_ice.model, sea_ice_outputs; + schedule = AveragedTimeInterval(365days, window=365days), + filename = "$(FILE_DIR)/sea_ice_complete_fields_yearly_average", + 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(100)) + +run!(omip) + +omip.Δt = 60minutes +omip.stop_time = 200 * 365days + +run!(omip) + +#%% +@info "Plotting results..." +using CairoMakie + +uo = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "u"; backend = OnDisk()) +vo = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "v"; backend = OnDisk()) +To = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "T"; backend = OnDisk()) + +# and sea ice fields with "i": +ui = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "u"; backend = OnDisk()) +vi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "v"; backend = OnDisk()) +hi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "h"; backend = OnDisk()) +ℵi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "ℵ"; backend = OnDisk()) +Ti = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "T"; backend = OnDisk()) + +times = uo.times +Nt = length(times) +n = Observable(Nt) + +# We create a land mask and use it to fill land points with `NaN`s. +land = interior(To.grid.immersed_boundary.bottom_height) .≥ 0 + +Toₙ = @lift begin + Tₙ = interior(To[$n]) + Tₙ[land] .= NaN + view(Tₙ, :, :, 1) +end + +heₙ = @lift begin + hₙ = interior(hi[$n]) + ℵₙ = interior(ℵi[$n]) + hₙ[land] .= NaN + view(hₙ, :, :, 1) .* view(ℵₙ, :, :, 1) +end + +# We compute the surface speeds for the ocean and the sea ice. +uoₙ = Field{Face, Center, Nothing}(uo.grid) +voₙ = Field{Center, Face, Nothing}(vo.grid) + +uiₙ = Field{Face, Center, Nothing}(ui.grid) +viₙ = Field{Center, Face, Nothing}(vi.grid) + +so = Field(sqrt(uoₙ^2 + voₙ^2)) +si = Field(sqrt(uiₙ^2 + viₙ^2)) + +soₙ = @lift begin + parent(uoₙ) .= parent(uo[$n]) + parent(voₙ) .= parent(vo[$n]) + compute!(so) + soₙ = interior(so) + soₙ[land] .= NaN + view(soₙ, :, :, 1) +end + +siₙ = @lift begin + parent(uiₙ) .= parent(ui[$n]) + parent(viₙ) .= parent(vi[$n]) + compute!(si) + siₙ = interior(si) + hₙ = interior(hi[$n]) + ℵₙ = interior(ℵi[$n]) + he = hₙ .* ℵₙ + siₙ[he .< 1e-7] .= 0 + siₙ[land] .= NaN + view(siₙ, :, :, 1) +end + +# Finally, we plot a snapshot of the surface speed, temperature, and the turbulent +# eddy kinetic energy from the CATKE vertical mixing parameterization as well as the +# sea ice speed and the effective sea ice thickness. +fig = Figure(size=(2000, 1000)) + +title = @lift string("Global 1/8ᵒ ocean simulation after ", prettytime(times[$n] - times[1])) + +axso = Axis(fig[1, 1]) +axsi = Axis(fig[1, 3]) +axTo = Axis(fig[2, 1]) +axhi = Axis(fig[2, 3]) + +hmo = heatmap!(axso, soₙ, colorrange = (0, 0.5), colormap = :deep, nan_color=:lightgray) +hmi = heatmap!(axsi, siₙ, colorrange = (0, 0.5), colormap = :greys, nan_color=:lightgray) +Colorbar(fig[1, 2], hmo, label = "Ocean Surface speed (m s⁻¹)") +Colorbar(fig[1, 4], hmi, label = "Sea ice speed (m s⁻¹)") + +hmo = heatmap!(axTo, Toₙ, colorrange = (-1, 32), colormap = :magma, nan_color=:lightgray) +hmi = heatmap!(axhi, heₙ, colorrange = (0, 4), colormap = :blues, nan_color=:lightgray) +Colorbar(fig[2, 2], hmo, label = "Surface Temperature (ᵒC)") +Colorbar(fig[2, 4], hmi, label = "Effective ice thickness (m)") + +for ax in (axso, axsi, axTo, axhi) + hidedecorations!(ax) +end + +Label(fig[0, :], title) + +save("$(FILE_DIR)/global_snapshot.png", fig) +nothing #hide + +# ![](global_snapshot.png) + +# And now a movie: + +CairoMakie.record(fig, "$(FILE_DIR)/oneeighth_degree_global_ocean_surface.mp4", 1:Nt, framerate = 8) do nn + n[] = nn +end +nothing +#%% \ No newline at end of file From cb89c6b561efc0c7d1859f03ebf7ea9934c6364f Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 29 Sep 2025 14:53:51 -0700 Subject: [PATCH 180/258] Add PythonCall import to one-eighth degree simulation script --- experiments/omip_prototype/oneeighth_degree_simulation.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl index 88165da99..31ecc8a9e 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -12,6 +12,7 @@ using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium using Printf using Dates using CUDA +using PythonCall using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address From 60ff1b73f7beb4f64eaa4e2456b19da994426d27 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 29 Sep 2025 17:19:12 -0700 Subject: [PATCH 181/258] Enhance one-eighth degree simulation with detailed logging and initialization steps --- .../omip_prototype/oneeighth_degree_simulation.jl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl index 31ecc8a9e..68b3e246a 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -28,12 +28,16 @@ z_faces = ExponentialCoordinate(Nz, -6000, 0) const z_surf = z_faces(Nz) +@info "Building grid..." grid = TripolarGrid(arch; size = (Nx, Ny, Nz), z = z_faces, halo = (7, 7, 7)) +@info "Regridding bathymetry..." bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=75) + +@info "Building immersed boundary grid..." grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) ##### @@ -70,6 +74,7 @@ Smetadata = Metadata(:salinity; dataset=glorys_dataset, dir=glorys_dir) FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 10) +@info "Building ocean component..." ocean = ocean_simulation(grid; Δt=1minutes, momentum_advection, tracer_advection, @@ -82,6 +87,7 @@ start_date = DateTime(1993, 1, 1) end_date = DateTime(2003, 4, 1) simulation_period = Dates.value(Second(end_date - start_date)) +@info "Setting initial conditions..." set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir), S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir)) @@ -91,10 +97,12 @@ set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_d ##### A Prognostic Sea-ice model ##### +@info "Building sea-ice component..." # Default sea-ice dynamics and salinity coupling are included in the defaults # sea_ice = sea_ice_simulation(grid, ocean; advection=WENO(order=7)) sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) +@info "Setting sea-ice initial conditions..." inpainting = NearestNeighborInpainting(5000) set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, inpainting), ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, inpainting)) @@ -109,6 +117,7 @@ mkpath(jra55_dir) jra55_dataset = RepeatYearJRA55() jra55_backend = JRA55NetCDFBackend(100) +@info "Building atmospheric forcing..." atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_backend, backend=jra55_backend, include_rivers_and_icebergs=true) radiation = Radiation() @@ -116,6 +125,7 @@ radiation = Radiation() ##### An ocean-sea ice coupled model ##### +@info "Building coupled ocean-sea ice model..." omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) omip = Simulation(omip, Δt=20minutes, stop_time=60days) @@ -125,6 +135,7 @@ checkpointer_address(::SeaIceModel) = "SeaIceModel" FILE_DIR = "./Data/$(prefix)/" mkpath(FILE_DIR) +@info "Setting up output writers..." ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, schedule = SpecifiedTimes([simulation_period]), prefix = "$(FILE_DIR)/ocean_checkpoint_onedegree", @@ -188,8 +199,6 @@ sea_ice.output_writers[:yearly_average] = JLD2Writer(sea_ice.model, sea_ice_outp filename = "$(FILE_DIR)/sea_ice_complete_fields_yearly_average", overwrite_existing = true) - - wall_time = Ref(time_ns()) using Statistics @@ -223,6 +232,7 @@ end # And add it as a callback to the simulation. add_callback!(omip, progress, IterationInterval(100)) +@info "Starting simulation..." run!(omip) omip.Δt = 60minutes From 09d5b2aa588f7011ceea051cfef1c14da96b0ed0 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 30 Sep 2025 09:09:34 -0700 Subject: [PATCH 182/258] Update one-eighth degree simulation parameters and configurations --- .../oneeighth_degree_simulation.jl | 54 +++++++++++-------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl index 68b3e246a..3c79cf566 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -18,10 +18,11 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address arch = GPU() +# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction -Nz = 60 +Nz = 100 z_faces = ExponentialCoordinate(Nz, -6000, 0) # z_faces = MutableVerticalDiscretization(z_faces) @@ -35,7 +36,7 @@ grid = TripolarGrid(arch; halo = (7, 7, 7)) @info "Regridding bathymetry..." -bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=75) +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=10) @info "Building immersed boundary grid..." grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) @@ -48,10 +49,10 @@ using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity -momentum_advection = WENOVectorInvariant(order=5) -tracer_advection = WENO(order=5) +momentum_advection = WENOVectorInvariant() +tracer_advection = WENO(order=7) -free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=45minutes) +free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=12minutes) obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() # CATKE # obl_closure = RiBasedVerticalDiffusivity() @@ -69,10 +70,11 @@ glorys_dir = joinpath(homedir(), "GLORYS_data") mkpath(glorys_dir) glorys_dataset = GLORYSMonthly() -@inline mask(x, y, z, t) = z ≥ z_surf - 1 -Smetadata = Metadata(:salinity; dataset=glorys_dataset, dir=glorys_dir) -FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 10) +# Turn off salinity restoring for now +# @inline mask(x, y, z, t) = z ≥ z_surf - 1 +# Smetadata = Metadata(:salinity; dataset=glorys_dataset, dir=glorys_dir) +# FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 3) @info "Building ocean component..." ocean = ocean_simulation(grid; Δt=1minutes, @@ -80,16 +82,17 @@ ocean = ocean_simulation(grid; Δt=1minutes, tracer_advection, timestepper = :SplitRungeKutta3, free_surface, - forcing = (; S = FS), + # forcing = (; S = FS), closure) start_date = DateTime(1993, 1, 1) end_date = DateTime(2003, 4, 1) simulation_period = Dates.value(Second(end_date - start_date)) +inpainting = NearestNeighborInpainting(50) @info "Setting initial conditions..." -set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir), - S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir)) +set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir, inpainting), + S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir, inpainting)) @info ocean.model.clock @@ -103,9 +106,8 @@ set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_d sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) @info "Setting sea-ice initial conditions..." -inpainting = NearestNeighborInpainting(5000) -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, inpainting), - ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, inpainting)) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, inpainting=nothing), + ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, inpainting=nothing)) ##### ##### A Prescribed Atmosphere model @@ -113,12 +115,12 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, jra55_dir = joinpath(homedir(), "JRA55_data") mkpath(jra55_dir) -# dataset = MultiYearJRA55() -jra55_dataset = RepeatYearJRA55() -jra55_backend = JRA55NetCDFBackend(100) +dataset = MultiYearJRA55() +# jra55_dataset = RepeatYearJRA55() +jra55_backend = JRA55NetCDFBackend(10) @info "Building atmospheric forcing..." -atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_backend, backend=jra55_backend, include_rivers_and_icebergs=true) +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_backend, backend=jra55_backend, include_rivers_and_icebergs=true, start_date) radiation = Radiation() ##### @@ -127,7 +129,8 @@ radiation = Radiation() @info "Building coupled ocean-sea ice model..." omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=20minutes, stop_time=60days) +# omip = Simulation(omip, Δt=10minutes, stop_time=60days) +omip = Simulation(omip, Δt=10minutes, stop_time=simulation_period) # Figure out the outputs.... checkpointer_address(::SeaIceModel) = "SeaIceModel" @@ -138,12 +141,17 @@ mkpath(FILE_DIR) @info "Setting up output writers..." ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, schedule = SpecifiedTimes([simulation_period]), - prefix = "$(FILE_DIR)/ocean_checkpoint_onedegree", + prefix = "$(FILE_DIR)/ocean_checkpoint_oneeighthdegree", overwrite_existing = true) +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = TimeInterval(60days), + prefix = "$(FILE_DIR)/sea_ice_checkpoint_oneeighthdegree", + overwrite_existing = true) + sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, schedule = SpecifiedTimes([simulation_period]), - prefix = "$(FILE_DIR)/sea_ice_checkpoint_onedegree", + prefix = "$(FILE_DIR)/sea_ice_checkpoint_oneeighthdegree_final", overwrite_existing = true) u, v, w = ocean.model.velocities @@ -235,8 +243,8 @@ add_callback!(omip, progress, IterationInterval(100)) @info "Starting simulation..." run!(omip) -omip.Δt = 60minutes -omip.stop_time = 200 * 365days +# omip.Δt = 10minutes +# omip.stop_time = simulation_period run!(omip) From 87f5ab65cbfb9738c383c021234003c92aab1d8c Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 30 Sep 2025 10:07:26 -0700 Subject: [PATCH 183/258] Adjust vertical grid resolution to 80 levels in one-eighth degree simulation --- experiments/omip_prototype/oneeighth_degree_simulation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl index 3c79cf566..25f4ce86f 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -22,7 +22,7 @@ arch = GPU() Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction -Nz = 100 +Nz = 80 z_faces = ExponentialCoordinate(Nz, -6000, 0) # z_faces = MutableVerticalDiscretization(z_faces) From 8d8244a1bec65c4d81055bb3a574fa39bf271b70 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 30 Sep 2025 10:24:08 -0700 Subject: [PATCH 184/258] Refactor initial condition setup to improve inpainting parameter handling --- experiments/omip_prototype/oneeighth_degree_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl index 25f4ce86f..e69fdbc1f 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -91,8 +91,8 @@ simulation_period = Dates.value(Second(end_date - start_date)) inpainting = NearestNeighborInpainting(50) @info "Setting initial conditions..." -set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir, inpainting), - S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir, inpainting)) +set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir), + S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir); inpainting) @info ocean.model.clock From ca25c22db7dbb3598f46c1a7572958e503e5b033 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 30 Sep 2025 10:37:26 -0700 Subject: [PATCH 185/258] change to 60 vertical levels --- experiments/omip_prototype/oneeighth_degree_simulation.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl index e69fdbc1f..8580f8acf 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -22,7 +22,7 @@ arch = GPU() Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction -Nz = 80 +Nz = 60 z_faces = ExponentialCoordinate(Nz, -6000, 0) # z_faces = MutableVerticalDiscretization(z_faces) @@ -106,8 +106,8 @@ set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_d sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) @info "Setting sea-ice initial conditions..." -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, inpainting=nothing), - ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, inpainting=nothing)) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir), + ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir), inpainting = nothing) ##### ##### A Prescribed Atmosphere model From cf49b612dd0f88dc134f4416d222e0cfbc74b3d0 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 30 Sep 2025 12:14:52 -0700 Subject: [PATCH 186/258] distributed is the way --- experiments/omip_prototype/oneeighth_degree_simulation.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl index 8580f8acf..a1dade25e 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -17,12 +17,12 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address -arch = GPU() -# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = GPU() +arch = Distributed(GPU(), partition=Partition(1, 2), synchronized_communication=true) Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction -Nz = 60 +Nz = 100 z_faces = ExponentialCoordinate(Nz, -6000, 0) # z_faces = MutableVerticalDiscretization(z_faces) From 4f01721c7728fe6606eeed2bdf1295a0e843e8b0 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Wed, 1 Oct 2025 04:20:48 +0000 Subject: [PATCH 187/258] add Manifest for reproducibility --- Manifest.toml | 249 +++++++++++++++++++++++++++++--------------------- 1 file changed, 145 insertions(+), 104 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index e31e9c89a..bbb48d88c 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.10" +julia_version = "1.11.6" manifest_format = "2.0" -project_hash = "f57e0b9bc9bbdd1cb6d317ebea00412e67510515" +project_hash = "2033fc2574fe13596dbb816d1dde3aa0d3072a4d" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -44,9 +44,9 @@ version = "0.1.42" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "f7817e2e585aa6d924fd714df1e2a84be7896c60" +git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.3.0" +version = "4.4.0" weakdeps = ["SparseArrays", "StaticArrays"] [deps.Adapt.extensions] @@ -55,7 +55,7 @@ weakdeps = ["SparseArrays", "StaticArrays"] [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" +version = "1.1.2" [[deps.ArnoldiMethod]] deps = ["LinearAlgebra", "Random", "StaticArrays"] @@ -65,9 +65,9 @@ version = "0.4.0" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "9606d7832795cbef89e06a550475be300364a8aa" +git-tree-sha1 = "dbd8c3bbbdbb5c2778f85f4422c39960eac65a42" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.19.0" +version = "7.20.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -77,6 +77,7 @@ version = "7.19.0" ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" ArrayInterfaceChainRulesExt = "ChainRules" ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceMetalExt = "Metal" ArrayInterfaceReverseDiffExt = "ReverseDiff" ArrayInterfaceSparseArraysExt = "SparseArrays" ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" @@ -90,6 +91,7 @@ version = "7.19.0" ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" @@ -97,6 +99,7 @@ version = "7.19.0" [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" [[deps.Atomix]] deps = ["UnsafeAtomics"] @@ -124,6 +127,7 @@ version = "0.5.1" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" [[deps.BitFlags]] git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" @@ -155,9 +159,9 @@ version = "0.5.0" [[deps.CFTime]] deps = ["Dates", "Printf"] -git-tree-sha1 = "9b37e9e51aeea9763eea65b9b3aa1728fca94ffc" +git-tree-sha1 = "2ed76cf4ac70526e3df565435d65e7c7b5c7a77a" uuid = "179af706-886a-5703-950a-314cd64e0468" -version = "0.2.1" +version = "0.2.4" [[deps.CPUSummary]] deps = ["CpuId", "IfElse", "PrecompileTools", "Preferences", "Static"] @@ -167,9 +171,9 @@ 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" +git-tree-sha1 = "d5840b32b52a201ca90ac9d538c1d3a1641bfa2d" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.8.3" +version = "5.9.0" [deps.CUDA.extensions] ChainRulesCoreExt = "ChainRulesCore" @@ -184,16 +188,16 @@ version = "5.8.3" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" [[deps.CUDA_Compiler_jll]] -deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "fdb9ddf3e08e2aca4c84b3252df2dea046caadee" +deps = ["Artifacts", "CUDA_Driver_jll", "CUDA_Runtime_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] +git-tree-sha1 = "8c4f340dd6501a93c4b99b690797772e4a203099" uuid = "d1e2174e-dfdc-576e-b43e-73b79eb1aca8" -version = "0.2.0+1" +version = "0.2.1+0" [[deps.CUDA_Driver_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "12621de83838b5ce6a185050db5a184f4540679b" +git-tree-sha1 = "e6a1d9f5518122c186fd27786b61d2053cfa1b0c" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "13.0.0+0" +version = "13.0.1+0" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] @@ -203,17 +207,15 @@ version = "1.0.0" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "cc727d90c9769db27945219f9ba149dbddc74f06" +git-tree-sha1 = "e24c6de116c0735c37e83b8bc05ed60d4d359693" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.19.0+0" +version = "0.19.1+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" +git-tree-sha1 = "2dc7e793f69084fa821997a3fa97842276e220da" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.3.5" +version = "0.3.7" [[deps.CloseOpenIntervals]] deps = ["Static", "StaticArrayInterface"] @@ -232,13 +234,11 @@ deps = ["FixedPointNumbers", "Random"] git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.12.1" +weakdeps = ["StyledStrings"] [deps.ColorTypes.extensions] StyledStringsExt = "StyledStrings" - [deps.ColorTypes.weakdeps] - StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" - [[deps.ColorVectorSpace]] deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" @@ -257,9 +257,9 @@ version = "0.13.1" [[deps.CommonDataModel]] deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "a4f9a314202585fcdce4f1a3c4b86ce988ce76b1" +git-tree-sha1 = "1985a3201d376bf13a866527e19c2272c252870f" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.9" +version = "0.3.10" [[deps.CommonSolve]] git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" @@ -358,9 +358,9 @@ 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" +git-tree-sha1 = "c967271c27a95160e30432e011b58f42cd7501b5" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.7.0" +version = "1.8.0" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] @@ -376,6 +376,7 @@ version = "1.0.0" [[deps.Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -391,9 +392,9 @@ version = "1.15.1" [[deps.DiskArrays]] deps = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] -git-tree-sha1 = "bfde0790720fcac006a3d62149309a685fc3aa13" +git-tree-sha1 = "297ac5efb7c9c7849114eba76111af2814cac8ec" uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.4.15" +version = "0.4.16" [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] @@ -412,6 +413,7 @@ version = "0.10.12" [[deps.Distributed]] deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" [[deps.DocStringExtensions]] git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" @@ -440,10 +442,10 @@ 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" +deps = ["AbstractFFTs", "FFTW_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "97f08406df914023af55ade2f843c39e99c5d969" uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.9.0" +version = "1.10.0" [[deps.FFTW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -463,6 +465,7 @@ weakdeps = ["HTTP"] [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" [[deps.FixedPointNumbers]] deps = ["Statistics"] @@ -472,9 +475,9 @@ version = "0.8.5" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "910febccb28d493032495b7009dce7d7f7aee554" +git-tree-sha1 = "dc41303865a16274ecb8450c220021ce1e0cf05f" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.0.1" +version = "1.2.1" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] @@ -483,12 +486,17 @@ weakdeps = ["StaticArrays"] [[deps.Future]] deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" +version = "1.11.0" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "Statistics"] -git-tree-sha1 = "be941842a40b6daac98496994ea69054ba4c5144" +git-tree-sha1 = "ec30748ac561b82e531f6b8ed2fb52498e82f307" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "11.2.3" +version = "11.2.5" +weakdeps = ["JLD2"] + + [deps.GPUArrays.extensions] + JLD2Ext = "JLD2" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -498,9 +506,9 @@ version = "0.2.0" [[deps.GPUCompiler]] deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "PrecompileTools", "Preferences", "Scratch", "Serialization", "TOML", "Tracy", "UUIDs"] -git-tree-sha1 = "eb1e212e12cc058fa16712082d44be499d23638c" +git-tree-sha1 = "4b477428fbc2b3f4a906a47c9d4156764074f581" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "1.6.1" +version = "1.6.2" [[deps.GPUToolbox]] deps = ["LLVM"] @@ -543,10 +551,10 @@ uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" version = "0.1.17" [[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "92f65c4d78ce8cdbb6b68daf88889950b0a99d11" +deps = ["Artifacts", "JLLWrappers", "Libdl", "XML2_jll", "Xorg_libpciaccess_jll"] +git-tree-sha1 = "3d468106a05408f9f7b6f161d9e7715159af247b" uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.12.1+0" +version = "2.12.2+0" [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" @@ -571,9 +579,9 @@ uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" version = "0.1.5" [[deps.InlineStrings]] -git-tree-sha1 = "8594fac023c5ce1ef78260f24d1ad18b4327b420" +git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d" uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.4" +version = "1.4.5" [deps.InlineStrings.extensions] ArrowTypesExt = "ArrowTypes" @@ -592,6 +600,7 @@ version = "2025.2.0+0" [[deps.InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" [[deps.InverseFunctions]] git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb" @@ -613,12 +622,6 @@ 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" @@ -664,9 +667,9 @@ version = "0.9.38" [[deps.Krylov]] deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "b94257a1a8737099ca40bc7271a8b374033473ed" +git-tree-sha1 = "d1fc961038207e43982851e57ee257adc37be5e8" uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.10.1" +version = "0.10.2" [[deps.KrylovPreconditioners]] deps = ["Adapt", "Graphs", "KernelAbstractions", "LinearAlgebra", "Metis", "SparseArrays"] @@ -728,6 +731,7 @@ version = "0.1.17" [[deps.LazyArtifacts]] deps = ["Artifacts", "Pkg"] uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" +version = "1.11.0" [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] @@ -737,16 +741,17 @@ version = "0.6.4" [[deps.LibCURL_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.4.0+0" +version = "8.6.0+0" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" [[deps.LibGit2_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.6.4+0" +version = "1.7.2+0" [[deps.LibSSH2_jll]] deps = ["Artifacts", "Libdl", "MbedTLS_jll"] @@ -761,6 +766,7 @@ version = "0.9.1+6" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" [[deps.Libiconv_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -771,6 +777,7 @@ version = "1.18.0+0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.11.0" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] @@ -790,6 +797,7 @@ version = "0.3.29" [[deps.Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" [[deps.LoggingExtras]] deps = ["Dates", "Logging"] @@ -880,6 +888,7 @@ version = "0.4.2" [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] @@ -890,7 +899,7 @@ version = "1.1.9" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+1" +version = "2.28.6+0" [[deps.Metis]] deps = ["CEnum", "LinearAlgebra", "METIS_jll", "SparseArrays"] @@ -922,6 +931,7 @@ version = "1.2.0" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" [[deps.MosaicViews]] deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] @@ -931,7 +941,7 @@ version = "0.3.4" [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.1.10" +version = "2023.12.12" [[deps.MuladdMacro]] git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" @@ -973,12 +983,10 @@ 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" +deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] +git-tree-sha1 = "0b4e7bbd1cdf8dec20401159598dc76c7c4d40fe" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.97.7" +version = "0.99.2" [deps.Oceananigans.extensions] OceananigansAMDGPUExt = "AMDGPU" @@ -989,6 +997,7 @@ version = "0.97.7" OceananigansNCDatasetsExt = "NCDatasets" OceananigansOneAPIExt = "oneAPI" OceananigansReactantExt = ["Reactant", "KernelAbstractions", "ConstructionBase"] + OceananigansXESMFExt = ["XESMF"] [deps.Oceananigans.weakdeps] AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" @@ -1000,6 +1009,7 @@ version = "0.97.7" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" + XESMF = "2e0b0046-e7a1-486f-88de-807ee8ffabe5" oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" [[deps.OffsetArrays]] @@ -1014,7 +1024,7 @@ weakdeps = ["Adapt"] [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.23+4" +version = "0.3.27+1" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] @@ -1057,9 +1067,13 @@ 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"] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.10.0" +version = "1.11.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" [[deps.PkgVersion]] deps = ["Pkg"] @@ -1092,14 +1106,15 @@ 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" +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "5e9fe23c86d3ca630baa1efcad78575a27f158b2" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.4.0" +version = "3.0.11" [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" [[deps.Quaternions]] deps = ["LinearAlgebra", "Random", "RealDot"] @@ -1108,12 +1123,14 @@ uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" version = "0.7.6" [[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" [[deps.Random]] deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" [[deps.Random123]] deps = ["Random", "RandomNumbers"] @@ -1129,9 +1146,9 @@ version = "1.6.0" [[deps.ReactantCore]] deps = ["ExpressionExplorer", "MacroTools"] -git-tree-sha1 = "120feaf6a97738e3a63902644a0afb3b69cc7b98" +git-tree-sha1 = "f3e31b90afcd152578a6c389eae46dd38b9a4f38" uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" -version = "0.1.15" +version = "0.1.16" [[deps.RealDot]] deps = ["LinearAlgebra"] @@ -1139,12 +1156,6 @@ 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" @@ -1164,9 +1175,9 @@ version = "0.4.6" [[deps.Roots]] deps = ["Accessors", "CommonSolve", "Printf"] -git-tree-sha1 = "668e411c0616a70860249b4c96e5d35296631a1d" +git-tree-sha1 = "8a433b1ede5e9be9a7ba5b1cc6698daa8d718f1d" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.2.8" +version = "2.2.10" [deps.Roots.extensions] RootsChainRulesCoreExt = "ChainRulesCore" @@ -1174,6 +1185,7 @@ version = "2.2.8" RootsIntervalRootFindingExt = "IntervalRootFinding" RootsSymPyExt = "SymPy" RootsSymPyPythonCallExt = "SymPyPythonCall" + RootsUnitfulExt = "Unitful" [deps.Roots.weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" @@ -1181,17 +1193,20 @@ 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"] git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" version = "1.7.1" -weakdeps = ["RecipesBase"] [deps.Rotations.extensions] RotationsRecipesBaseExt = "RecipesBase" + [deps.Rotations.weakdeps] + RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" + [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" @@ -1207,11 +1222,16 @@ git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" version = "0.6.43" +[[deps.SciMLPublic]] +git-tree-sha1 = "ed647f161e8b3f2973f24979ec074e8d084f1bee" +uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" +version = "1.0.0" + [[deps.ScopedValues]] deps = ["HashArrayMappedTries", "Logging"] -git-tree-sha1 = "7f44eef6b1d284465fafc66baf4d9bdcc239a15b" +git-tree-sha1 = "c3b2323466378a2ba15bea4b2f73b081e022f473" uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" -version = "1.4.0" +version = "1.5.0" [[deps.Scratch]] deps = ["Dates"] @@ -1232,10 +1252,12 @@ version = "1.4.8" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" [[deps.SharedArrays]] deps = ["Distributed", "Mmap", "Random", "Serialization"] uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +version = "1.11.0" [[deps.SimpleBufferStream]] git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" @@ -1250,6 +1272,7 @@ version = "0.9.5" [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" [[deps.SortingAlgorithms]] deps = ["DataStructures"] @@ -1260,7 +1283,7 @@ version = "1.2.2" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.10.0" +version = "1.11.0" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] @@ -1281,10 +1304,10 @@ uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" version = "0.1.2" [[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools"] -git-tree-sha1 = "f737d444cb0ad07e61b3c1bef8eb91203c321eff" +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] +git-tree-sha1 = "1e44e7b1dbb5249876d84c32466f8988a6b41bbb" uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.2.0" +version = "1.3.0" [[deps.StaticArrayInterface]] deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] @@ -1299,9 +1322,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "cbea8a6bd7bed51b1619658dec70035e07b8502f" +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.14" +version = "1.9.15" [deps.StaticArrays.extensions] StaticArraysChainRulesCoreExt = "ChainRulesCore" @@ -1317,9 +1340,14 @@ uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" version = "1.4.3" [[deps.Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.10.0" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] [[deps.StatsAPI]] deps = ["LinearAlgebra"] @@ -1347,16 +1375,20 @@ weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "Sp StructArraysSparseArraysExt = "SparseArrays" StructArraysStaticArraysExt = "StaticArrays" +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.2.1+1" +version = "7.7.0+0" [[deps.SurfaceFluxes]] deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "eb96fea9de18a3935a836ee8634af3c126d6b77f" +git-tree-sha1 = "a03a545014be4f89d36d4a7d024b69427a105e9e" uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.12.1" +version = "0.12.3" [deps.SurfaceFluxes.extensions] CreateParametersExt = "ClimaParams" @@ -1413,12 +1445,13 @@ version = "0.1.1" [[deps.Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "ForwardDiff", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "edce99e94489c25f5c7f5b4065c06ffb5adb1317" +git-tree-sha1 = "14ec5f1776187fd9a1849a4f59e6d22f706a6fb5" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.13.1" +version = "0.14.1" [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" @@ -1440,9 +1473,9 @@ version = "0.5.0" [[deps.Tracy]] deps = ["ExprTools", "LibTracyClient_jll", "Libdl"] -git-tree-sha1 = "91dbaee0f50faa4357f7e9fc69442c7b6364dfe5" +git-tree-sha1 = "73e3ff50fd3990874c59fef0f35d10644a1487bc" uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" -version = "0.1.5" +version = "0.1.6" [deps.Tracy.extensions] TracyProfilerExt = "TracyProfiler_jll" @@ -1463,6 +1496,7 @@ version = "1.6.1" [[deps.UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" [[deps.UnPack]] git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" @@ -1471,6 +1505,7 @@ version = "1.0.2" [[deps.Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" [[deps.UnsafeAtomics]] git-tree-sha1 = "b13c4edda90890e5b04ba24e20a310fbe6f249ff" @@ -1483,15 +1518,15 @@ weakdeps = ["LLVM"] [[deps.VectorizationBase]] deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "4ab62a49f1d8d9548a1c8d1a75e5f55cf196f64e" +git-tree-sha1 = "d1d9a935a26c475ebffd54e9c7ad11627c43ea85" uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.71" +version = "0.21.72" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "b8b243e47228b4a3877f1dd6aee0c5d56db7fcf4" +git-tree-sha1 = "80d3930c6347cfce7ccf96bd3bafdf079d9c0390" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.6+1" +version = "2.13.9+0" [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1499,6 +1534,12 @@ git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" version = "5.8.1+0" +[[deps.Xorg_libpciaccess_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "4909eb8f1cbf6bd4b1c30dd18b2ead9019ef2fad" +uuid = "a65dc6b1-eb27-53a1-bb3e-dea574b5389e" +version = "0.18.1+0" + [[deps.ZipFile]] deps = ["Libdl", "Printf", "Zlib_jll"] git-tree-sha1 = "f492b7fe1698e623024e873244f10d89c95c340a" @@ -1524,9 +1565,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"] @@ -1542,7 +1583,7 @@ version = "1.11.3+0" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.52.0+1" +version = "1.59.0+0" [[deps.oneTBB_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] From 79a61c0b4f86cba948829de030e01e262c04db4b Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 30 Sep 2025 21:24:15 -0700 Subject: [PATCH 188/258] create minimal script for debugging --- .../oneeighth_degree_simulation_minimal.jl | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl diff --git a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl new file mode 100644 index 000000000..515a22445 --- /dev/null +++ b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl @@ -0,0 +1,163 @@ +using ClimaOcean +using ClimaSeaIce +using Oceananigans +using Oceananigans.Grids +using Oceananigans.Units +using Oceananigans.OrthogonalSphericalShellGrids +using Oceananigans.Architectures: on_architecture +using ClimaOcean.OceanSimulations +using ClimaOcean.JRA55 +using ClimaOcean.DataWrangling +using ClimaOcean.DataWrangling: NearestNeighborInpainting +using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using Printf +using Dates +using CUDA +using PythonCall +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency + +import Oceananigans.OutputWriters: checkpointer_address + +# arch = GPU() +arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = Distributed(CPU(), partition=Partition(1, 2), synchronized_communication=true) + +@info "Architecture $(arch)" + +Nx = 2880 # longitudinal direction +Ny = 1440 # meridional direction +Nz = 100 + +z_faces = ExponentialCoordinate(Nz, -6000, 0) + +const z_surf = z_faces(Nz) + +@info "Building grid..." +grid = TripolarGrid(arch; + size = (Nx, Ny, Nz), + z = z_faces, + halo = (7, 7, 7)) + +@info "Regridding bathymetry..." +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=10) + +fitted_bottom = GridFittedBottom(bottom_height) + +@info "Building immersed boundary grid..." +grid = ImmersedBoundaryGrid(grid, fitted_bottom; active_cells_map=true) + +@info grid +@info "Created ImmersedBoundaryGrid" + +##### +##### A Propgnostic Ocean model +##### + +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation +using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity + +momentum_advection = WENOVectorInvariant() +tracer_advection = WENO(order=7) + +free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=12minutes) +@info "Free surface", free_surface + +obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() # CATKE +closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4)) + +glorys_dir = joinpath(homedir(), "GLORYS_data") +mkpath(glorys_dir) + +glorys_dataset = GLORYSMonthly() + +@info "Building ocean component..." +ocean = ocean_simulation(grid; Δt=1minutes, + momentum_advection, + tracer_advection, + timestepper = :SplitRungeKutta3, + free_surface, + closure) + +start_date = DateTime(1993, 1, 1) +end_date = DateTime(2003, 4, 1) +simulation_period = Dates.value(Second(end_date - start_date)) + +inpainting = NearestNeighborInpainting(50) +@info "Setting initial conditions..." +set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir), + S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir); inpainting) + +@info ocean.model.clock + +##### +##### A Prognostic Sea-ice model +##### + +@info "Building sea-ice component..." +sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) + +@info "Setting sea-ice initial conditions..." +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir), + ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir), inpainting = nothing) + +##### +##### A Prescribed Atmosphere model +##### + +jra55_dir = joinpath(homedir(), "JRA55_data") +mkpath(jra55_dir) +dataset = MultiYearJRA55() +jra55_backend = JRA55NetCDFBackend(10) + +@info "Building atmospheric forcing..." +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_backend, backend=jra55_backend, include_rivers_and_icebergs=true, start_date) +radiation = Radiation() + +##### +##### An ocean-sea ice coupled model +##### + +@info "Building coupled ocean-sea ice model..." +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +omip = Simulation(omip, Δt=10minutes, stop_time=60days) + +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 + +add_callback!(omip, progress, IterationInterval(1)) + +@info "Starting simulation..." +run!(omip) + +omip.Δt = 10minutes +omip.stop_time = simulation_period + +run!(omip) \ No newline at end of file From abac83879c38abe4a77746bae823e804fd456ac8 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Wed, 1 Oct 2025 21:40:54 +0000 Subject: [PATCH 189/258] use oceananigans fixed branch --- Manifest.toml | 22 ++++++++++++---------- Project.toml | 4 ++-- src/ClimaOcean.jl | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index bbb48d88c..a56a9fa76 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.11.6" manifest_format = "2.0" -project_hash = "2033fc2574fe13596dbb816d1dde3aa0d3072a4d" +project_hash = "8e07c9559cfd858e914c4c0b10f5cd8ce4bc243c" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -213,7 +213,7 @@ version = "0.19.1+0" [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "2dc7e793f69084fa821997a3fa97842276e220da" +path = "/home/ext_xinkai_caltech_edu/.julia/dev/ClimaSeaIce" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.3.7" @@ -279,9 +279,9 @@ version = "1.0.0" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "0037835448781bb46feb39866934e243886d756a" +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.18.0" +version = "4.18.1" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -984,9 +984,11 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "0b4e7bbd1cdf8dec20401159598dc76c7c4d40fe" +git-tree-sha1 = "40921ee0aa4d6fd06a19478294887c36489ab769" +repo-rev = "ss/fix-distributed-memory-issue" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.99.2" +version = "0.100.0" [deps.Oceananigans.extensions] OceananigansAMDGPUExt = "AMDGPU" @@ -1045,9 +1047,9 @@ version = "1.5.0" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2ae7d4ddec2e13ad3bddf5c0796f7547cf682391" +git-tree-sha1 = "f19301ae653233bc88b1810ae908194f07f8db9d" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.2+0" +version = "3.5.4+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] @@ -1449,9 +1451,9 @@ version = "1.11.0" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "ForwardDiff", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "14ec5f1776187fd9a1849a4f59e6d22f706a6fb5" +git-tree-sha1 = "e3a9fe706f095c6a176a76ea4613c57900898999" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.14.1" +version = "0.14.2" [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" diff --git a/Project.toml b/Project.toml index aa74be19d..0c91a2ebb 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.5" +ClimaSeaIce = "0.3" CondaPkg = "0.2.28" CubicSplines = "0.2" DataDeps = "0.7" @@ -55,7 +55,7 @@ JLD2 = "0.4, 0.5, 0.6" KernelAbstractions = "0.9" MPI = "0.20" NCDatasets = "0.12, 0.13, 0.14" -Oceananigans = "0.97.6, 0.98, 0.99" +Oceananigans = "0.97.6, 0.98, 0.99, 0.100" OffsetArrays = "1.14" PrecompileTools = "1" PythonCall = "0.9" diff --git a/src/ClimaOcean.jl b/src/ClimaOcean.jl index 7f4edb40e..e10c0192c 100644 --- a/src/ClimaOcean.jl +++ b/src/ClimaOcean.jl @@ -107,7 +107,7 @@ using PrecompileTools: @setup_workload, @compile_workload Nx, Ny, Nz = 32, 32, 10 @compile_workload begin depth = 6000 - z = Oceananigans.Grids.ExponentialCoordinate(Nz, -depth, 0) + z = Oceananigans.Grids.ExponentialDiscretization(Nz, -depth, 0) grid = Oceananigans.OrthogonalSphericalShellGrids.TripolarGrid(CPU(); size=(Nx, Ny, Nz), halo=(7, 7, 7), z) grid = ImmersedBoundaryGrid(grid, GridFittedBottom((x, y) -> -5000)) # ocean = ocean_simulation(grid) From 7f2f37da90979ca318f5c714c6551435237f0ad8 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Wed, 1 Oct 2025 14:41:30 -0700 Subject: [PATCH 190/258] a "technically working" script --- .../oneeighth_degree_simulation_minimal.jl | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl index 515a22445..19acdc5ca 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl @@ -5,6 +5,8 @@ using Oceananigans.Grids using Oceananigans.Units using Oceananigans.OrthogonalSphericalShellGrids using Oceananigans.Architectures: on_architecture +using Oceananigans.DistributedComputations: Equal +using Oceananigans.BoundaryConditions: fill_halo_regions! using ClimaOcean.OceanSimulations using ClimaOcean.JRA55 using ClimaOcean.DataWrangling @@ -19,7 +21,8 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address # arch = GPU() -arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) # arch = Distributed(CPU(), partition=Partition(1, 2), synchronized_communication=true) @info "Architecture $(arch)" @@ -28,7 +31,8 @@ Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction Nz = 100 -z_faces = ExponentialCoordinate(Nz, -6000, 0) +# z_faces = ExponentialCoordinate(Nz, -6000, 0) +z_faces = ExponentialDiscretization(Nz, -6000, 0) const z_surf = z_faces(Nz) @@ -60,7 +64,8 @@ using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity momentum_advection = WENOVectorInvariant() tracer_advection = WENO(order=7) -free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=12minutes) +# free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=12minutes) +free_surface = SplitExplicitFreeSurface(grid; substeps = 70) @info "Free surface", free_surface obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() # CATKE @@ -85,8 +90,18 @@ simulation_period = Dates.value(Second(end_date - start_date)) inpainting = NearestNeighborInpainting(50) @info "Setting initial conditions..." -set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir), - S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir); inpainting) + +Tᵢ = Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir) +Sᵢ = Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir) + +set!(ocean.model.tracers.T, Tᵢ; inpainting) +set!(ocean.model.tracers.S, Sᵢ; inpainting) + +fill_halo_regions!(ocean.model.tracers.T) +fill_halo_regions!(ocean.model.tracers.S) + +# set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir), + # S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir); inpainting) @info ocean.model.clock From 3de93e999d532d7bbb74a3f104f806e7f90a3093 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Thu, 2 Oct 2025 11:41:15 -0700 Subject: [PATCH 191/258] Refactor sea-ice initialization and adjust simulation time step --- .../oneeighth_degree_simulation_minimal.jl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl index 19acdc5ca..bd9ddeb8b 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl @@ -113,8 +113,14 @@ fill_halo_regions!(ocean.model.tracers.S) sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) @info "Setting sea-ice initial conditions..." -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir), - ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir), inpainting = nothing) +hᵢ = Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, date=start_date) +ℵᵢ = Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, date=start_date) + +set!(sea_ice.model.tracers.h, hᵢ; inpainting) +set!(sea_ice.model.tracers.ℵ, ℵᵢ; inpainting) + +fill_halo_regions!(sea_ice.model.tracers.h) +fill_halo_regions!(sea_ice.model.tracers.ℵ) ##### ##### A Prescribed Atmosphere model @@ -135,7 +141,7 @@ radiation = Radiation() @info "Building coupled ocean-sea ice model..." omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=10minutes, stop_time=60days) +omip = Simulation(omip, Δt=5minutes, stop_time=60days) wall_time = Ref(time_ns()) @@ -172,6 +178,7 @@ add_callback!(omip, progress, IterationInterval(1)) @info "Starting simulation..." run!(omip) +@info "Initialization complete. Running the rest..." omip.Δt = 10minutes omip.stop_time = simulation_period From 76f5528c82cf3819746a8199f97b9912112670d8 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Thu, 2 Oct 2025 11:50:29 -0700 Subject: [PATCH 192/258] no inpainting for sea ice! --- .../omip_prototype/oneeighth_degree_simulation_minimal.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl index bd9ddeb8b..59e9dff97 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl @@ -116,8 +116,8 @@ sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) hᵢ = Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, date=start_date) ℵᵢ = Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, date=start_date) -set!(sea_ice.model.tracers.h, hᵢ; inpainting) -set!(sea_ice.model.tracers.ℵ, ℵᵢ; inpainting) +set!(sea_ice.model.tracers.h, hᵢ; inpainting=nothing) +set!(sea_ice.model.tracers.ℵ, ℵᵢ; inpainting=nothing) fill_halo_regions!(sea_ice.model.tracers.h) fill_halo_regions!(sea_ice.model.tracers.ℵ) From a2fef5c441e9743ec3a64c6addbef725ce3470d0 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Thu, 2 Oct 2025 12:52:03 -0700 Subject: [PATCH 193/258] Refactor sea-ice initial condition setting for improved clarity --- .../omip_prototype/oneeighth_degree_simulation_minimal.jl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl index 59e9dff97..5391e84bb 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl @@ -113,11 +113,8 @@ fill_halo_regions!(ocean.model.tracers.S) sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) @info "Setting sea-ice initial conditions..." -hᵢ = Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, date=start_date) -ℵᵢ = Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, date=start_date) - -set!(sea_ice.model.tracers.h, hᵢ; inpainting=nothing) -set!(sea_ice.model.tracers.ℵ, ℵᵢ; inpainting=nothing) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, date=start_date), + ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, date=start_date)) fill_halo_regions!(sea_ice.model.tracers.h) fill_halo_regions!(sea_ice.model.tracers.ℵ) From bad6fb18f2af1eba501e89e4823899f145993eae Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 3 Oct 2025 15:51:19 -0700 Subject: [PATCH 194/258] first fix, doesn't solve the nan issue yet --- src/DataWrangling/Copernicus/Copernicus.jl | 38 +++++++++++++++------- src/DataWrangling/metadata_field.jl | 19 +++++++---- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/DataWrangling/Copernicus/Copernicus.jl b/src/DataWrangling/Copernicus/Copernicus.jl index 2ee7f0116..7005bdf99 100644 --- a/src/DataWrangling/Copernicus/Copernicus.jl +++ b/src/DataWrangling/Copernicus/Copernicus.jl @@ -22,7 +22,8 @@ import ClimaOcean.DataWrangling: metadata_filename, inpainted_metadata_path, reversed_vertical_axis, - available_variables + available_variables, + is_three_dimensional using Scratch @@ -129,20 +130,33 @@ end inpainted_metadata_path(metadata::CopernicusMetadata) = joinpath(metadata.dir, inpainted_metadata_filename(metadata)) -location(::CopernicusMetadata) = (Center, Center, Center) +copernicus_location(metadata::CopernicusMetadata) = is_three_dimensional(metadata) ? (Center, Center, Center) : (Center, Center, Nothing) + +location(metadata::CopernicusMetadata) = copernicus_location(metadata) longitude_interfaces(::CopernicusMetadata) = (0, 360) latitude_interfaces(::CopernicusMetadata) = (-80, 90) +is_three_dimensional(metadata::CopernicusMetadata) = + metadata.name == :temperature || + metadata.name == :salinity || + metadata.name == :u_velocity || + metadata.name == :v_velocity + function z_interfaces(metadata::CopernicusMetadata) - path = metadata_path(metadata) - ds = Dataset(path) - zc = - reverse(ds["depth"][:]) - close(ds) - dz = zc[2] - zc[1] - zf = zc[1:end-1] .+ zc[2:end] - push!(zf, 0) - pushfirst!(zf, zf[1] - dz) - return zf + # Check if this is a 2D surface variable + if !is_three_dimensional(metadata) + return (0, 1) + else + path = metadata_path(metadata) + ds = Dataset(path) + zc = - reverse(ds["depth"][:]) + close(ds) + dz = zc[2] - zc[1] + zf = zc[1:end-1] .+ zc[2:end] + push!(zf, 0) + pushfirst!(zf, zf[1] - dz) + return zf + end end -end # module Copernicus +end # module Copernicus \ No newline at end of file diff --git a/src/DataWrangling/metadata_field.jl b/src/DataWrangling/metadata_field.jl index a57b6622c..86130e19f 100644 --- a/src/DataWrangling/metadata_field.jl +++ b/src/DataWrangling/metadata_field.jl @@ -83,7 +83,8 @@ function Field(metadata::Metadatum, arch=CPU(); inpainting = default_inpainting(metadata), mask = nothing, halo = (3, 3, 3), - cache_inpainted_data = true) + cache_inpainted_data = true, + fill_nans = nothing) download_dataset(metadata) @@ -118,7 +119,7 @@ function Field(metadata::Metadatum, arch=CPU(); # Retrieve data from file according to metadata type data = retrieve_data(metadata) - set_metadata_field!(field, data, metadata) + set_metadata_field!(field, data, metadata; fill_nans) fill_halo_regions!(field) if !isnothing(inpainting) @@ -172,7 +173,7 @@ struct AverageNorthSouth end @inline mangle(i, j, k, data, ::ShiftSouth) = @inbounds data[i, j-1, k] @inline mangle(i, j, k, data, ::AverageNorthSouth) = @inbounds (data[i, j+1, k] + data[i, j, k]) / 2 -function set_metadata_field!(field, data, metadatum) +function set_metadata_field!(field, data, metadatum; fill_nans) grid = field.grid arch = architecture(grid) @@ -206,12 +207,13 @@ function set_metadata_field!(field, data, metadatum) end data = on_architecture(arch, data) - Oceananigans.Utils.launch!(arch, grid, spec, _kernel, field, data, mangling, temp_units, conc_units) + Oceananigans.Utils.launch!(arch, grid, spec, _kernel, field, data, mangling, temp_units, conc_units, fill_nans) return nothing end -@kernel function _set_2d_metadata_field!(field, data, mangling, temp_units, conc_units) +# TODO: sort out elegant way to handle NaNs for sea ice data in GLORYS +@kernel function _set_2d_metadata_field!(field, data, mangling, temp_units, conc_units, fill_nans) i, j = @index(Global, NTuple) d = mangle(i, j, data, mangling) @@ -223,13 +225,16 @@ end elseif !isnothing(conc_units) d = convert_concentration(d, conc_units) end + d = ifelse(isnothing(fill_nans), d, ifelse(isnan(d), convert(FT, 0), d)) + + d = convert_temperature(d, temp_units) @inbounds field[i, j, 1] = d end @inline nan_convert_missing(FT, ::Missing) = convert(FT, NaN) @inline nan_convert_missing(FT, d::Number) = convert(FT, d) -@kernel function _set_3d_metadata_field!(field, data, mangling, temp_units, conc_units) +@kernel function _set_3d_metadata_field!(field, data, mangling, temp_units, conc_units, fill_nans) i, j, k = @index(Global, NTuple) d = mangle(i, j, k, data, mangling) @@ -241,6 +246,8 @@ end elseif !isnothing(conc_units) d = convert_concentration(d, conc_units) end + d = ifelse(isnothing(fill_nans), d, ifelse(isnan(d), convert(FT, 0), d)) + @inbounds field[i, j, k] = d end From fb347270e64feb938c66474113845593fa032d70 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 3 Oct 2025 16:51:40 -0700 Subject: [PATCH 195/258] write ValueInpainting, but leaves vestigial maxiter value --- src/DataWrangling/inpainting.jl | 66 +++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/src/DataWrangling/inpainting.jl b/src/DataWrangling/inpainting.jl index dde0f1f91..93414de91 100644 --- a/src/DataWrangling/inpainting.jl +++ b/src/DataWrangling/inpainting.jl @@ -11,6 +11,30 @@ struct NearestNeighborInpainting{M} maxiter :: M end +""" + ValueInpainting{V} + +A structure representing a simple value inpainting algorithm, where all missing values are +substituted with a specified constant value. + +# Fields +- `value :: V`: The constant value to use for inpainting missing data. +- `maxiter`: For cache compatibility (not used in the algorithm itself). Defaults to 0. + +# Example +```julia +inpainting = ValueInpainting(0.0) # Fill missing values with 0 +inpaint_mask!(field, mask; inpainting) +``` +""" +struct ValueInpainting{V, M} + value :: V + maxiter :: M +end + +# Convenience constructor that sets maxiter to a default value +ValueInpainting(value) = ValueInpainting(value, 0) + propagate_horizontally!(field, ::Nothing, substituting_field=deepcopy(field); kw...) = field function propagating(field, mask, iter, inpainting::NearestNeighborInpainting) @@ -18,6 +42,9 @@ function propagating(field, mask, iter, inpainting::NearestNeighborInpainting) return nans > 0 && iter < inpainting.maxiter end +# ValueInpainting doesn't need iteration +propagating(field, mask, iter, inpainting::ValueInpainting) = false + """ propagate_horizontally!(inpainting, field, mask [, substituting_field=deepcopy(field)]) @@ -57,6 +84,17 @@ function propagate_horizontally!(inpainting::NearestNeighborInpainting, field, m return field end +function propagate_horizontally!(inpainting::ValueInpainting, field, mask, + substituting_field=deepcopy(field)) + grid = field.grid + arch = architecture(grid) + + launch!(arch, grid, size(field), _fill_with_number!, field, mask, inpainting.value) + fill_halo_regions!(field) + + return field +end + # Maybe we can remove this propagate field in lieu of a diffusion, # Still we'll need to do this a couple of steps on the original grid @kernel function _propagate_field!(substituting_field, ::NearestNeighborInpainting, field) @@ -102,6 +140,12 @@ end @inbounds field[i, j, k] *= !isnan(field[i, j, k]) end +@kernel function _fill_with_number!(field, mask, value) + i, j, k = @index(Global, NTuple) + FT_value = convert(eltype(field), value) + @inbounds field[i, j, k] = ifelse(mask[i, j, k], FT_value, field[i, j, k]) +end + """ inpaint_mask!(field, mask; inpainting=NearestNeighborInpainting(Inf)) @@ -117,10 +161,24 @@ Arguments - `mask`: Boolean-valued `Field`, values where `mask[i, j, k] == true` are inpainted. -- `inpainting`: The inpainting algorithm to use. The only option is - `NearestNeighborInpainting(maxiter)`, where an average - of the valid surrounding values is used `maxiter` times. - Default: `NearestNeighborInpainting(Inf)`. +- `inpainting`: The inpainting algorithm to use. Options include: + * `NearestNeighborInpainting(maxiter)`: Uses an average + of the valid surrounding values, repeated `maxiter` times. + Default: `NearestNeighborInpainting(Inf)`. + * `ValueInpainting(value)`: Fills all missing values with + the specified constant `value`. + +# Examples +```julia +# Use nearest neighbor inpainting with default settings +inpaint_mask!(field, mask) + +# Fill missing values with zero +inpaint_mask!(field, mask; inpainting=ValueInpainting(0)) + +# Fill missing values with a specific temperature +inpaint_mask!(field, mask; inpainting=ValueInpainting(273.15)) +``` """ function inpaint_mask!(field, mask; inpainting=NearestNeighborInpainting(Inf)) From dee9a1788b4fe362e4dbd2adb0b63bc6daf13280 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 3 Oct 2025 16:54:38 -0700 Subject: [PATCH 196/258] remove fill_nans functionaloty --- src/DataWrangling/metadata_field.jl | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/DataWrangling/metadata_field.jl b/src/DataWrangling/metadata_field.jl index 86130e19f..1802585d3 100644 --- a/src/DataWrangling/metadata_field.jl +++ b/src/DataWrangling/metadata_field.jl @@ -83,8 +83,7 @@ function Field(metadata::Metadatum, arch=CPU(); inpainting = default_inpainting(metadata), mask = nothing, halo = (3, 3, 3), - cache_inpainted_data = true, - fill_nans = nothing) + cache_inpainted_data = true) download_dataset(metadata) @@ -119,7 +118,7 @@ function Field(metadata::Metadatum, arch=CPU(); # Retrieve data from file according to metadata type data = retrieve_data(metadata) - set_metadata_field!(field, data, metadata; fill_nans) + set_metadata_field!(field, data, metadata) fill_halo_regions!(field) if !isnothing(inpainting) @@ -173,7 +172,7 @@ struct AverageNorthSouth end @inline mangle(i, j, k, data, ::ShiftSouth) = @inbounds data[i, j-1, k] @inline mangle(i, j, k, data, ::AverageNorthSouth) = @inbounds (data[i, j+1, k] + data[i, j, k]) / 2 -function set_metadata_field!(field, data, metadatum; fill_nans) +function set_metadata_field!(field, data, metadatum) grid = field.grid arch = architecture(grid) @@ -207,13 +206,13 @@ function set_metadata_field!(field, data, metadatum; fill_nans) end data = on_architecture(arch, data) - Oceananigans.Utils.launch!(arch, grid, spec, _kernel, field, data, mangling, temp_units, conc_units, fill_nans) + Oceananigans.Utils.launch!(arch, grid, spec, _kernel, field, data, mangling, temp_units, conc_units) return nothing end # TODO: sort out elegant way to handle NaNs for sea ice data in GLORYS -@kernel function _set_2d_metadata_field!(field, data, mangling, temp_units, conc_units, fill_nans) +@kernel function _set_2d_metadata_field!(field, data, mangling, temp_units, conc_units) i, j = @index(Global, NTuple) d = mangle(i, j, data, mangling) @@ -225,7 +224,6 @@ end elseif !isnothing(conc_units) d = convert_concentration(d, conc_units) end - d = ifelse(isnothing(fill_nans), d, ifelse(isnan(d), convert(FT, 0), d)) d = convert_temperature(d, temp_units) @inbounds field[i, j, 1] = d @@ -234,7 +232,7 @@ end @inline nan_convert_missing(FT, ::Missing) = convert(FT, NaN) @inline nan_convert_missing(FT, d::Number) = convert(FT, d) -@kernel function _set_3d_metadata_field!(field, data, mangling, temp_units, conc_units, fill_nans) +@kernel function _set_3d_metadata_field!(field, data, mangling, temp_units, conc_units) i, j, k = @index(Global, NTuple) d = mangle(i, j, k, data, mangling) @@ -246,7 +244,6 @@ end elseif !isnothing(conc_units) d = convert_concentration(d, conc_units) end - d = ifelse(isnothing(fill_nans), d, ifelse(isnan(d), convert(FT, 0), d)) @inbounds field[i, j, k] = d end From a8df621a83bf5e16e98a652ecf468bdba4acf81d Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 3 Oct 2025 17:03:10 -0700 Subject: [PATCH 197/258] update default_inpainting to return ValueInpainting for sea ice metrics --- src/DataWrangling/DataWrangling.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataWrangling/DataWrangling.jl b/src/DataWrangling/DataWrangling.jl index e5da9795f..ca0d7ced2 100644 --- a/src/DataWrangling/DataWrangling.jl +++ b/src/DataWrangling/DataWrangling.jl @@ -206,7 +206,7 @@ function default_inpainting(metadata) if metadata.name in (:temperature, :salinity) return NearestNeighborInpainting(Inf) elseif metadata.name in (:sea_ice_thickness, :sea_ice_concentration) - return nothing + return ValueInpainting(0) else return NearestNeighborInpainting(5) end From c33ab4003a5c0a1b5ea3a0bd1425b2bf62a1237a Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 3 Oct 2025 17:29:28 -0700 Subject: [PATCH 198/258] Update sea-ice initial conditions and fix minor typos in simulation script --- .../oneeighth_degree_simulation_minimal.jl | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl index 5391e84bb..f89414bb3 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl @@ -1,3 +1,6 @@ +ENV["ECCO_USERNAME"] = "xkykai" +ENV["ECCO_WEBDAV_PASSWORD"] = "JyaheQ1SzR4yp1gDDkn" + using ClimaOcean using ClimaSeaIce using Oceananigans @@ -22,8 +25,8 @@ import Oceananigans.OutputWriters: checkpointer_address # arch = GPU() # arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) -arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) -# arch = Distributed(CPU(), partition=Partition(1, 2), synchronized_communication=true) +# arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) +arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) @info "Architecture $(arch)" @@ -54,7 +57,7 @@ grid = ImmersedBoundaryGrid(grid, fitted_bottom; active_cells_map=true) @info "Created ImmersedBoundaryGrid" ##### -##### A Propgnostic Ocean model +##### A Prognostic Ocean model ##### using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization @@ -113,11 +116,11 @@ fill_halo_regions!(ocean.model.tracers.S) sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) @info "Setting sea-ice initial conditions..." -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, date=start_date), - ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, date=start_date)) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir=glorys_dir, date=start_date), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir=glorys_dir, date=start_date)) -fill_halo_regions!(sea_ice.model.tracers.h) -fill_halo_regions!(sea_ice.model.tracers.ℵ) +# set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, date=start_date), + # ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, date=start_date)) ##### ##### A Prescribed Atmosphere model @@ -125,11 +128,11 @@ fill_halo_regions!(sea_ice.model.tracers.ℵ) jra55_dir = joinpath(homedir(), "JRA55_data") mkpath(jra55_dir) -dataset = MultiYearJRA55() -jra55_backend = JRA55NetCDFBackend(10) +jra55_dataset = MultiYearJRA55() +jra55_backend = JRA55NetCDFBackend(100) @info "Building atmospheric forcing..." -atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_backend, backend=jra55_backend, include_rivers_and_icebergs=true, start_date) +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_dataset, backend=jra55_backend, include_rivers_and_icebergs=true, start_date) radiation = Radiation() ##### @@ -138,6 +141,8 @@ radiation = Radiation() @info "Building coupled ocean-sea ice model..." omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +@info "Built ocean-sea ice model" omip = Simulation(omip, Δt=5minutes, stop_time=60days) wall_time = Ref(time_ns()) From 3d0a6ffb0b9dbf970fefdf1044cd99bb2899bd41 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 3 Oct 2025 17:29:42 -0700 Subject: [PATCH 199/258] Update Julia version and dependencies in Manifest.toml --- Manifest.toml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index a56a9fa76..6ba7fc68a 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.11.6" +julia_version = "1.11.4" manifest_format = "2.0" project_hash = "8e07c9559cfd858e914c4c0b10f5cd8ce4bc243c" @@ -213,9 +213,9 @@ version = "0.19.1+0" [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -path = "/home/ext_xinkai_caltech_edu/.julia/dev/ClimaSeaIce" +path = "C:\\Users\\xinle\\.julia\\dev\\ClimaSeaIce" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.3.7" +version = "0.3.8" [[deps.CloseOpenIntervals]] deps = ["Static", "StaticArrayInterface"] @@ -279,9 +279,9 @@ version = "1.0.0" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +git-tree-sha1 = "0037835448781bb46feb39866934e243886d756a" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.18.1" +version = "4.18.0" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -1031,7 +1031,7 @@ version = "0.3.27+1" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.5+0" +version = "0.8.1+4" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] @@ -1047,9 +1047,9 @@ version = "1.5.0" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f19301ae653233bc88b1810ae908194f07f8db9d" +git-tree-sha1 = "2ae7d4ddec2e13ad3bddf5c0796f7547cf682391" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.4+0" +version = "3.5.2+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] @@ -1109,9 +1109,9 @@ version = "1.5.0" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "5e9fe23c86d3ca630baa1efcad78575a27f158b2" +git-tree-sha1 = "60f23271568238b236899d00fc290e43d1f2658f" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "3.0.11" +version = "3.0.10" [[deps.Printf]] deps = ["Unicode"] @@ -1451,9 +1451,9 @@ version = "1.11.0" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "ForwardDiff", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "e3a9fe706f095c6a176a76ea4613c57900898999" +git-tree-sha1 = "14ec5f1776187fd9a1849a4f59e6d22f706a6fb5" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.14.2" +version = "0.14.1" [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" @@ -1526,9 +1526,9 @@ version = "0.21.72" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "80d3930c6347cfce7ccf96bd3bafdf079d9c0390" +git-tree-sha1 = "59071150afa35787c1656ba234cf03fdf8e2603f" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.9+0" +version = "2.13.8+0" [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] From c06f864b02f4fc1ca68d7a0a6839e38452f5dee5 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 4 Oct 2025 05:38:15 +0000 Subject: [PATCH 200/258] update ClimaSeaIce and Oceananigans --- Manifest.toml | 67 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 6ba7fc68a..da7e62a05 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.11.4" +julia_version = "1.11.6" manifest_format = "2.0" -project_hash = "8e07c9559cfd858e914c4c0b10f5cd8ce4bc243c" +project_hash = "994bc3384548d592e0292c3b3932a8a7c535d546" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -211,9 +211,15 @@ git-tree-sha1 = "e24c6de116c0735c37e83b8bc05ed60d4d359693" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" version = "0.19.1+0" +[[deps.CatViews]] +deps = ["Random", "Test"] +git-tree-sha1 = "23d1f1e10d4e24374112fcf800ac981d14a54b24" +uuid = "81a5f4ea-a946-549a-aa7e-2a7f63a27d31" +version = "1.0.0" + [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -path = "C:\\Users\\xinle\\.julia\\dev\\ClimaSeaIce" +git-tree-sha1 = "7ea1d7d2539199c82d65779991104652f9c1964e" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" version = "0.3.8" @@ -901,6 +907,28 @@ deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" version = "2.28.6+0" +[[deps.MeshArrays]] +deps = ["CatViews", "Dates", "Distributed", "Glob", "LazyArtifacts", "NearestNeighbors", "Pkg", "Printf", "SharedArrays", "SparseArrays", "Statistics", "Unitful"] +git-tree-sha1 = "fea0859c1406389b3e6657b5376b577ffffdd03a" +uuid = "cb8c808f-1acf-59a3-9d2b-6e38d009f683" +version = "0.3.23" + + [deps.MeshArrays.extensions] + MeshArraysDataDepsExt = ["DataDeps"] + MeshArraysGeoJSONExt = ["GeoJSON"] + MeshArraysJLD2Ext = ["JLD2"] + MeshArraysMakieExt = ["Makie"] + MeshArraysProjExt = ["Proj"] + MeshArraysShapefileExt = ["Shapefile"] + + [deps.MeshArrays.weakdeps] + DataDeps = "124859b0-ceae-595e-8997-d05f6a7a8dfe" + GeoJSON = "61d90e0f-e114-555e-ac52-39dfb47a3ef9" + JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + Proj = "c94c279d-25a6-4763-9509-64d165bea63e" + Shapefile = "8e980c4a-a4fe-5da2-b3a7-4b4b0353a2f4" + [[deps.Metis]] deps = ["CEnum", "LinearAlgebra", "METIS_jll", "SparseArrays"] git-tree-sha1 = "54aca4fd53d39dcd2c3f1bef367b6921e8178628" @@ -972,6 +1000,12 @@ git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" version = "1.1.3" +[[deps.NearestNeighbors]] +deps = ["Distances", "StaticArrays"] +git-tree-sha1 = "ca7e18198a166a1f3eb92a3650d53d94ed8ca8a1" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.22" + [[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" @@ -984,9 +1018,7 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "40921ee0aa4d6fd06a19478294887c36489ab769" -repo-rev = "ss/fix-distributed-memory-issue" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +git-tree-sha1 = "a215a3c5d8b342b41c4968f39d780360d8ec9191" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.100.0" @@ -1031,7 +1063,7 @@ version = "0.3.27+1" [[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"] @@ -1509,6 +1541,27 @@ version = "1.0.2" uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" version = "1.11.0" +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "cec2df8cf14e0844a8c4d770d12347fda5931d72" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.25.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + LatexifyExt = ["Latexify", "LaTeXStrings"] + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" + Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + [[deps.UnsafeAtomics]] git-tree-sha1 = "b13c4edda90890e5b04ba24e20a310fbe6f249ff" uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" From 009ad6aebebe71949ca9ed7d3ce8fc85f09aad1b Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 3 Oct 2025 23:00:09 -0700 Subject: [PATCH 201/258] API --- .../omip_prototype/oneeighth_degree_simulation_minimal.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl index f89414bb3..e84d0dd3b 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl @@ -1,6 +1,3 @@ -ENV["ECCO_USERNAME"] = "xkykai" -ENV["ECCO_WEBDAV_PASSWORD"] = "JyaheQ1SzR4yp1gDDkn" - using ClimaOcean using ClimaSeaIce using Oceananigans From c4e9f45a5edaa4028284a3c4f754bea1262894ea Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 4 Oct 2025 12:33:09 -0700 Subject: [PATCH 202/258] minimal 1deg example --- .../omip_prototype/one_degree_omip_minimal.jl | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 experiments/omip_prototype/one_degree_omip_minimal.jl diff --git a/experiments/omip_prototype/one_degree_omip_minimal.jl b/experiments/omip_prototype/one_degree_omip_minimal.jl new file mode 100644 index 000000000..40c35fdfb --- /dev/null +++ b/experiments/omip_prototype/one_degree_omip_minimal.jl @@ -0,0 +1,130 @@ +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 +using Oceananigans.TurbulenceClosures: DiffusiveFormulation, AdvectiveFormulation +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency + +import Oceananigans.OutputWriters: checkpointer_address + +# arch = GPU() +# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) +arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) + +Nx = 360 # longitudinal direction +Ny = 180 # meridional direction +Nz = 60 + +z_faces = ExponentialDiscretization(Nz, -6000, 0) + +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) + +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation +using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity + +momentum_advection = WENOVectorInvariant(order=5) +tracer_advection = WENO(order=5) + +free_surface = SplitExplicitFreeSurface(grid; substeps = 70) + +κ_skew = 1e3 +κ_symmetric = 1e3 +eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=κ_skew, κ_symmetric=κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) + +@info eddy_closure + +obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() +closure = (obl_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, dir) + +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, dir), + S=Metadatum(:salinity; dataset, date, dir)) + +@info ocean.model.clock + +sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) + +jra55_dir = dir +dataset = RepeatYearJRA55() +backend = JRA55NetCDFBackend(100) + +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true) +radiation = Radiation() + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +omip = Simulation(omip, Δt=20minutes, stop_time=60days) + +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) \ No newline at end of file From 48ec24b323739213f1dfeaf9c716c3773f6ea8e6 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 4 Oct 2025 14:33:14 -0700 Subject: [PATCH 203/258] Add directory path for forcing data in one_degree_omip_minimal.jl --- experiments/omip_prototype/one_degree_omip_minimal.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/experiments/omip_prototype/one_degree_omip_minimal.jl b/experiments/omip_prototype/one_degree_omip_minimal.jl index 40c35fdfb..851e26b9f 100644 --- a/experiments/omip_prototype/one_degree_omip_minimal.jl +++ b/experiments/omip_prototype/one_degree_omip_minimal.jl @@ -56,6 +56,8 @@ eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4), eddy_closure) +dir = joinpath(homedir(), "forcing_data_1deg_minimal") + dataset = EN4Monthly() date = DateTime(1958, 1, 1) @inline mask(x, y, z, t) = z ≥ z_surf - 1 From 4f6ede7e55334a8320e99ce176524207c84aadf0 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 4 Oct 2025 14:57:52 -0700 Subject: [PATCH 204/258] Create directory for forcing data in one_degree_omip_minimal.jl --- experiments/omip_prototype/one_degree_omip_minimal.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/experiments/omip_prototype/one_degree_omip_minimal.jl b/experiments/omip_prototype/one_degree_omip_minimal.jl index 851e26b9f..e628bfdfd 100644 --- a/experiments/omip_prototype/one_degree_omip_minimal.jl +++ b/experiments/omip_prototype/one_degree_omip_minimal.jl @@ -57,6 +57,7 @@ obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4), eddy_closure) dir = joinpath(homedir(), "forcing_data_1deg_minimal") +mkpath(dir) dataset = EN4Monthly() date = DateTime(1958, 1, 1) From f42bb7c64e65f102aec07c65acb49aaa54414fde Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 4 Oct 2025 17:03:25 -0700 Subject: [PATCH 205/258] rename MWE script --- .../{one_degree_omip_minimal.jl => minimal_script_MWE.jl} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename experiments/omip_prototype/{one_degree_omip_minimal.jl => minimal_script_MWE.jl} (97%) diff --git a/experiments/omip_prototype/one_degree_omip_minimal.jl b/experiments/omip_prototype/minimal_script_MWE.jl similarity index 97% rename from experiments/omip_prototype/one_degree_omip_minimal.jl rename to experiments/omip_prototype/minimal_script_MWE.jl index e628bfdfd..340c982bd 100644 --- a/experiments/omip_prototype/one_degree_omip_minimal.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -22,9 +22,9 @@ import Oceananigans.OutputWriters: checkpointer_address # arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) -Nx = 360 # longitudinal direction -Ny = 180 # meridional direction -Nz = 60 +Nx = 2880 # longitudinal direction +Ny = 1440 # meridional direction +Nz = 100 z_faces = ExponentialDiscretization(Nz, -6000, 0) @@ -95,7 +95,7 @@ atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, in radiation = Radiation() omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -omip = Simulation(omip, Δt=20minutes, stop_time=60days) +omip = Simulation(omip, Δt=10minutes, stop_time=60days) wall_time = Ref(time_ns()) From 9dce3bda548f6c2261decfcdb51338835d2c4ba3 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 4 Oct 2025 18:22:03 -0700 Subject: [PATCH 206/258] try GPU --- experiments/omip_prototype/minimal_script_MWE.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index 340c982bd..ed19814fd 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -18,9 +18,9 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address # arch = GPU() -# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) # arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) -arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction From 37f487f1ce877a15224f5b636ff650a0e3d5e941 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 4 Oct 2025 21:38:07 -0700 Subject: [PATCH 207/258] change date, use MultiYearJRA55 --- experiments/omip_prototype/minimal_script_MWE.jl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index ed19814fd..b6bc1e72c 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -18,9 +18,9 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address # arch = GPU() -arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) # arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) -# arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) +arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction @@ -60,7 +60,7 @@ dir = joinpath(homedir(), "forcing_data_1deg_minimal") mkpath(dir) dataset = EN4Monthly() -date = DateTime(1958, 1, 1) +date = DateTime(1993, 1, 1) @inline mask(x, y, z, t) = z ≥ z_surf - 1 Smetadata = Metadata(:salinity; dataset, dir) @@ -75,7 +75,6 @@ ocean = ocean_simulation(grid; Δt=1minutes, closure) dataset = EN4Monthly() -date = DateTime(1958, 1, 1) set!(ocean.model, T=Metadatum(:temperature; dataset, date, dir), S=Metadatum(:salinity; dataset, date, dir)) @@ -88,10 +87,10 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) jra55_dir = dir -dataset = RepeatYearJRA55() +dataset = MultiYearJRA55() backend = JRA55NetCDFBackend(100) -atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true) +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date=date) radiation = Radiation() omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) From 0c272b01f4ed57b15f04240dc76fa1cb60ae5c75 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 4 Oct 2025 21:39:50 -0700 Subject: [PATCH 208/258] set ECCO date too --- experiments/omip_prototype/minimal_script_MWE.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index b6bc1e72c..955df5582 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -18,9 +18,9 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address # arch = GPU() -# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) # arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) -arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction @@ -83,8 +83,8 @@ set!(ocean.model, T=Metadatum(:temperature; dataset, date, dir), sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), - ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir, date), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir, date)) jra55_dir = dir dataset = MultiYearJRA55() From d4c22a0e6fa621d9c654401656fd27432ab3f18b Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 4 Oct 2025 21:48:39 -0700 Subject: [PATCH 209/258] Switch architecture to CPU for minimal_script_MWE.jl --- experiments/omip_prototype/minimal_script_MWE.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index 955df5582..c2fc33586 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -18,9 +18,9 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address # arch = GPU() -arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) # arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) -# arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) +arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction From 5ed95ac21c06cd4314060b1579e6c95a05f9936c Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sun, 5 Oct 2025 22:29:45 -0700 Subject: [PATCH 210/258] remove GM, change WENO, remove S restoring, start date for MultiYearJRA55 --- .../omip_prototype/minimal_script_MWE.jl | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index c2fc33586..dc45bdc67 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -18,9 +18,8 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address # arch = GPU() -# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) -# arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) -arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) +arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction @@ -35,28 +34,18 @@ grid = TripolarGrid(arch; z = z_faces, halo = (7, 7, 7)) -bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=75) +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=10) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) -using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization -using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation -using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity - -momentum_advection = WENOVectorInvariant(order=5) -tracer_advection = WENO(order=5) +momentum_advection = WENOVectorInvariant() +tracer_advection = WENO(order=7) free_surface = SplitExplicitFreeSurface(grid; substeps = 70) -κ_skew = 1e3 -κ_symmetric = 1e3 -eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=κ_skew, κ_symmetric=κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) - -@info eddy_closure - obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() -closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4), eddy_closure) +closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4)) -dir = joinpath(homedir(), "forcing_data_1deg_minimal") +dir = joinpath(homedir(), "forcing_data_1deg_minimal_gpu") mkpath(dir) dataset = EN4Monthly() @@ -64,14 +53,11 @@ date = DateTime(1993, 1, 1) @inline mask(x, y, z, t) = z ≥ z_surf - 1 Smetadata = Metadata(:salinity; dataset, dir) -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() @@ -93,7 +79,10 @@ backend = JRA55NetCDFBackend(100) atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date=date) radiation = Radiation() +@info "Setting up Ocean-SeaIce-Atmosphere model..." omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +@info "Setting up OMIP simulation..." omip = Simulation(omip, Δt=10minutes, stop_time=60days) wall_time = Ref(time_ns()) @@ -129,4 +118,5 @@ end # And add it as a callback to the simulation. add_callback!(omip, progress, IterationInterval(1)) +@info "Starting OMIP simulation..." run!(omip) \ No newline at end of file From 59d3004bb0d76f4272692324d25d3b2d1a744835 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 6 Oct 2025 11:27:15 -0700 Subject: [PATCH 211/258] refactor location function for clarity and consistency in CopernicusMetadata --- src/DataWrangling/Copernicus/Copernicus.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/DataWrangling/Copernicus/Copernicus.jl b/src/DataWrangling/Copernicus/Copernicus.jl index 7005bdf99..8c7ac0dce 100644 --- a/src/DataWrangling/Copernicus/Copernicus.jl +++ b/src/DataWrangling/Copernicus/Copernicus.jl @@ -130,9 +130,7 @@ end inpainted_metadata_path(metadata::CopernicusMetadata) = joinpath(metadata.dir, inpainted_metadata_filename(metadata)) -copernicus_location(metadata::CopernicusMetadata) = is_three_dimensional(metadata) ? (Center, Center, Center) : (Center, Center, Nothing) - -location(metadata::CopernicusMetadata) = copernicus_location(metadata) +location(metadata::CopernicusMetadata) = is_three_dimensional(metadata) ? (Center, Center, Center) : (Center, Center, Nothing) longitude_interfaces(::CopernicusMetadata) = (0, 360) latitude_interfaces(::CopernicusMetadata) = (-80, 90) From 9bcc290db698d455126919c228e54046b672bdcf Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 6 Oct 2025 12:04:53 -0700 Subject: [PATCH 212/258] Add logging for architecture setup in minimal_script_MWE.jl --- experiments/omip_prototype/minimal_script_MWE.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index dc45bdc67..2fd4a9c0f 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -20,6 +20,7 @@ import Oceananigans.OutputWriters: checkpointer_address # arch = GPU() arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) # arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) +@info "Architecture $(arch)" Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction From eac9e523cdfd038e4c32875b6f9c0ca855fbe76d Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 09:57:31 -0700 Subject: [PATCH 213/258] update atmosphere state to load correct time indices --- .../PrescribedAtmospheres.jl | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 4ececb707..0851f3f93 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -409,18 +409,21 @@ function PrescribedAtmosphere(grid, times=[zero(grid)]; thermodynamics_parameters = AtmosphereThermodynamicsParameters(FT) end - return PrescribedAtmosphere(grid, - clock, - velocities, - pressure, - tracers, - freshwater_flux, - auxiliary_freshwater_flux, - downwelling_radiation, - thermodynamics_parameters, - times, - convert(FT, surface_layer_height), - convert(FT, boundary_layer_height)) + atmosphere = PrescribedAtmosphere(grid, + clock, + velocities, + pressure, + tracers, + freshwater_flux, + auxiliary_freshwater_flux, + downwelling_radiation, + thermodynamics_parameters, + times, + convert(FT, surface_layer_height), + convert(FT, boundary_layer_height)) + update_state!(atmosphere) + + return atmosphere end struct TwoBandDownwellingRadiation{SW, LW} From 7e2f67ab88efcfef4822cc2b1b30d666000de99d Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 10:12:32 -0700 Subject: [PATCH 214/258] fix spacing --- .../PrescribedAtmospheres.jl | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/OceanSeaIceModels/PrescribedAtmospheres.jl b/src/OceanSeaIceModels/PrescribedAtmospheres.jl index 0851f3f93..e7a3ca18c 100644 --- a/src/OceanSeaIceModels/PrescribedAtmospheres.jl +++ b/src/OceanSeaIceModels/PrescribedAtmospheres.jl @@ -409,18 +409,18 @@ function PrescribedAtmosphere(grid, times=[zero(grid)]; thermodynamics_parameters = AtmosphereThermodynamicsParameters(FT) end - atmosphere = PrescribedAtmosphere(grid, - clock, - velocities, - pressure, - tracers, - freshwater_flux, - auxiliary_freshwater_flux, - downwelling_radiation, - thermodynamics_parameters, - times, - convert(FT, surface_layer_height), - convert(FT, boundary_layer_height)) + atmosphere = PrescribedAtmosphere(grid, + clock, + velocities, + pressure, + tracers, + freshwater_flux, + auxiliary_freshwater_flux, + downwelling_radiation, + thermodynamics_parameters, + times, + convert(FT, surface_layer_height), + convert(FT, boundary_layer_height)) update_state!(atmosphere) return atmosphere From 58f62d39eff732c8a61721263b4515e3e5d88a33 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 10:21:28 -0700 Subject: [PATCH 215/258] just to test simulation --- .../omip_prototype/minimal_script_MWE.jl | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index 2fd4a9c0f..af792dcb0 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -18,8 +18,8 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address # arch = GPU() -arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) -# arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) +# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) +arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) @info "Architecture $(arch)" Nx = 2880 # longitudinal direction @@ -29,11 +29,14 @@ Nz = 100 z_faces = ExponentialDiscretization(Nz, -6000, 0) const z_surf = z_faces(Nz) +halo_size = 7 grid = TripolarGrid(arch; size = (Nx, Ny, Nz), z = z_faces, - halo = (7, 7, 7)) + halo = (halo_size, halo_size, halo_size)) + +@info "halo size: $(halo_size)" bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=10) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) @@ -43,14 +46,16 @@ tracer_advection = WENO(order=7) free_surface = SplitExplicitFreeSurface(grid; substeps = 70) -obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() +obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4)) -dir = joinpath(homedir(), "forcing_data_1deg_minimal_gpu") +dir = joinpath(homedir(), "forcing_data_1deg_minimal_multi40_backend3") mkpath(dir) dataset = EN4Monthly() -date = DateTime(1993, 1, 1) +start_date = DateTime(1993, 1, 1) +end_date = start_date + Month(3) + @inline mask(x, y, z, t) = z ≥ z_surf - 1 Smetadata = Metadata(:salinity; dataset, dir) @@ -63,21 +68,26 @@ ocean = ocean_simulation(grid; Δt=1minutes, dataset = EN4Monthly() -set!(ocean.model, T=Metadatum(:temperature; dataset, date, dir), - S=Metadatum(:salinity; dataset, date, dir)) +set!(ocean.model, T=Metadatum(:temperature; dataset, start_date, dir), + S=Metadatum(:salinity; dataset, start_date, dir)) @info ocean.model.clock sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir, date), - ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir, date)) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir, start_date), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir, start_date)) -jra55_dir = dir +jra55_dir = joinpath(homedir(), "JRA55_data") dataset = MultiYearJRA55() -backend = JRA55NetCDFBackend(100) +# dataset = RepeatYearJRA55() +backend = JRA55NetCDFBackend(3) + +@info "dataset: $dataset" + +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) -atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date=date) +@info "atmosphere: $atmosphere" radiation = Radiation() @info "Setting up Ocean-SeaIce-Atmosphere model..." From b6ff54abb0f7d117668bbe7e0e086d713deb6726 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 10:27:34 -0700 Subject: [PATCH 216/258] using glorys to initialize --- .../oneeighth_degree_simulation_minimal.jl | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl index e84d0dd3b..abe1db92e 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl @@ -3,15 +3,12 @@ using ClimaSeaIce using Oceananigans using Oceananigans.Grids using Oceananigans.Units -using Oceananigans.OrthogonalSphericalShellGrids using Oceananigans.Architectures: on_architecture using Oceananigans.DistributedComputations: Equal using Oceananigans.BoundaryConditions: fill_halo_regions! using ClimaOcean.OceanSimulations -using ClimaOcean.JRA55 using ClimaOcean.DataWrangling using ClimaOcean.DataWrangling: NearestNeighborInpainting -using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium using Printf using Dates using CUDA @@ -31,7 +28,6 @@ Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction Nz = 100 -# z_faces = ExponentialCoordinate(Nz, -6000, 0) z_faces = ExponentialDiscretization(Nz, -6000, 0) const z_surf = z_faces(Nz) @@ -56,15 +52,9 @@ grid = ImmersedBoundaryGrid(grid, fitted_bottom; active_cells_map=true) ##### ##### A Prognostic Ocean model ##### - -using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization -using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation -using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity - momentum_advection = WENOVectorInvariant() tracer_advection = WENO(order=7) -# free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=12minutes) free_surface = SplitExplicitFreeSurface(grid; substeps = 70) @info "Free surface", free_surface @@ -85,7 +75,7 @@ ocean = ocean_simulation(grid; Δt=1minutes, closure) start_date = DateTime(1993, 1, 1) -end_date = DateTime(2003, 4, 1) +end_date = start_date + Month(3) simulation_period = Dates.value(Second(end_date - start_date)) inpainting = NearestNeighborInpainting(50) @@ -100,11 +90,6 @@ set!(ocean.model.tracers.S, Sᵢ; inpainting) fill_halo_regions!(ocean.model.tracers.T) fill_halo_regions!(ocean.model.tracers.S) -# set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir), - # S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir); inpainting) - -@info ocean.model.clock - ##### ##### A Prognostic Sea-ice model ##### @@ -113,11 +98,8 @@ fill_halo_regions!(ocean.model.tracers.S) sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) @info "Setting sea-ice initial conditions..." -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir=glorys_dir, date=start_date), - ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir=glorys_dir, date=start_date)) - -# set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, date=start_date), - # ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, date=start_date)) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir, date=start_date), + ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir, date=start_date)) ##### ##### A Prescribed Atmosphere model @@ -126,10 +108,10 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), jra55_dir = joinpath(homedir(), "JRA55_data") mkpath(jra55_dir) jra55_dataset = MultiYearJRA55() -jra55_backend = JRA55NetCDFBackend(100) +jra55_backend = JRA55NetCDFBackend(3) @info "Building atmospheric forcing..." -atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_dataset, backend=jra55_backend, include_rivers_and_icebergs=true, start_date) +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_dataset, backend=jra55_backend, include_rivers_and_icebergs=true, start_date, end_date) radiation = Radiation() ##### @@ -177,8 +159,8 @@ add_callback!(omip, progress, IterationInterval(1)) @info "Starting simulation..." run!(omip) -@info "Initialization complete. Running the rest..." -omip.Δt = 10minutes -omip.stop_time = simulation_period +# @info "Initialization complete. Running the rest..." +# omip.Δt = 10minutes +# omip.stop_time = simulation_period -run!(omip) \ No newline at end of file +# run!(omip) \ No newline at end of file From 3166ed275badb9bd26e2a51d58f826da54559b57 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 10:41:41 -0700 Subject: [PATCH 217/258] fix EN4 start date argument --- experiments/omip_prototype/minimal_script_MWE.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index af792dcb0..616e96e3a 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -75,12 +75,11 @@ set!(ocean.model, T=Metadatum(:temperature; dataset, start_date, dir), sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir, start_date), - ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir, start_date)) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir, date=start_date), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir, date=start_date)) jra55_dir = joinpath(homedir(), "JRA55_data") dataset = MultiYearJRA55() -# dataset = RepeatYearJRA55() backend = JRA55NetCDFBackend(3) @info "dataset: $dataset" From d580079c07d40cd94ad88c56d4a8e2e9742ae631 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 10:47:27 -0700 Subject: [PATCH 218/258] add info logs for one-eighth degree simulation setup --- experiments/omip_prototype/minimal_script_MWE.jl | 1 + .../omip_prototype/oneeighth_degree_simulation_minimal.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index 616e96e3a..c02e807f6 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -17,6 +17,7 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address +@info "Running one-eighth degree simulation with minimal setup" # arch = GPU() # arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl index abe1db92e..818dbf2a9 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation_minimal.jl @@ -17,9 +17,9 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address +@info "GLORYS: Running one-eighth degree simulation" # arch = GPU() # arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) -# arch = Distributed(GPU(); partition = Partition(y = Equal()), synchronized_communication=true) arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) @info "Architecture $(arch)" From e5d53ac8b17fc47ae1feb0ae84367c1601645c04 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 11:18:22 -0700 Subject: [PATCH 219/258] fix: correct argument name for temperature and salinity metadata in ocean model setup --- experiments/omip_prototype/minimal_script_MWE.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index c02e807f6..2cb29714c 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -69,8 +69,8 @@ ocean = ocean_simulation(grid; Δt=1minutes, dataset = EN4Monthly() -set!(ocean.model, T=Metadatum(:temperature; dataset, start_date, dir), - S=Metadatum(:salinity; dataset, start_date, dir)) +set!(ocean.model, T=Metadatum(:temperature; dataset, date=start_date, dir), + S=Metadatum(:salinity; dataset, date=start_date, dir)) @info ocean.model.clock From 50fa8fc5f550902f892366a30e36b57c5425b5e8 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Wed, 8 Oct 2025 00:19:47 +0000 Subject: [PATCH 220/258] add MPIPreferences, up Manifest --- Manifest.toml | 119 +++++++++++++++++++++++++------------------------- Project.toml | 2 + 2 files changed, 62 insertions(+), 59 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index da7e62a05..d8ebf5ff0 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.11.6" manifest_format = "2.0" -project_hash = "994bc3384548d592e0292c3b3932a8a7c535d546" +project_hash = "17aae685aef2ba02d64e4577c6218c1cf723a81c" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -217,6 +217,23 @@ git-tree-sha1 = "23d1f1e10d4e24374112fcf800ac981d14a54b24" uuid = "81a5f4ea-a946-549a-aa7e-2a7f63a27d31" version = "1.0.0" +[[deps.ChunkCodecCore]] +git-tree-sha1 = "51f4c10ee01bda57371e977931de39ee0f0cdb3e" +uuid = "0b6fb165-00bc-4d37-ab8b-79f91016dbe1" +version = "1.0.0" + +[[deps.ChunkCodecLibZlib]] +deps = ["ChunkCodecCore", "Zlib_jll"] +git-tree-sha1 = "cee8104904c53d39eb94fd06cbe60cb5acde7177" +uuid = "4c0bbee4-addc-4d73-81a0-b6caacae83c8" +version = "1.0.0" + +[[deps.ChunkCodecLibZstd]] +deps = ["ChunkCodecCore", "Zstd_jll"] +git-tree-sha1 = "34d9873079e4cb3d0c62926a225136824677073f" +uuid = "55437552-ac27-4d47-9aa3-63184e8fd398" +version = "1.0.0" + [[deps.ClimaSeaIce]] deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] git-tree-sha1 = "7ea1d7d2539199c82d65779991104652f9c1964e" @@ -262,10 +279,10 @@ uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" version = "0.13.1" [[deps.CommonDataModel]] -deps = ["CFTime", "DataStructures", "Dates", "Preferences", "Printf", "Statistics"] -git-tree-sha1 = "1985a3201d376bf13a866527e19c2272c252870f" +deps = ["CFTime", "DataStructures", "Dates", "DiskArrays", "Preferences", "Printf", "Statistics"] +git-tree-sha1 = "675149c3c06350dabb9a807ca3dd473de8173703" uuid = "1fbeeb36-5f17-413c-809b-666fb144f157" -version = "0.3.10" +version = "0.4.1" [[deps.CommonSolve]] git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" @@ -285,9 +302,9 @@ version = "1.0.0" [[deps.Compat]] deps = ["TOML", "UUIDs"] -git-tree-sha1 = "0037835448781bb46feb39866934e243886d756a" +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.18.0" +version = "4.18.1" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -369,10 +386,10 @@ uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" version = "1.8.0" [[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +deps = ["OrderedCollections"] +git-tree-sha1 = "6c72198e6a101cccdd4c9731d3985e904ba26037" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.22" +version = "0.19.1" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -461,9 +478,9 @@ version = "3.3.11+0" [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "b66970a70db13f45b7e57fbda1736e1cf72174ea" +git-tree-sha1 = "d60eb76f37d7e5a40cc2e7c36974d864b82dc802" uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.17.0" +version = "1.17.1" weakdeps = ["HTTP"] [deps.FileIO.extensions] @@ -496,9 +513,9 @@ version = "1.11.0" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "Statistics"] -git-tree-sha1 = "ec30748ac561b82e531f6b8ed2fb52498e82f307" +git-tree-sha1 = "8ddb438e956891a63a5367d7fab61550fc720026" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "11.2.5" +version = "11.2.6" weakdeps = ["JLD2"] [deps.GPUArrays.extensions] @@ -512,9 +529,9 @@ version = "0.2.0" [[deps.GPUCompiler]] deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "PrecompileTools", "Preferences", "Scratch", "Serialization", "TOML", "Tracy", "UUIDs"] -git-tree-sha1 = "4b477428fbc2b3f4a906a47c9d4156764074f581" +git-tree-sha1 = "9a8b92a457f55165923fcfe48997b7b93b712fca" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "1.6.2" +version = "1.7.2" [[deps.GPUToolbox]] deps = ["LLVM"] @@ -541,9 +558,9 @@ 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" +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.17" +version = "1.10.19" [[deps.HashArrayMappedTries]] git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" @@ -575,9 +592,9 @@ version = "0.10.5" [[deps.ImageMorphology]] deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] -git-tree-sha1 = "cffa21df12f00ca1a365eb8ed107614b40e8c6da" +git-tree-sha1 = "895205d762ae24a01689f8cc7ad584b55f1fd005" uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" -version = "0.4.6" +version = "0.4.7" [[deps.Inflate]] git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" @@ -634,10 +651,10 @@ uuid = "82899510-4779-5014-852e-03e436cf321d" version = "1.0.0" [[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues", "TranscodingStreams"] -git-tree-sha1 = "d97791feefda45729613fafeccc4fbef3f539151" +deps = ["ChunkCodecLibZlib", "ChunkCodecLibZstd", "FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues"] +git-tree-sha1 = "da2e9b4d1abbebdcca0aa68afa0aa272102baad7" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.5.15" +version = "0.6.2" weakdeps = ["UnPack"] [deps.JLD2.extensions] @@ -695,9 +712,9 @@ version = "0.3.6" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] -git-tree-sha1 = "9c7c721cfd800d87d48c745d8bfb65144f0a91df" +git-tree-sha1 = "0f8b6110c766baff87e54f83986afaf7e2a44d96" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "9.4.2" +version = "9.4.3" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -807,9 +824,9 @@ version = "1.11.0" [[deps.LoggingExtras]] deps = ["Dates", "Logging"] -git-tree-sha1 = "f02b56007b064fbfddb4c9cd60161b6dd0f40df3" +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.1.0" +version = "1.2.0" [[deps.LoopVectorization]] deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] @@ -978,9 +995,9 @@ version = "0.2.4" [[deps.NCDatasets]] deps = ["CFTime", "CommonDataModel", "DataStructures", "Dates", "DiskArrays", "NetCDF_jll", "NetworkOptions", "Printf"] -git-tree-sha1 = "be1095e2b767c19529409ec670bcfb01b825d717" +git-tree-sha1 = "5d5de6613f231d17cecb13a7dcdbb74740134ba8" uuid = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" -version = "0.14.8" +version = "0.14.9" [[deps.NVTX]] deps = ["Colors", "JuliaNVTXCallbacks_jll", "Libdl", "NVTX_jll"] @@ -1018,9 +1035,9 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "a215a3c5d8b342b41c4968f39d780360d8ec9191" +git-tree-sha1 = "9dcc2cc5962882ca2160a64ee4f6c716c2338d55" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.100.0" +version = "0.100.1" [deps.Oceananigans.extensions] OceananigansAMDGPUExt = "AMDGPU" @@ -1079,9 +1096,9 @@ version = "1.5.0" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2ae7d4ddec2e13ad3bddf5c0796f7547cf682391" +git-tree-sha1 = "f19301ae653233bc88b1810ae908194f07f8db9d" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.2+0" +version = "3.5.4+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] @@ -1141,9 +1158,9 @@ version = "1.5.0" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "60f23271568238b236899d00fc290e43d1f2658f" +git-tree-sha1 = "5e9fe23c86d3ca630baa1efcad78575a27f158b2" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "3.0.10" +version = "3.0.11" [[deps.Printf]] deps = ["Unicode"] @@ -1321,9 +1338,9 @@ version = "1.11.0" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "41852b8679f78c8d8961eeadc8f62cef861a52e3" +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.5.1" +version = "2.6.1" [deps.SpecialFunctions.extensions] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -1418,18 +1435,6 @@ deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" version = "7.7.0+0" -[[deps.SurfaceFluxes]] -deps = ["DocStringExtensions", "RootSolvers", "Thermodynamics"] -git-tree-sha1 = "a03a545014be4f89d36d4a7d024b69427a105e9e" -uuid = "49b00bb7-8bd4-4f2b-b78c-51cd0450215f" -version = "0.12.3" - - [deps.SurfaceFluxes.extensions] - CreateParametersExt = "ClimaParams" - - [deps.SurfaceFluxes.weakdeps] - ClimaParams = "5c42b081-d73a-476f-9059-fd94b934656c" - [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" @@ -1453,21 +1458,17 @@ uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" version = "1.10.0" [[deps.TaylorSeries]] -deps = ["LinearAlgebra", "Markdown", "SparseArrays"] -git-tree-sha1 = "2c308aab2e14b399e4b8d6af7c486a241c8ca87a" +deps = ["LinearAlgebra", "Markdown", "Requires", "SparseArrays"] +git-tree-sha1 = "abc13c4d3cccd1703335ba03abdaf0dc8ecc97e2" uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" -version = "0.19.1" +version = "0.17.3" [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]] @@ -1483,9 +1484,9 @@ version = "1.11.0" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "ForwardDiff", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "14ec5f1776187fd9a1849a4f59e6d22f706a6fb5" +git-tree-sha1 = "e3a9fe706f095c6a176a76ea4613c57900898999" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.14.1" +version = "0.14.2" [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" @@ -1579,9 +1580,9 @@ version = "0.21.72" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "59071150afa35787c1656ba234cf03fdf8e2603f" +git-tree-sha1 = "80d3930c6347cfce7ccf96bd3bafdf079d9c0390" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.8+0" +version = "2.13.9+0" [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] diff --git a/Project.toml b/Project.toml index 64937901d..99f7740e8 100644 --- a/Project.toml +++ b/Project.toml @@ -19,6 +19,7 @@ ImageMorphology = "787d08f9-d448-5407-9aad-5290dd7ab264" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" +MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" MeshArrays = "cb8c808f-1acf-59a3-9d2b-6e38d009f683" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" @@ -56,6 +57,7 @@ ImageMorphology = "0.4" JLD2 = "0.4, 0.5, 0.6" KernelAbstractions = "0.9" MPI = "0.20" +MPIPreferences = "0.1.11" MeshArrays = "0.3" NCDatasets = "0.12, 0.13, 0.14" Oceananigans = "0.100" From 5a95d168883628cf9e1b2a0d149541f5b5d0faee Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 17:21:38 -0700 Subject: [PATCH 221/258] fix: update GPU architecture setup and simulation parameters in minimal script --- .../omip_prototype/minimal_script_MWE.jl | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index 2cb29714c..65d3f4381 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -17,14 +17,15 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address -@info "Running one-eighth degree simulation with minimal setup" +ngpus = Int(length(CUDA.devices())) +@info "$ngpus GPUs" # arch = GPU() -# arch = Distributed(GPU(), partition=Partition(1, 4), synchronized_communication=true) -arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) +arch = Distributed(GPU(), partition=Partition(1, ngpus), synchronized_communication=true) +# arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) @info "Architecture $(arch)" -Nx = 2880 # longitudinal direction -Ny = 1440 # meridional direction +Nx = 1440 # longitudinal direction +Ny = 720 # meridional direction Nz = 100 z_faces = ExponentialDiscretization(Nz, -6000, 0) @@ -81,7 +82,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), jra55_dir = joinpath(homedir(), "JRA55_data") dataset = MultiYearJRA55() -backend = JRA55NetCDFBackend(3) +backend = JRA55NetCDFBackend(10) @info "dataset: $dataset" @@ -92,9 +93,12 @@ radiation = Radiation() @info "Setting up Ocean-SeaIce-Atmosphere model..." omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +# omip = OceanSeaIceModel(ocean; atmosphere, radiation) +@info "sea ice model: $(omip.model.sea_ice)" +@info omip @info "Setting up OMIP simulation..." -omip = Simulation(omip, Δt=10minutes, stop_time=60days) +omip = Simulation(omip, Δt=1minutes, stop_time=60days) wall_time = Ref(time_ns()) @@ -107,6 +111,10 @@ function progress(sim) ℵ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) + # Tmax = maximum(ocean.model.tracers.T) + # Tmin = minimum(ocean.model.tracers.T) + Smax = maximum(ocean.model.tracers.S) + Smin = minimum(ocean.model.tracers.S) umax = maximum(ocean.model.velocities.u) vmax = maximum(ocean.model.velocities.v) wmax = maximum(ocean.model.velocities.w) @@ -116,10 +124,12 @@ 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) 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)) + msg5 = @sprintf("extrema(S): (%.2f, %.2f) psu, ", Smax, Smin) + msg6 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) + msg7 = @sprintf("wall time: %s \n", prettytime(step_time)) - @info msg1 * msg2 * msg4 * msg5 * msg6 + @info msg1 * msg2 * msg4 * msg5 * msg6 * msg7 + # @info msg1 * msg4 * msg5 * msg6 * msg7 wall_time[] = time_ns() From a6d8d1910a20f998a62eb901af2582403e484fd9 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 17:33:41 -0700 Subject: [PATCH 222/258] fix: update sea ice model reference in OMIP setup --- experiments/omip_prototype/minimal_script_MWE.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index 65d3f4381..9d5a9f9fa 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -94,7 +94,7 @@ radiation = Radiation() @info "Setting up Ocean-SeaIce-Atmosphere model..." omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) # omip = OceanSeaIceModel(ocean; atmosphere, radiation) -@info "sea ice model: $(omip.model.sea_ice)" +@info "sea ice model: $(omip.sea_ice)" @info omip @info "Setting up OMIP simulation..." From 33588ace9c3c7806f716c110afafaf464c6fe97f Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 7 Oct 2025 21:36:20 -0700 Subject: [PATCH 223/258] increase halo size for native grid in bathymetry regridding --- src/Bathymetry.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bathymetry.jl b/src/Bathymetry.jl index fc619d7d2..e54ac2594 100644 --- a/src/Bathymetry.jl +++ b/src/Bathymetry.jl @@ -101,7 +101,7 @@ function _regrid_bathymetry(target_grid, metadata; arch = architecture(target_grid) - bathymetry_native_grid = native_grid(metadata, arch; halo = (10, 10, 1)) + bathymetry_native_grid = native_grid(metadata, arch; halo = (20, 20, 1)) FT = eltype(target_grid) filepath = metadata_path(metadata) From c461625e1b5045a3516bdb5e835db2c5b4bff9f9 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Wed, 8 Oct 2025 19:31:14 +0000 Subject: [PATCH 224/258] pin CUDA at v0.8.5 --- Manifest.toml | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index d8ebf5ff0..e21358939 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -171,9 +171,10 @@ 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 = "d5840b32b52a201ca90ac9d538c1d3a1641bfa2d" +git-tree-sha1 = "224c078c40f7cbd98f393d1722953f3a7f24a3ca" +pinned = true uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.9.0" +version = "5.8.5" [deps.CUDA.extensions] ChainRulesCoreExt = "ChainRulesCore" @@ -257,11 +258,13 @@ deps = ["FixedPointNumbers", "Random"] git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.12.1" -weakdeps = ["StyledStrings"] [deps.ColorTypes.extensions] StyledStringsExt = "StyledStrings" + [deps.ColorTypes.weakdeps] + StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" + [[deps.ColorVectorSpace]] deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" @@ -415,9 +418,9 @@ version = "1.15.1" [[deps.DiskArrays]] deps = ["ConstructionBase", "LRUCache", "Mmap", "OffsetArrays"] -git-tree-sha1 = "297ac5efb7c9c7849114eba76111af2814cac8ec" +git-tree-sha1 = "cb1635fa91dfccffdaa09f99d457b581575e2a67" uuid = "3c3547ce-8d99-4f5e-a174-61eb10b00ae3" -version = "0.4.16" +version = "0.4.17" [[deps.Distances]] deps = ["LinearAlgebra", "Statistics", "StatsAPI"] @@ -830,17 +833,19 @@ version = "1.2.0" [[deps.LoopVectorization]] deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "e5afce7eaf5b5ca0d444bcb4dc4fd78c54cbbac0" +git-tree-sha1 = "a9fc7883eb9b5f04f46efb9a540833d1fad974b3" uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.172" +version = "0.12.173" [deps.LoopVectorization.extensions] ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + ForwardDiffNNlibExt = ["ForwardDiff", "NNlib"] SpecialFunctionsExt = "SpecialFunctions" [deps.LoopVectorization.weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" [[deps.Lz4_jll]] @@ -1035,9 +1040,9 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "9dcc2cc5962882ca2160a64ee4f6c716c2338d55" +git-tree-sha1 = "a215a3c5d8b342b41c4968f39d780360d8ec9191" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.100.1" +version = "0.100.0" [deps.Oceananigans.extensions] OceananigansAMDGPUExt = "AMDGPU" @@ -1121,11 +1126,13 @@ version = "0.5.12" deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" version = "1.11.0" -weakdeps = ["REPL"] [deps.Pkg.extensions] REPLExt = "REPL" + [deps.Pkg.weakdeps] + REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + [[deps.PkgVersion]] deps = ["Pkg"] git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" @@ -1157,10 +1164,10 @@ uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.5.0" [[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "5e9fe23c86d3ca630baa1efcad78575a27f158b2" +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "3.0.11" +version = "2.4.0" [[deps.Printf]] deps = ["Unicode"] @@ -1173,11 +1180,6 @@ git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" version = "0.7.6" -[[deps.REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" -version = "1.11.0" - [[deps.Random]] deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" @@ -1426,10 +1428,6 @@ weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "Sp StructArraysSparseArraysExt = "SparseArrays" StructArraysStaticArraysExt = "StaticArrays" -[[deps.StyledStrings]] -uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" -version = "1.11.0" - [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" From 207fcc47005410492b67c54b473c378c18892852 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Thu, 9 Oct 2025 10:36:02 -0700 Subject: [PATCH 225/258] a "working version" on google cloud --- .../omip_prototype/minimal_script_MWE.jl | 73 +++++++++++++------ 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index 9d5a9f9fa..d2d81bf30 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -17,15 +17,18 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address +CUDA.versioninfo() + ngpus = Int(length(CUDA.devices())) @info "$ngpus GPUs" # arch = GPU() arch = Distributed(GPU(), partition=Partition(1, ngpus), synchronized_communication=true) +# arch = Distributed(GPU(), partition=Partition(1, ngpus)) # arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) @info "Architecture $(arch)" -Nx = 1440 # longitudinal direction -Ny = 720 # meridional direction +Nx = 2880 # longitudinal direction +Ny = 1440 # meridional direction Nz = 100 z_faces = ExponentialDiscretization(Nz, -6000, 0) @@ -42,13 +45,17 @@ grid = TripolarGrid(arch; bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=10) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) +# grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=false) momentum_advection = WENOVectorInvariant() tracer_advection = WENO(order=7) -free_surface = SplitExplicitFreeSurface(grid; substeps = 70) +free_surface = SplitExplicitFreeSurface(grid; substeps = 200) + +using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() +# obl_closure = RiBasedVerticalDiffusivity() closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4)) dir = joinpath(homedir(), "forcing_data_1deg_minimal_multi40_backend3") @@ -107,37 +114,57 @@ 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) - # Tmax = maximum(ocean.model.tracers.T) - # Tmin = minimum(ocean.model.tracers.T) - Smax = maximum(ocean.model.tracers.S) - Smin = minimum(ocean.model.tracers.S) - umax = maximum(ocean.model.velocities.u) - vmax = maximum(ocean.model.velocities.v) - wmax = maximum(ocean.model.velocities.w) + # hmax = maximum(interior(sea_ice.model.ice_thickness)) + # ℵmax = maximum(interior(sea_ice.model.ice_concentration)) + # Tmax = maximum(interior(sim.model.interfaces.atmosphere_sea_ice_interface.temperature)) + # Tmin = minimum(interior(sim.model.interfaces.atmosphere_sea_ice_interface.temperature)) + # # Tmax = maximum(ocean.model.tracers.T) + # # Tmin = minimum(ocean.model.tracers.T) + # Smax = maximum(interior(ocean.model.tracers.S)) + # Smin = minimum(interior(ocean.model.tracers.S)) + # umax = maximum(interior(ocean.model.velocities.u)) + # vmax = maximum(interior(ocean.model.velocities.v)) + # wmax = maximum(interior(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("extrema(S): (%.2f, %.2f) psu, ", Smax, Smin) - msg6 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) + msg0 = @sprintf("local rank: %d, ", arch.local_rank) + # 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("extrema(S): (%.2f, %.2f) psu, ", Smax, Smin) + # msg6 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) msg7 = @sprintf("wall time: %s \n", prettytime(step_time)) - @info msg1 * msg2 * msg4 * msg5 * msg6 * msg7 + @info msg1 + # @info msg0 * msg1 * msg2 * msg4 * msg5 * msg6 * msg7 + # @info msg1 * msg2 * msg4 * msg5 * msg6 * msg7 # @info msg1 * msg4 * msg5 * msg6 * msg7 - wall_time[] = time_ns() + CUDA.memory_status() + wall_time[] = time_ns() + return nothing +end - return nothing +function gpus_gc(sim) + @info "Starting GPU garbage collection for iteration $(iteration(sim))..." + @info "before GC:" + CUDA.memory_status() + wall_time[] = time_ns() + + GC.gc() + CUDA.reclaim() + @info "after GC:" + CUDA.memory_status() + step_time = 1e-9 * (time_ns() - wall_time[]) + @info "GPU garbage collection took $(prettytime(step_time))" + wall_time[] = time_ns() + return nothing end # And add it as a callback to the simulation. -add_callback!(omip, progress, IterationInterval(1)) +add_callback!(omip, progress, IterationInterval(10)) +# add_callback!(omip, gpus_gc, IterationInterval(10)) @info "Starting OMIP simulation..." run!(omip) \ No newline at end of file From 0da47b27d48188b1325c39363f1c351febcf631a Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Thu, 9 Oct 2025 10:57:06 -0700 Subject: [PATCH 226/258] oneeighth! --- .../oneeighth_degree_simulation.jl | 326 +++++++++--------- 1 file changed, 156 insertions(+), 170 deletions(-) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl index a1dade25e..616552e0d 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -4,6 +4,7 @@ using Oceananigans using Oceananigans.Grids using Oceananigans.Units using Oceananigans.OrthogonalSphericalShellGrids +using Oceananigans.Architectures: on_architecture using ClimaOcean.OceanSimulations using ClimaOcean.JRA55 using ClimaOcean.DataWrangling @@ -17,15 +18,23 @@ using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency import Oceananigans.OutputWriters: checkpointer_address +CUDA.versioninfo() + +ngpus = Int(length(CUDA.devices())) +@info "$ngpus GPUs" # arch = GPU() -arch = Distributed(GPU(), partition=Partition(1, 2), synchronized_communication=true) +arch = Distributed(GPU(), partition=Partition(1, ngpus), synchronized_communication=true) +# arch = Distributed(GPU(), partition=Partition(1, ngpus)) +# arch = Distributed(CPU(), partition=Partition(1, 4), synchronized_communication=true) +@info "Architecture $(arch)" Nx = 2880 # longitudinal direction Ny = 1440 # meridional direction Nz = 100 -z_faces = ExponentialCoordinate(Nz, -6000, 0) -# z_faces = MutableVerticalDiscretization(z_faces) +Δt = 10minutes + +z_faces = ExponentialDiscretization(Nz, -6000, 0) const z_surf = z_faces(Nz) @@ -37,22 +46,22 @@ grid = TripolarGrid(arch; @info "Regridding bathymetry..." bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=10) +fitted_bottom = GridFittedBottom(bottom_height) @info "Building immersed boundary grid..." -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) +grid = ImmersedBoundaryGrid(grid, fitted_bottom; active_cells_map=true) +# grid = ImmersedBoundaryGrid(grid, fitted_bottom) +@info grid +@info "Created ImmersedBoundaryGrid" ##### ##### A Propgnostic Ocean model ##### - -using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization -using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation -using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity - momentum_advection = WENOVectorInvariant() tracer_advection = WENO(order=7) -free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=12minutes) +free_surface = SplitExplicitFreeSurface(grid; substeps = 200) +@info "Free surface", free_surface obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() # CATKE # obl_closure = RiBasedVerticalDiffusivity() @@ -64,35 +73,29 @@ else prefix = "CATKE" end -prefix *= "oneeighth_degree" - -glorys_dir = joinpath(homedir(), "GLORYS_data") -mkpath(glorys_dir) +prefix *= "oneeighth_degree_$(Δt)" -glorys_dataset = GLORYSMonthly() - -# Turn off salinity restoring for now -# @inline mask(x, y, z, t) = z ≥ z_surf - 1 -# Smetadata = Metadata(:salinity; dataset=glorys_dataset, dir=glorys_dir) -# FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 3) +dir = joinpath(homedir(), "oneeighth_degree_forcing_data") +mkpath(dir) @info "Building ocean component..." -ocean = ocean_simulation(grid; Δt=1minutes, +ocean = ocean_simulation(grid; Δt=5minutes, momentum_advection, tracer_advection, timestepper = :SplitRungeKutta3, free_surface, - # forcing = (; S = FS), closure) start_date = DateTime(1993, 1, 1) end_date = DateTime(2003, 4, 1) simulation_period = Dates.value(Second(end_date - start_date)) +monthly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Month(1):end_date))))) + +dataset = EN4Monthly() -inpainting = NearestNeighborInpainting(50) @info "Setting initial conditions..." -set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_date, dir=glorys_dir), - S=Metadatum(:salinity; dataset=glorys_dataset, date=start_date, dir=glorys_dir); inpainting) +set!(ocean.model, T=Metadatum(:temperature; dataset, date=start_date, dir), + S=Metadatum(:salinity; dataset, date=start_date, dir)) @info ocean.model.clock @@ -106,8 +109,8 @@ set!(ocean.model, T=Metadatum(:temperature; dataset=glorys_dataset, date=start_d sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) @info "Setting sea-ice initial conditions..." -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, dir=glorys_dir), - ℵ=Metadatum(:sea_ice_concentration; dataset=glorys_dataset, dir=glorys_dir), inpainting = nothing) +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir, date=start_date), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir, date=start_date)) ##### ##### A Prescribed Atmosphere model @@ -116,11 +119,10 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=glorys_dataset, jra55_dir = joinpath(homedir(), "JRA55_data") mkpath(jra55_dir) dataset = MultiYearJRA55() -# jra55_dataset = RepeatYearJRA55() -jra55_backend = JRA55NetCDFBackend(10) +backend = JRA55NetCDFBackend(20) @info "Building atmospheric forcing..." -atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset=jra55_backend, backend=jra55_backend, include_rivers_and_icebergs=true, start_date) +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) radiation = Radiation() ##### @@ -129,8 +131,7 @@ radiation = Radiation() @info "Building coupled ocean-sea ice model..." omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) -# omip = Simulation(omip, Δt=10minutes, stop_time=60days) -omip = Simulation(omip, Δt=10minutes, stop_time=simulation_period) +omip = Simulation(omip, Δt=5minutes, stop_time=60days) # Figure out the outputs.... checkpointer_address(::SeaIceModel) = "SeaIceModel" @@ -140,20 +141,15 @@ mkpath(FILE_DIR) @info "Setting up output writers..." ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, - schedule = SpecifiedTimes([simulation_period]), + schedule = SpecifiedTimes(monthly_times), prefix = "$(FILE_DIR)/ocean_checkpoint_oneeighthdegree", overwrite_existing = true) sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, - schedule = TimeInterval(60days), + schedule = SpecifiedTimes(monthly_times), prefix = "$(FILE_DIR)/sea_ice_checkpoint_oneeighthdegree", overwrite_existing = true) -sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, - schedule = SpecifiedTimes([simulation_period]), - prefix = "$(FILE_DIR)/sea_ice_checkpoint_oneeighthdegree_final", - overwrite_existing = true) - u, v, w = ocean.model.velocities T, S = ocean.model.tracers b = Field(buoyancy(ocean.model)) @@ -178,12 +174,12 @@ sea_ice.output_writers[:surface] = JLD2Writer(ocean.model, sea_ice_outputs; overwrite_existing = true) ocean.output_writers[:full] = JLD2Writer(ocean.model, ocean_outputs; - schedule = SpecifiedTimes([simulation_period]), + schedule = SpecifiedTimes(monthly_times), filename = "$(FILE_DIR)/ocean_complete_fields", overwrite_existing = true) sea_ice.output_writers[:full] = JLD2Writer(sea_ice.model, sea_ice_outputs; - schedule = SpecifiedTimes([simulation_period]), + schedule = SpecifiedTimes(monthly_times), filename = "$(FILE_DIR)/sea_ice_complete_fields", overwrite_existing = true) @@ -212,146 +208,136 @@ 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)) + msg1 = @sprintf("local rank: %d, ", arch.local_rank) + msg2 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt)) + msg3 = @sprintf("wall time: %s \n", prettytime(step_time)) - @info msg1 * msg2 * msg4 * msg5 * msg6 + @info msg1 * msg2 * msg3 - wall_time[] = time_ns() - - return nothing + CUDA.memory_status() + wall_time[] = time_ns() + return nothing end # And add it as a callback to the simulation. -add_callback!(omip, progress, IterationInterval(100)) +add_callback!(omip, progress, IterationInterval(400)) @info "Starting simulation..." run!(omip) -# omip.Δt = 10minutes -# omip.stop_time = simulation_period - -run!(omip) - -#%% -@info "Plotting results..." -using CairoMakie - -uo = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "u"; backend = OnDisk()) -vo = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "v"; backend = OnDisk()) -To = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "T"; backend = OnDisk()) - -# and sea ice fields with "i": -ui = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "u"; backend = OnDisk()) -vi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "v"; backend = OnDisk()) -hi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "h"; backend = OnDisk()) -ℵi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "ℵ"; backend = OnDisk()) -Ti = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "T"; backend = OnDisk()) - -times = uo.times -Nt = length(times) -n = Observable(Nt) - -# We create a land mask and use it to fill land points with `NaN`s. -land = interior(To.grid.immersed_boundary.bottom_height) .≥ 0 - -Toₙ = @lift begin - Tₙ = interior(To[$n]) - Tₙ[land] .= NaN - view(Tₙ, :, :, 1) -end - -heₙ = @lift begin - hₙ = interior(hi[$n]) - ℵₙ = interior(ℵi[$n]) - hₙ[land] .= NaN - view(hₙ, :, :, 1) .* view(ℵₙ, :, :, 1) -end - -# We compute the surface speeds for the ocean and the sea ice. -uoₙ = Field{Face, Center, Nothing}(uo.grid) -voₙ = Field{Center, Face, Nothing}(vo.grid) - -uiₙ = Field{Face, Center, Nothing}(ui.grid) -viₙ = Field{Center, Face, Nothing}(vi.grid) - -so = Field(sqrt(uoₙ^2 + voₙ^2)) -si = Field(sqrt(uiₙ^2 + viₙ^2)) - -soₙ = @lift begin - parent(uoₙ) .= parent(uo[$n]) - parent(voₙ) .= parent(vo[$n]) - compute!(so) - soₙ = interior(so) - soₙ[land] .= NaN - view(soₙ, :, :, 1) -end - -siₙ = @lift begin - parent(uiₙ) .= parent(ui[$n]) - parent(viₙ) .= parent(vi[$n]) - compute!(si) - siₙ = interior(si) - hₙ = interior(hi[$n]) - ℵₙ = interior(ℵi[$n]) - he = hₙ .* ℵₙ - siₙ[he .< 1e-7] .= 0 - siₙ[land] .= NaN - view(siₙ, :, :, 1) -end - -# Finally, we plot a snapshot of the surface speed, temperature, and the turbulent -# eddy kinetic energy from the CATKE vertical mixing parameterization as well as the -# sea ice speed and the effective sea ice thickness. -fig = Figure(size=(2000, 1000)) +@info "Initialization complete. Running the rest..." -title = @lift string("Global 1/8ᵒ ocean simulation after ", prettytime(times[$n] - times[1])) +omip.Δt = Δt +omip.stop_time = simulation_period -axso = Axis(fig[1, 1]) -axsi = Axis(fig[1, 3]) -axTo = Axis(fig[2, 1]) -axhi = Axis(fig[2, 3]) - -hmo = heatmap!(axso, soₙ, colorrange = (0, 0.5), colormap = :deep, nan_color=:lightgray) -hmi = heatmap!(axsi, siₙ, colorrange = (0, 0.5), colormap = :greys, nan_color=:lightgray) -Colorbar(fig[1, 2], hmo, label = "Ocean Surface speed (m s⁻¹)") -Colorbar(fig[1, 4], hmi, label = "Sea ice speed (m s⁻¹)") - -hmo = heatmap!(axTo, Toₙ, colorrange = (-1, 32), colormap = :magma, nan_color=:lightgray) -hmi = heatmap!(axhi, heₙ, colorrange = (0, 4), colormap = :blues, nan_color=:lightgray) -Colorbar(fig[2, 2], hmo, label = "Surface Temperature (ᵒC)") -Colorbar(fig[2, 4], hmi, label = "Effective ice thickness (m)") - -for ax in (axso, axsi, axTo, axhi) - hidedecorations!(ax) -end - -Label(fig[0, :], title) - -save("$(FILE_DIR)/global_snapshot.png", fig) -nothing #hide - -# ![](global_snapshot.png) - -# And now a movie: +run!(omip) -CairoMakie.record(fig, "$(FILE_DIR)/oneeighth_degree_global_ocean_surface.mp4", 1:Nt, framerate = 8) do nn - n[] = nn -end -nothing -#%% \ No newline at end of file +# #%% +# @info "Plotting results..." +# using CairoMakie + +# uo = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "u"; backend = OnDisk()) +# vo = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "v"; backend = OnDisk()) +# To = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "T"; backend = OnDisk()) + +# # and sea ice fields with "i": +# ui = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "u"; backend = OnDisk()) +# vi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "v"; backend = OnDisk()) +# hi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "h"; backend = OnDisk()) +# ℵi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "ℵ"; backend = OnDisk()) +# Ti = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "T"; backend = OnDisk()) + +# times = uo.times +# Nt = length(times) +# n = Observable(Nt) + +# # We create a land mask and use it to fill land points with `NaN`s. +# land = interior(To.grid.immersed_boundary.bottom_height) .≥ 0 + +# Toₙ = @lift begin +# Tₙ = interior(To[$n]) +# Tₙ[land] .= NaN +# view(Tₙ, :, :, 1) +# end + +# heₙ = @lift begin +# hₙ = interior(hi[$n]) +# ℵₙ = interior(ℵi[$n]) +# hₙ[land] .= NaN +# view(hₙ, :, :, 1) .* view(ℵₙ, :, :, 1) +# end + +# # We compute the surface speeds for the ocean and the sea ice. +# uoₙ = Field{Face, Center, Nothing}(uo.grid) +# voₙ = Field{Center, Face, Nothing}(vo.grid) + +# uiₙ = Field{Face, Center, Nothing}(ui.grid) +# viₙ = Field{Center, Face, Nothing}(vi.grid) + +# so = Field(sqrt(uoₙ^2 + voₙ^2)) +# si = Field(sqrt(uiₙ^2 + viₙ^2)) + +# soₙ = @lift begin +# parent(uoₙ) .= parent(uo[$n]) +# parent(voₙ) .= parent(vo[$n]) +# compute!(so) +# soₙ = interior(so) +# soₙ[land] .= NaN +# view(soₙ, :, :, 1) +# end + +# siₙ = @lift begin +# parent(uiₙ) .= parent(ui[$n]) +# parent(viₙ) .= parent(vi[$n]) +# compute!(si) +# siₙ = interior(si) +# hₙ = interior(hi[$n]) +# ℵₙ = interior(ℵi[$n]) +# he = hₙ .* ℵₙ +# siₙ[he .< 1e-7] .= 0 +# siₙ[land] .= NaN +# view(siₙ, :, :, 1) +# end + +# # Finally, we plot a snapshot of the surface speed, temperature, and the turbulent +# # eddy kinetic energy from the CATKE vertical mixing parameterization as well as the +# # sea ice speed and the effective sea ice thickness. +# fig = Figure(size=(2000, 1000)) + +# title = @lift string("Global 1/8ᵒ ocean simulation after ", prettytime(times[$n] - times[1])) + +# axso = Axis(fig[1, 1]) +# axsi = Axis(fig[1, 3]) +# axTo = Axis(fig[2, 1]) +# axhi = Axis(fig[2, 3]) + +# hmo = heatmap!(axso, soₙ, colorrange = (0, 0.5), colormap = :deep, nan_color=:lightgray) +# hmi = heatmap!(axsi, siₙ, colorrange = (0, 0.5), colormap = :greys, nan_color=:lightgray) +# Colorbar(fig[1, 2], hmo, label = "Ocean Surface speed (m s⁻¹)") +# Colorbar(fig[1, 4], hmi, label = "Sea ice speed (m s⁻¹)") + +# hmo = heatmap!(axTo, Toₙ, colorrange = (-1, 32), colormap = :magma, nan_color=:lightgray) +# hmi = heatmap!(axhi, heₙ, colorrange = (0, 4), colormap = :blues, nan_color=:lightgray) +# Colorbar(fig[2, 2], hmo, label = "Surface Temperature (ᵒC)") +# Colorbar(fig[2, 4], hmi, label = "Effective ice thickness (m)") + +# for ax in (axso, axsi, axTo, axhi) +# hidedecorations!(ax) +# end + +# Label(fig[0, :], title) + +# save("$(FILE_DIR)/global_snapshot.png", fig) +# nothing #hide + +# # ![](global_snapshot.png) + +# # And now a movie: + +# CairoMakie.record(fig, "$(FILE_DIR)/oneeighth_degree_global_ocean_surface.mp4", 1:Nt, framerate = 8) do nn +# n[] = nn +# end +# nothing +# #%% \ No newline at end of file From e78341389f1f671a5c0e8db88db7ca21ebd7adc9 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Thu, 9 Oct 2025 11:42:26 -0700 Subject: [PATCH 227/258] Add memory usage logging to progress function --- experiments/omip_prototype/oneeighth_degree_simulation.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/experiments/omip_prototype/oneeighth_degree_simulation.jl b/experiments/omip_prototype/oneeighth_degree_simulation.jl index 616552e0d..8db222c29 100644 --- a/experiments/omip_prototype/oneeighth_degree_simulation.jl +++ b/experiments/omip_prototype/oneeighth_degree_simulation.jl @@ -217,6 +217,11 @@ function progress(sim) @info msg1 * msg2 * msg3 CUDA.memory_status() + + total_mem = Sys.total_memory() + free_mem = Sys.free_memory() + used_mem = total_mem - free_mem + @info msg1 * "Memory usage: $(round(100 * used_mem / total_mem, digits=1))%, $(round(used_mem / 1e9, digits=1)) / $(round(total_mem / 1e9, digits=1)) GB" wall_time[] = time_ns() return nothing end From 695c05249f1d9b0424766e75387996c643d0d23f Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Thu, 9 Oct 2025 23:30:49 -0700 Subject: [PATCH 228/258] Refactor ocean simulation parameters and enhance progress logging --- .../omip_prototype/minimal_script_MWE.jl | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index d2d81bf30..a1b5d2e84 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -58,7 +58,7 @@ obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() # obl_closure = RiBasedVerticalDiffusivity() closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4)) -dir = joinpath(homedir(), "forcing_data_1deg_minimal_multi40_backend3") +dir = joinpath(homedir(), "forcing_data_minimal") mkpath(dir) dataset = EN4Monthly() @@ -68,7 +68,7 @@ end_date = start_date + Month(3) @inline mask(x, y, z, t) = z ≥ z_surf - 1 Smetadata = Metadata(:salinity; dataset, dir) -ocean = ocean_simulation(grid; Δt=1minutes, +ocean = ocean_simulation(grid; Δt=5minutes, momentum_advection, tracer_advection, timestepper = :SplitRungeKutta3, @@ -105,7 +105,7 @@ omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) @info omip @info "Setting up OMIP simulation..." -omip = Simulation(omip, Δt=1minutes, stop_time=60days) +omip = Simulation(omip, Δt=5minutes, stop_time=60days) wall_time = Ref(time_ns()) @@ -114,29 +114,30 @@ using Statistics function progress(sim) sea_ice = sim.model.sea_ice ocean = sim.model.ocean - # hmax = maximum(interior(sea_ice.model.ice_thickness)) - # ℵmax = maximum(interior(sea_ice.model.ice_concentration)) - # Tmax = maximum(interior(sim.model.interfaces.atmosphere_sea_ice_interface.temperature)) - # Tmin = minimum(interior(sim.model.interfaces.atmosphere_sea_ice_interface.temperature)) - # # Tmax = maximum(ocean.model.tracers.T) - # # Tmin = minimum(ocean.model.tracers.T) - # Smax = maximum(interior(ocean.model.tracers.S)) - # Smin = minimum(interior(ocean.model.tracers.S)) - # umax = maximum(interior(ocean.model.velocities.u)) - # vmax = maximum(interior(ocean.model.velocities.v)) - # wmax = maximum(interior(ocean.model.velocities.w)) + hmax = maximum(interior(sea_ice.model.ice_thickness)) + ℵmax = maximum(interior(sea_ice.model.ice_concentration)) + Tmax = maximum(interior(sim.model.interfaces.atmosphere_sea_ice_interface.temperature)) + Tmin = minimum(interior(sim.model.interfaces.atmosphere_sea_ice_interface.temperature)) + # Tmax = maximum(ocean.model.tracers.T) + # Tmin = minimum(ocean.model.tracers.T) + Smax = maximum(interior(ocean.model.tracers.S)) + Smin = minimum(interior(ocean.model.tracers.S)) + umax = maximum(interior(ocean.model.velocities.u)) + vmax = maximum(interior(ocean.model.velocities.v)) + wmax = maximum(interior(ocean.model.velocities.w)) step_time = 1e-9 * (time_ns() - wall_time[]) - msg0 = @sprintf("local rank: %d, ", arch.local_rank) - # 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("extrema(S): (%.2f, %.2f) psu, ", Smax, Smin) - # msg6 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) + # msg0 = @sprintf("local rank: %d, ", arch.local_rank) + 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("extrema(S): (%.2f, %.2f) psu, ", Smax, Smin) + msg6 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) msg7 = @sprintf("wall time: %s \n", prettytime(step_time)) - @info msg1 + # @info msg0 * msg1 + @info msg1 * msg2 * msg4 * msg5 * msg6 * msg7 # @info msg0 * msg1 * msg2 * msg4 * msg5 * msg6 * msg7 # @info msg1 * msg2 * msg4 * msg5 * msg6 * msg7 # @info msg1 * msg4 * msg5 * msg6 * msg7 From b234fe1564896fd20688ff485ac018168ff66826 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 10 Oct 2025 12:09:43 -0700 Subject: [PATCH 229/258] Create directory for JRA55 data and initialize dataset --- experiments/omip_prototype/minimal_script_MWE.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/experiments/omip_prototype/minimal_script_MWE.jl b/experiments/omip_prototype/minimal_script_MWE.jl index a1b5d2e84..c6c7f2bf9 100644 --- a/experiments/omip_prototype/minimal_script_MWE.jl +++ b/experiments/omip_prototype/minimal_script_MWE.jl @@ -88,6 +88,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir, date=start_date)) jra55_dir = joinpath(homedir(), "JRA55_data") +mkpath(jra55_dir) dataset = MultiYearJRA55() backend = JRA55NetCDFBackend(10) From eb0105df9e2171d147ceda80e6338785d7351a63 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 10 Oct 2025 18:52:52 -0700 Subject: [PATCH 230/258] Update Julia version and project dependencies in Manifest.toml --- Manifest.toml | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index e21358939..3dc7b3e6a 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.11.6" +julia_version = "1.11.4" manifest_format = "2.0" -project_hash = "17aae685aef2ba02d64e4577c6218c1cf723a81c" +project_hash = "6d49749dd3429f77a448642c87c467e52d884f9c" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -236,10 +236,10 @@ uuid = "55437552-ac27-4d47-9aa3-63184e8fd398" version = "1.0.0" [[deps.ClimaSeaIce]] -deps = ["Adapt", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] -git-tree-sha1 = "7ea1d7d2539199c82d65779991104652f9c1964e" +deps = ["Adapt", "JLD2", "KernelAbstractions", "Oceananigans", "RootSolvers", "Roots", "SeawaterPolynomials"] +git-tree-sha1 = "bc7928604980aaec717a1cf9029bac8026a9276c" uuid = "6ba0ff68-24e6-4315-936c-2e99227c95a4" -version = "0.3.8" +version = "0.3.9" [[deps.CloseOpenIntervals]] deps = ["Static", "StaticArrayInterface"] @@ -360,10 +360,10 @@ uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" version = "4.1.1" [[deps.CubedSphere]] -deps = ["TaylorSeries"] -git-tree-sha1 = "afe9e8c11bf816a6fee878ddfc661e0bd138b747" +deps = ["Distances", "LinearAlgebra", "Printf", "Random", "Statistics", "TaylorSeries"] +git-tree-sha1 = "aa3c0d323eb110def3f1e634a24739ef9e989f4a" uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.3.2" +version = "0.3.3" [[deps.CubicSplines]] deps = ["Random", "Test"] @@ -715,9 +715,9 @@ version = "0.3.6" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] -git-tree-sha1 = "0f8b6110c766baff87e54f83986afaf7e2a44d96" +git-tree-sha1 = "ce8614210409eaa54ed5968f4b50aa96da7ae543" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "9.4.3" +version = "9.4.4" weakdeps = ["BFloat16s"] [deps.LLVM.extensions] @@ -725,9 +725,9 @@ weakdeps = ["BFloat16s"] [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "2ea068aac1e7f0337d381b0eae3110581e3f3216" +git-tree-sha1 = "8e76807afb59ebb833e9b131ebf1a8c006510f33" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.37+2" +version = "0.0.38+0" [[deps.LLVMLoopInfo]] git-tree-sha1 = "2e5c102cfc41f48ae4740c7eca7743cc7e7b75ea" @@ -1040,9 +1040,11 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "a215a3c5d8b342b41c4968f39d780360d8ec9191" +git-tree-sha1 = "e9ece90127caad63528602115f88fffb61baa8a6" +repo-rev = "xk/new-gm-updated" +repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.100.0" +version = "0.100.3" [deps.Oceananigans.extensions] OceananigansAMDGPUExt = "AMDGPU" @@ -1085,7 +1087,7 @@ version = "0.3.27+1" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.5+0" +version = "0.8.1+4" [[deps.OpenMPI_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "MPIPreferences", "TOML", "Zlib_jll"] @@ -1482,9 +1484,9 @@ version = "1.11.0" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "ForwardDiff", "KernelAbstractions", "Random", "RootSolvers"] -git-tree-sha1 = "e3a9fe706f095c6a176a76ea4613c57900898999" +git-tree-sha1 = "bae39665e42c36e2e6bf5b814631915ec7d90232" uuid = "b60c26fb-14c3-4610-9d3e-2d17fe7ff00c" -version = "0.14.2" +version = "0.15.0" [deps.Thermodynamics.extensions] CreateParametersExt = "ClimaParams" From 47929f4d3cddc380caaa49fd464f66e9bdcd24f1 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 10 Oct 2025 21:51:14 -0700 Subject: [PATCH 231/258] first trial of half degree simulation! --- .../omip_prototype/half_degree_simulation.jl | 433 ++++++++++++++++++ 1 file changed, 433 insertions(+) create mode 100644 experiments/omip_prototype/half_degree_simulation.jl diff --git a/experiments/omip_prototype/half_degree_simulation.jl b/experiments/omip_prototype/half_degree_simulation.jl new file mode 100644 index 000000000..8b0b39390 --- /dev/null +++ b/experiments/omip_prototype/half_degree_simulation.jl @@ -0,0 +1,433 @@ +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 +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency +using ArgParse + +import Oceananigans.OutputWriters: checkpointer_address + +function parse_commandline() + s = ArgParseSettings() + + @add_arg_table! s begin + "--kappa_skew" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + "--kappa_symmetric" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + end + return parse_args(s) +end + +args = parse_commandline() +κ_skew = args["kappa_skew"] +κ_symmetric = args["kappa_symmetric"] + +arch = GPU() + +Nx = 720 # longitudinal direction +Ny = 360 # meridional direction +Nz = 100 + +z_faces = ExponentialDiscretization(Nz, -6000, 0) + +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=40) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +##### +##### A Prognostic Ocean model +##### + +using Oceananigans.TurbulenceClosures: RiBasedVerticalDiffusivity + +momentum_advection = WENOVectorInvariant() +tracer_advection = WENO(order=7) + +free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=65minutes) + +gm_closure = Oceananigans.TurbulenceClosures.EddyAdvectiveClosure(; κ_skew) +redi_closure = Oceananigans.TurbulenceClosures.IsopycnalDiffusivity(; κ_symmetric) + +# obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() +obl_closure = RiBasedVerticalDiffusivity() +closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4), gm_closure, redi_closure) + +prefix = "halfdegree" +if obl_closure isa RiBasedVerticalDiffusivity + prefix *= "_RiBased" +else + prefix *= "_CATKE" +end + +prefix *= "_$(κ_skew)_$(κ_symmetric)" +prefix *= "_newgm_multiyearjra55" + +dir = joinpath(homedir(), "forcing_data_half_degree") +mkpath(dir) + +start_date = DateTime(1958, 1, 1) +end_date = start_date + Year(40) +simulation_period = Dates.value(Second(end_date - start_date)) +yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) +decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) + +@inline mask(x, y, z, t) = z ≥ z_surf - 1 +Smetadata = Metadata(:salinity; dataset=EN4Monthly(), dir, start_date, end_date) +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) + +set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_date, dir), + S=Metadatum(:salinity; dataset=EN4Monthly(), date=start_date, dir)) + +##### +##### 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)) +sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) + +##### +##### A Prescribed Atmosphere model +##### +jra55_dir = joinpath(homedir(), "JRA55_data") +dataset = MultiYearJRA55() +backend = JRA55NetCDFBackend(20) + +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) +radiation = Radiation() + +##### +##### An ocean-sea ice coupled model +##### + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) +omip = Simulation(omip, Δt=20minutes, stop_time=60days) + +# Figure out the outputs.... +checkpointer_address(::SeaIceModel) = "SeaIceModel" + +FILE_DIR = "./Data/$(prefix)/" +mkpath(FILE_DIR) + +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/ocean_checkpoint", + overwrite_existing = true) + +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/sea_ice_checkpoint", + overwrite_existing = true) + +u, v, w = ocean.model.velocities +T, S = ocean.model.tracers +b = Field(buoyancy(ocean.model)) +N² = Field(buoyancy_frequency(ocean.model)) + +ocean_outputs = merge(ocean.model.tracers, ocean.model.velocities, (; b, N²)) +sea_ice_outputs = merge((h = sea_ice.model.ice_thickness, + ℵ = sea_ice.model.ice_concentration, + T = sea_ice.model.ice_thermodynamics.top_surface_temperature), + sea_ice.model.velocities) + +ocean.output_writers[:surface] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/ocean_surface_fields", + indices = (:, :, grid.Nz), + overwrite_existing = true) + +sea_ice.output_writers[:surface] = JLD2Writer(ocean.model, sea_ice_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/sea_ice_surface_fields", + overwrite_existing = true) + +ocean.output_writers[:full] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(1825days), + filename = "$(FILE_DIR)/ocean_complete_fields", + overwrite_existing = true) + +ocean.output_writers[:time_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(1825days, window=1825days), + filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", + overwrite_existing = true) + +sea_ice.output_writers[:time_average] = JLD2Writer(sea_ice.model, sea_ice_outputs; + schedule = AveragedTimeInterval(1825days, window=1825days), + filename = "$(FILE_DIR)/sea_ice_complete_fields_10year_average", + 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(100)) + +run!(omip) + +omip.Δt = 60minutes +omip.stop_time = simulation_period + +run!(omip) + +#%% +@info "Plotting results..." +using CairoMakie + +uo = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "u"; backend = OnDisk()) +vo = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "v"; backend = OnDisk()) +To = FieldTimeSeries("$(FILE_DIR)/ocean_surface_fields.jld2", "T"; backend = OnDisk()) + +# and sea ice fields with "i": +ui = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "u"; backend = OnDisk()) +vi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "v"; backend = OnDisk()) +hi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "h"; backend = OnDisk()) +ℵi = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "ℵ"; backend = OnDisk()) +Ti = FieldTimeSeries("$(FILE_DIR)/sea_ice_surface_fields.jld2", "T"; backend = OnDisk()) + +times = uo.times +Nt = length(times) +n = Observable(Nt) + +# We create a land mask and use it to fill land points with `NaN`s. +land = interior(To.grid.immersed_boundary.bottom_height) .≥ 0 + +Toₙ = @lift begin + Tₙ = interior(To[$n]) + Tₙ[land] .= NaN + view(Tₙ, :, :, 1) +end + +heₙ = @lift begin + hₙ = interior(hi[$n]) + ℵₙ = interior(ℵi[$n]) + hₙ[land] .= NaN + view(hₙ, :, :, 1) .* view(ℵₙ, :, :, 1) +end + +# We compute the surface speeds for the ocean and the sea ice. +uoₙ = Field{Face, Center, Nothing}(uo.grid) +voₙ = Field{Center, Face, Nothing}(vo.grid) + +uiₙ = Field{Face, Center, Nothing}(ui.grid) +viₙ = Field{Center, Face, Nothing}(vi.grid) + +so = Field(sqrt(uoₙ^2 + voₙ^2)) +si = Field(sqrt(uiₙ^2 + viₙ^2)) + +soₙ = @lift begin + parent(uoₙ) .= parent(uo[$n]) + parent(voₙ) .= parent(vo[$n]) + compute!(so) + soₙ = interior(so) + soₙ[land] .= NaN + view(soₙ, :, :, 1) +end + +siₙ = @lift begin + parent(uiₙ) .= parent(ui[$n]) + parent(viₙ) .= parent(vi[$n]) + compute!(si) + siₙ = interior(si) + hₙ = interior(hi[$n]) + ℵₙ = interior(ℵi[$n]) + he = hₙ .* ℵₙ + siₙ[he .< 1e-7] .= 0 + siₙ[land] .= NaN + view(siₙ, :, :, 1) +end + +# Finally, we plot a snapshot of the surface speed, temperature, and the turbulent +# eddy kinetic energy from the CATKE vertical mixing parameterization as well as the +# sea ice speed and the effective sea ice thickness. +fig = Figure(size=(1500, 1000)) + +title = @lift string("Global 1ᵒ ocean simulation after ", prettytime(times[$n] - times[1])) + +axso = Axis(fig[1, 1]) +axsi = Axis(fig[1, 3]) +axTo = Axis(fig[2, 1]) +axhi = Axis(fig[2, 3]) + +hmo = heatmap!(axso, soₙ, colorrange = (0, 0.5), colormap = :deep, nan_color=:lightgray) +hmi = heatmap!(axsi, siₙ, colorrange = (0, 0.5), colormap = :greys, nan_color=:lightgray) +Colorbar(fig[1, 2], hmo, label = "Ocean Surface speed (m s⁻¹)") +Colorbar(fig[1, 4], hmi, label = "Sea ice speed (m s⁻¹)") + +hmo = heatmap!(axTo, Toₙ, colorrange = (-1, 32), colormap = :magma, nan_color=:lightgray) +hmi = heatmap!(axhi, heₙ, colorrange = (0, 4), colormap = :blues, nan_color=:lightgray) +Colorbar(fig[2, 2], hmo, label = "Surface Temperature (ᵒC)") +Colorbar(fig[2, 4], hmi, label = "Effective ice thickness (m)") + +for ax in (axso, axsi, axTo, axhi) + hidedecorations!(ax) +end + +Label(fig[0, :], title) + +save("$(FILE_DIR)/global_snapshot.png", fig) +nothing #hide + +# ![](global_snapshot.png) + +# And now a movie: + +CairoMakie.record(fig, "$(FILE_DIR)/global_ocean_surface.mp4", 1:Nt, framerate = 8) do nn + n[] = nn +end +nothing + +#%% +uoac = FieldTimeSeries("$(FILE_DIR)/ocean_complete_fields_10year_average.jld2", "u"; backend = OnDisk()) +voac = FieldTimeSeries("$(FILE_DIR)/ocean_complete_fields_10year_average.jld2", "v"; backend = OnDisk()) +woac = FieldTimeSeries("$(FILE_DIR)/ocean_complete_fields_10year_average.jld2", "w"; backend = OnDisk()) +Toac = FieldTimeSeries("$(FILE_DIR)/ocean_complete_fields_10year_average.jld2", "T"; backend = OnDisk()) +Soac = FieldTimeSeries("$(FILE_DIR)/ocean_complete_fields_10year_average.jld2", "S"; backend = OnDisk()) + +times = uoac.times +Nt = length(times) +n = Observable(Nt) + +# We create a land mask and use it to fill land points with `NaN`s. +land = interior(Toac.grid.immersed_boundary.bottom_height) .≥ 0 + +Toacₙ = @lift begin + Tₙ = interior(Toac[$n]) + Tₙ[land[:, :, 1], :] .= NaN + view(Tₙ, :, :, :) +end + +Soacₙ = @lift begin + Sₙ = interior(Soac[$n]) + Sₙ[land[:, :, 1], :] .= NaN + view(Sₙ, :, :, :) +end + +surface = Toac.grid.underlying_grid.Nz +middle = findlast(x -> x <= -500, Toac.grid.underlying_grid.z.cᵃᵃᶜ) +bottom = findlast(x -> x <= -2000, Toac.grid.underlying_grid.z.cᵃᵃᶜ) + +T_surfaceₙ = @lift $Toacₙ[:, :, surface] +T_middleₙ = @lift $Toacₙ[:, :, middle] +T_bottomₙ = @lift $Toacₙ[:, :, bottom] + +S_surfaceₙ = @lift $Soacₙ[:, :, surface] +S_middleₙ = @lift $Soacₙ[:, :, middle] +S_bottomₙ = @lift $Soacₙ[:, :, bottom] + +Tlim_surface = extrema(interior(Toac[Nt], :, :, surface)) +Tlim_middle = extrema(interior(Toac[Nt], :, :, middle)) +Tlim_bottom = extrema(interior(Toac[Nt], :, :, bottom)) + +Slim_surface = extrema(interior(Soac[Nt], :, :, surface)[interior(Soac[Nt], :, :, surface) .!= 0]) +Slim_middle = extrema(interior(Soac[Nt], :, :, middle)[interior(Soac[Nt], :, :, middle) .!= 0]) +Slim_bottom = extrema(interior(Soac[Nt], :, :, bottom)[interior(Soac[Nt], :, :, bottom) .!= 0]) + +# Finally, we plot a snapshot of the surface speed, temperature, and the turbulent +# eddy kinetic energy from the CATKE vertical mixing parameterization as well as the +# sea ice speed and the effective sea ice thickness. +fig = Figure(size=(2400, 1000)) + +title = @lift string("10 year average starting from year ", round((times[$n] - times[1]) / 365 / 24 / 60^2)) + +axTs = Axis(fig[1, 1], title = "z = $(round(Toac.grid.underlying_grid.z.cᵃᵃᶜ[surface])) m") +axTm = Axis(fig[1, 3], title = "z = $(round(Toac.grid.underlying_grid.z.cᵃᵃᶜ[middle])) m") +axTb = Axis(fig[1, 5], title = "z = $(round(Toac.grid.underlying_grid.z.cᵃᵃᶜ[bottom])) m") + +axSs = Axis(fig[2, 1]) +axSm = Axis(fig[2, 3]) +axSb = Axis(fig[2, 5]) + +T_colorscheme = :turbo +S_colorscheme = :turbo + +hmTs = heatmap!(axTs, T_surfaceₙ, colormap = T_colorscheme, nan_color=:lightgray, colorrange = Tlim_surface) +hmTm = heatmap!(axTm, T_middleₙ, colormap = T_colorscheme, nan_color=:lightgray, colorrange = Tlim_middle) +hmTb = heatmap!(axTb, T_bottomₙ, colormap = T_colorscheme, nan_color=:lightgray, colorrange = Tlim_bottom) +Colorbar(fig[1, 2], hmTs) +Colorbar(fig[1, 4], hmTm) +Colorbar(fig[1, 6], hmTb, label = "Temperature (ᵒC)") + +hmSs = heatmap!(axSs, S_surfaceₙ, colormap = S_colorscheme, nan_color=:lightgray, colorrange = Slim_surface) +hmSm = heatmap!(axSm, S_middleₙ, colormap = S_colorscheme, nan_color=:lightgray, colorrange = Slim_middle) +hmSb = heatmap!(axSb, S_bottomₙ, colormap = S_colorscheme, nan_color=:lightgray, colorrange = Slim_bottom) +Colorbar(fig[2, 2], hmSs) +Colorbar(fig[2, 4], hmSm) +Colorbar(fig[2, 6], hmSb, label = "Salinity (psu)") + +for ax in (axTs, axTm, axTb, axSs, axSm, axSb) + hidedecorations!(ax) +end + +Label(fig[0, :], title) + +save("$(FILE_DIR)/10year_time_average_level_snapshot.png", fig) +nothing #hide + +# ![](global_snapshot.png) + +# And now a movie: + +CairoMakie.record(fig, "$(FILE_DIR)/10year_time_average_level.mp4", 1:Nt, framerate = 1) do nn + n[] = nn +end +nothing +#%% \ No newline at end of file From 5e613958dd20eb5c9bc0185452fffa23aa4f79ff Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 10 Oct 2025 23:18:28 -0700 Subject: [PATCH 232/258] Enhance logging for ocean and sea ice model setup and initialization --- .../omip_prototype/half_degree_simulation.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/experiments/omip_prototype/half_degree_simulation.jl b/experiments/omip_prototype/half_degree_simulation.jl index 8b0b39390..f0780f7c6 100644 --- a/experiments/omip_prototype/half_degree_simulation.jl +++ b/experiments/omip_prototype/half_degree_simulation.jl @@ -55,6 +55,8 @@ grid = TripolarGrid(arch; bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=40) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) +@info "Built grid $(grid)" + ##### ##### A Prognostic Ocean model ##### @@ -92,6 +94,7 @@ simulation_period = Dates.value(Second(end_date - start_date)) yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) +@info "Settting up salinity restoring..." @inline mask(x, y, z, t) = z ≥ z_surf - 1 Smetadata = Metadata(:salinity; dataset=EN4Monthly(), dir, start_date, end_date) FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 10) @@ -104,8 +107,11 @@ ocean = ocean_simulation(grid; Δt=1minutes, forcing = (; S = FS), closure) +@info "Built ocean model $(ocean)" + set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_date, dir), S=Metadatum(:salinity; dataset=EN4Monthly(), date=start_date, dir)) +@info "Initialized T and S" ##### ##### A Prognostic Sea-ice model @@ -114,10 +120,13 @@ set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_dat # Default sea-ice dynamics and salinity coupling are included in the defaults # sea_ice = sea_ice_simulation(grid, ocean; advection=WENO(order=7)) sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) +@info "Built sea ice model $(sea_ice)" set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) +@info "Initialized sea ice fields" + ##### ##### A Prescribed Atmosphere model ##### @@ -125,15 +134,22 @@ jra55_dir = joinpath(homedir(), "JRA55_data") dataset = MultiYearJRA55() backend = JRA55NetCDFBackend(20) +@info "Setting up presctibed atmosphere $(dataset)" atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) radiation = Radiation() +@info "Built atmosphere model $(atmosphere)" + ##### ##### An ocean-sea ice coupled model ##### omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +@info "Built coupled model $(omip)" + omip = Simulation(omip, Δt=20minutes, stop_time=60days) +@info "Built simulation $(omip)" # Figure out the outputs.... checkpointer_address(::SeaIceModel) = "SeaIceModel" From 915512c1d8039ee007ba48ca07a9ae8c4b3ef474 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 11 Oct 2025 10:28:52 -0700 Subject: [PATCH 233/258] Adjust dataset memory settings for salinity restoring and JRA55 backend --- experiments/omip_prototype/half_degree_simulation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/omip_prototype/half_degree_simulation.jl b/experiments/omip_prototype/half_degree_simulation.jl index f0780f7c6..862cb9a97 100644 --- a/experiments/omip_prototype/half_degree_simulation.jl +++ b/experiments/omip_prototype/half_degree_simulation.jl @@ -97,7 +97,7 @@ decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10): @info "Settting up salinity restoring..." @inline mask(x, y, z, t) = z ≥ z_surf - 1 Smetadata = Metadata(:salinity; dataset=EN4Monthly(), dir, start_date, end_date) -FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 10) +FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 3) ocean = ocean_simulation(grid; Δt=1minutes, momentum_advection, @@ -132,7 +132,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), ##### jra55_dir = joinpath(homedir(), "JRA55_data") dataset = MultiYearJRA55() -backend = JRA55NetCDFBackend(20) +backend = JRA55NetCDFBackend(6) @info "Setting up presctibed atmosphere $(dataset)" atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) From eff629b01b5be0db3b668d79e31afa9f52827cee Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 11 Oct 2025 11:33:00 -0700 Subject: [PATCH 234/258] Add logging for simulation script startup --- experiments/omip_prototype/half_degree_simulation.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/experiments/omip_prototype/half_degree_simulation.jl b/experiments/omip_prototype/half_degree_simulation.jl index 862cb9a97..d65753e12 100644 --- a/experiments/omip_prototype/half_degree_simulation.jl +++ b/experiments/omip_prototype/half_degree_simulation.jl @@ -17,6 +17,8 @@ using ArgParse import Oceananigans.OutputWriters: checkpointer_address +@info "Starting half degree simulation script..." + function parse_commandline() s = ArgParseSettings() From b29c25af3ed31ed515c56c64b0c1b05f87bb6239 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 11 Oct 2025 12:50:26 -0700 Subject: [PATCH 235/258] Remove startup logging and ensure JRA55 data directory is created --- experiments/omip_prototype/half_degree_simulation.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/experiments/omip_prototype/half_degree_simulation.jl b/experiments/omip_prototype/half_degree_simulation.jl index d65753e12..45ac70037 100644 --- a/experiments/omip_prototype/half_degree_simulation.jl +++ b/experiments/omip_prototype/half_degree_simulation.jl @@ -17,8 +17,6 @@ using ArgParse import Oceananigans.OutputWriters: checkpointer_address -@info "Starting half degree simulation script..." - function parse_commandline() s = ArgParseSettings() @@ -133,6 +131,7 @@ set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), ##### A Prescribed Atmosphere model ##### jra55_dir = joinpath(homedir(), "JRA55_data") +mkpath(jra55_dir) dataset = MultiYearJRA55() backend = JRA55NetCDFBackend(6) From 94fa5a31a80b9a09b22e5b7b546092697f853d2e Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 11:27:34 -0700 Subject: [PATCH 236/258] Simone's version --- half_degree_omip.jl | 256 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 half_degree_omip.jl diff --git a/half_degree_omip.jl b/half_degree_omip.jl new file mode 100644 index 000000000..0c7de6739 --- /dev/null +++ b/half_degree_omip.jl @@ -0,0 +1,256 @@ +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 +using JLD2 + +import Oceananigans.OutputWriters: checkpointer_address + +using ArgParse + +function parse_commandline() + s = ArgParseSettings() + + @add_arg_table! s begin + "--kappa_skew" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + "--kappa_symmetric" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + end + return parse_args(s) +end + +args = parse_commandline() +κ_skew = args["kappa_skew"] +κ_symmetric = args["kappa_symmetric"] + +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) +# restart_iteration = "446000" +restart_iteration = nothing + +arch = GPU() + +Nx = 720 # longitudinal direction +Ny = 360 # meridional direction +Nz = 100 + +z_faces = ExponentialDiscretization(Nz, -6000, 0; scale=1800) + +const z_surf = z_faces.cᵃᵃᶠ(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=55) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +##### +##### A Propgnostic Ocean model +##### + +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization, AdvectiveFormulation, IsopycnalSkewSymmetricDiffusivity +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation + +momentum_advection = WENOVectorInvariant(order=5) +tracer_advection = WENO(order=7) +free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=50minutes) + +using Oceananigans.Operators: Δx, Δy + +@inline Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz) = 2 * (1 / (1 / Δx(i, j, k, grid, lx, ly, lz)^2 + 1 / Δy(i, j, k, grid, lx, ly, lz)^2)) +@inline geometric_νhb(i, j, k, grid, lx, ly, lz, clock, fields, λ) = Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz)^2 / λ + +eddy_closure = IsopycnalSkewSymmetricDiffusivity(κ_skew, κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) +# obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() +obl_closure = RiBasedVerticalDiffusivity() +visc_closure = HorizontalScalarBiharmonicDiffusivity(ν=geometric_νhb, discrete_form=true, parameters=25days) + +closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=3e-4), visc_closure, eddy_closure) + +prefix = "halfdegree" +if obl_closure isa RiBasedVerticalDiffusivity + prefix *= "_RiBased" +else + prefix *= "_CATKE" +end + +prefix *= "_$(κ_skew)_$(κ_symmetric)" +prefix *= "_advectiveGM_multiyearjra55" + +dir = joinpath(homedir(), "forcing_data_half_degree") +mkpath(dir) + +start_date = DateTime(1958, 1, 1) +end_date = start_date + Year(20) +simulation_period = Dates.value(Second(end_date - start_date)) +yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) +decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) + +@info "Settting up salinity restoring..." +@inline mask(x, y, z, t) = z ≥ z_surf - 1 +Smetadata = Metadata(:salinity; dataset=EN4Monthly(), dir, start_date, end_date) +FS = DatasetRestoring(Smetadata, grid; rate = 1/30days, mask, time_indices_in_memory = 10) + +ocean = ocean_simulation(grid; Δt=1minutes, + momentum_advection, + tracer_advection, + timestepper = :SplitRungeKutta3, + free_surface, + forcing = (; S = FS), + closure) + +@info "Built ocean model $(ocean)" + +set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_date, dir), + S=Metadatum(:salinity; dataset=EN4Monthly(), date=start_date, dir)) +@info "Initialized T and S" + +##### +##### 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)) +sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) +@info "Built sea ice model $(sea_ice)" + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) + +@info "Initialized sea ice fields" + +##### +##### A Prescribed Atmosphere model +##### +jra55_dir = joinpath(homedir(), "JRA55_data") +mkpath(jra55_dir) +dataset = MultiYearJRA55() +backend = JRA55NetCDFBackend(100) + +@info "Setting up presctibed atmosphere $(dataset)" +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) +radiation = Radiation() + +@info "Built atmosphere model $(atmosphere)" + +##### +##### An ocean-sea ice coupled model +##### + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +@info "Built coupled model $(omip)" + +omip = Simulation(omip, Δt=30minutes, stop_time=simulation_period) +@info "Built simulation $(omip)" + +# Figure out the outputs.... +checkpointer_address(::SeaIceModel) = "SeaIceModel" + +FILE_DIR = "./Data/$(prefix)/" +mkpath(FILE_DIR) + +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/ocean_checkpoint", + overwrite_existing = true) + +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/sea_ice_checkpoint", + overwrite_existing = true) + +u, v, w = ocean.model.velocities +T, S = ocean.model.tracers +b = Field(buoyancy(ocean.model)) +N² = Field(buoyancy_frequency(ocean.model)) + +ocean_outputs = merge(ocean.model.tracers, ocean.model.velocities, (; b, N²)) +sea_ice_outputs = merge((h = sea_ice.model.ice_thickness, + ℵ = sea_ice.model.ice_concentration, + T = sea_ice.model.ice_thermodynamics.top_surface_temperature), + sea_ice.model.velocities) + +ocean.output_writers[:surface] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/ocean_surface_fields", + indices = (:, :, grid.Nz), + overwrite_existing = true) + +sea_ice.output_writers[:surface] = JLD2Writer(ocean.model, sea_ice_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/sea_ice_surface_fields", + overwrite_existing = true) + +ocean.output_writers[:full] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(1825days), + filename = "$(FILE_DIR)/ocean_complete_fields", + overwrite_existing = true) + +ocean.output_writers[:time_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(1825days, window=1825days), + filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", + overwrite_existing = true) + +sea_ice.output_writers[:time_average] = JLD2Writer(sea_ice.model, sea_ice_outputs; + schedule = AveragedTimeInterval(1825days, window=1825days), + filename = "$(FILE_DIR)/sea_ice_complete_fields_10year_average", + 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(100)) + +run!(omip) \ No newline at end of file From f9f9e6405facb8bc98fbbce0fe6066d3faf54a99 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 11:35:18 -0700 Subject: [PATCH 237/258] Fix z_surf assignment to use correct function call for ExponentialDiscretization --- half_degree_omip.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/half_degree_omip.jl b/half_degree_omip.jl index 0c7de6739..e0a637222 100644 --- a/half_degree_omip.jl +++ b/half_degree_omip.jl @@ -56,8 +56,7 @@ Ny = 360 # meridional direction Nz = 100 z_faces = ExponentialDiscretization(Nz, -6000, 0; scale=1800) - -const z_surf = z_faces.cᵃᵃᶠ(Nz) +const z_surf = z_faces(Nz) grid = TripolarGrid(arch; size = (Nx, Ny, Nz), From 4944de45fd423eee82eb98fac7aaf3165f4b35da Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 11:50:28 -0700 Subject: [PATCH 238/258] Fix eddy_closure instantiation by adding missing semicolon for keyword arguments --- half_degree_omip.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/half_degree_omip.jl b/half_degree_omip.jl index e0a637222..a02c31e00 100644 --- a/half_degree_omip.jl +++ b/half_degree_omip.jl @@ -82,7 +82,7 @@ using Oceananigans.Operators: Δx, Δy @inline Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz) = 2 * (1 / (1 / Δx(i, j, k, grid, lx, ly, lz)^2 + 1 / Δy(i, j, k, grid, lx, ly, lz)^2)) @inline geometric_νhb(i, j, k, grid, lx, ly, lz, clock, fields, λ) = Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz)^2 / λ -eddy_closure = IsopycnalSkewSymmetricDiffusivity(κ_skew, κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) +eddy_closure = IsopycnalSkewSymmetricDiffusivity(; κ_skew, κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) # obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() obl_closure = RiBasedVerticalDiffusivity() visc_closure = HorizontalScalarBiharmonicDiffusivity(ν=geometric_νhb, discrete_form=true, parameters=25days) From b3a21b5092faceb7035e147e950d7c839b4db40a Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 12:15:43 -0700 Subject: [PATCH 239/258] add buoyancy push --- half_degree_omip.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/half_degree_omip.jl b/half_degree_omip.jl index a02c31e00..5798f806d 100644 --- a/half_degree_omip.jl +++ b/half_degree_omip.jl @@ -4,6 +4,7 @@ using Oceananigans using Oceananigans.Grids using Oceananigans.Units using Oceananigans.OrthogonalSphericalShellGrids +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency= using ClimaOcean.OceanSimulations using ClimaOcean.ECCO using ClimaOcean.JRA55 @@ -13,11 +14,10 @@ using Printf using Dates using CUDA using JLD2 +using ArgParse import Oceananigans.OutputWriters: checkpointer_address -using ArgParse - function parse_commandline() s = ArgParseSettings() From 3e525b562236fec46f96e1a6fa3baa6b89a8cde6 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 12:26:47 -0700 Subject: [PATCH 240/258] Fix import statement for buoyancy formulations by removing unnecessary assignment --- half_degree_omip.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/half_degree_omip.jl b/half_degree_omip.jl index 5798f806d..0fdb554f0 100644 --- a/half_degree_omip.jl +++ b/half_degree_omip.jl @@ -4,7 +4,7 @@ using Oceananigans using Oceananigans.Grids using Oceananigans.Units using Oceananigans.OrthogonalSphericalShellGrids -using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency= +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency using ClimaOcean.OceanSimulations using ClimaOcean.ECCO using ClimaOcean.JRA55 From 1bf8a998f174b8265d387f557f5980cc9f8d6657 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 15:30:15 -0700 Subject: [PATCH 241/258] =?UTF-8?q?Add=20logging=20for=20=CE=BA=5Fskew=20a?= =?UTF-8?q?nd=20=CE=BA=5Fsymmetric=20values=20in=20command=20line=20argume?= =?UTF-8?q?nts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- half_degree_omip.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/half_degree_omip.jl b/half_degree_omip.jl index 0fdb554f0..4d0d01897 100644 --- a/half_degree_omip.jl +++ b/half_degree_omip.jl @@ -38,6 +38,8 @@ args = parse_commandline() κ_skew = args["kappa_skew"] κ_symmetric = args["kappa_symmetric"] +@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s" + function synch!(clock1::Clock, clock2) # Synchronize the clocks clock1.time = clock2.time From 01c98acf6df55c19fb6d973792c5d08b5604b878 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 16:10:31 -0700 Subject: [PATCH 242/258] script for running calibration samples --- half_degree_omip_calibrationsamples.jl | 263 +++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 half_degree_omip_calibrationsamples.jl diff --git a/half_degree_omip_calibrationsamples.jl b/half_degree_omip_calibrationsamples.jl new file mode 100644 index 000000000..7c757792b --- /dev/null +++ b/half_degree_omip_calibrationsamples.jl @@ -0,0 +1,263 @@ +using ClimaOcean +using ClimaSeaIce +using Oceananigans +using Oceananigans.Grids +using Oceananigans.Units +using Oceananigans.OrthogonalSphericalShellGrids +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency +using ClimaOcean.OceanSimulations +using ClimaOcean.ECCO +using ClimaOcean.JRA55 +using ClimaOcean.DataWrangling +using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using Printf +using Dates +using CUDA +using JLD2 +using ArgParse + +import Oceananigans.OutputWriters: checkpointer_address + +function parse_commandline() + s = ArgParseSettings() + + @add_arg_table! s begin + "--kappa_skew" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + "--kappa_symmetric" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + end + return parse_args(s) +end + +args = parse_commandline() +κ_skew = args["kappa_skew"] +κ_symmetric = args["kappa_symmetric"] + +@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s" + +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) +# restart_iteration = "446000" +restart_iteration = nothing + +arch = GPU() + +Nx = 720 # longitudinal direction +Ny = 360 # meridional direction +Nz = 100 + +z_faces = ExponentialDiscretization(Nz, -6000, 0; scale=1800) +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=55) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +##### +##### A Propgnostic Ocean model +##### + +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization, AdvectiveFormulation, IsopycnalSkewSymmetricDiffusivity +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation + +momentum_advection = WENOVectorInvariant(order=5) +tracer_advection = WENO(order=7) +free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=50minutes) + +using Oceananigans.Operators: Δx, Δy + +@inline Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz) = 2 * (1 / (1 / Δx(i, j, k, grid, lx, ly, lz)^2 + 1 / Δy(i, j, k, grid, lx, ly, lz)^2)) +@inline geometric_νhb(i, j, k, grid, lx, ly, lz, clock, fields, λ) = Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz)^2 / λ + +eddy_closure = IsopycnalSkewSymmetricDiffusivity(; κ_skew, κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) +# obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() +obl_closure = RiBasedVerticalDiffusivity() +visc_closure = HorizontalScalarBiharmonicDiffusivity(ν=geometric_νhb, discrete_form=true, parameters=25days) + +closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=3e-4), visc_closure, eddy_closure) + +prefix = "halfdegree" +if obl_closure isa RiBasedVerticalDiffusivity + prefix *= "_RiBased" +else + prefix *= "_CATKE" +end + +prefix *= "_$(κ_skew)_$(κ_symmetric)" +prefix *= "_advectiveGM_multiyearjra55_calibrationsamples" + +dir = joinpath(homedir(), "forcing_data_half_degree") +mkpath(dir) + +start_date = DateTime(1962, 1, 1) +end_date = start_date + Year(50) +simulation_period = Dates.value(Second(end_date - start_date)) +yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) +decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) +sampling_endtimes = decadal_times[3:end] + +@info "Settting up salinity restoring..." +@inline mask(x, y, z, t) = z ≥ z_surf - 1 +Smetadata = Metadata(:salinity; dataset=EN4Monthly(), dir, start_date, end_date) +FS = DatasetRestoring(Smetadata, grid; rate = 1/30days, mask, time_indices_in_memory = 10) + +ocean = ocean_simulation(grid; Δt=1minutes, + momentum_advection, + tracer_advection, + timestepper = :SplitRungeKutta3, + free_surface, + forcing = (; S = FS), + closure) + +@info "Built ocean model $(ocean)" + +set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_date, dir), + S=Metadatum(:salinity; dataset=EN4Monthly(), date=start_date, dir)) +@info "Initialized T and S" + +##### +##### 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)) +sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) +@info "Built sea ice model $(sea_ice)" + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) + +@info "Initialized sea ice fields" + +##### +##### A Prescribed Atmosphere model +##### +jra55_dir = joinpath(homedir(), "JRA55_data") +mkpath(jra55_dir) +dataset = MultiYearJRA55() +backend = JRA55NetCDFBackend(100) + +@info "Setting up presctibed atmosphere $(dataset)" +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) +radiation = Radiation() + +@info "Built atmosphere model $(atmosphere)" + +##### +##### An ocean-sea ice coupled model +##### + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +@info "Built coupled model $(omip)" + +omip = Simulation(omip, Δt=30minutes, stop_time=simulation_period) +@info "Built simulation $(omip)" + +# Figure out the outputs.... +checkpointer_address(::SeaIceModel) = "SeaIceModel" + +FILE_DIR = "./Data/$(prefix)/" +mkpath(FILE_DIR) + +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/ocean_checkpoint", + overwrite_existing = true) + +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/sea_ice_checkpoint", + overwrite_existing = true) + +u, v, w = ocean.model.velocities +T, S = ocean.model.tracers +b = Field(buoyancy(ocean.model)) +N² = Field(buoyancy_frequency(ocean.model)) + +ocean_outputs = merge(ocean.model.tracers, ocean.model.velocities, (; b, N²)) +sea_ice_outputs = merge((h = sea_ice.model.ice_thickness, + ℵ = sea_ice.model.ice_concentration, + T = sea_ice.model.ice_thermodynamics.top_surface_temperature), + sea_ice.model.velocities) + +ocean.output_writers[:surface] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/ocean_surface_fields", + indices = (:, :, grid.Nz), + overwrite_existing = true) + +sea_ice.output_writers[:surface] = JLD2Writer(ocean.model, sea_ice_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/sea_ice_surface_fields", + overwrite_existing = true) + +ocean.output_writers[:full] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(1825days), + filename = "$(FILE_DIR)/ocean_complete_fields", + overwrite_existing = true) + +ocean.output_writers[:time_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(3650days, window=3650days), + filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", + overwrite_existing = true) + +sea_ice.output_writers[:time_average] = JLD2Writer(sea_ice.model, sea_ice_outputs; + schedule = AveragedTimeInterval(3650days, window=3650days), + filename = "$(FILE_DIR)/sea_ice_complete_fields_10year_average", + overwrite_existing = true) + +ocean.output_writers[:sample_decadal_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedSpecifiedTimes(sampling_endtimes, window=3650days), + filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", + 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(100)) + +run!(omip) \ No newline at end of file From 25faf57cb6d7d200cc8ce24c2db54821ead85bf7 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 23:16:17 +0000 Subject: [PATCH 243/258] update Manifest --- Manifest.toml | 79 ++++++++++++++++----------------------------------- 1 file changed, 25 insertions(+), 54 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 3dc7b3e6a..7eefb708a 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.11.4" +julia_version = "1.10.10" manifest_format = "2.0" -project_hash = "6d49749dd3429f77a448642c87c467e52d884f9c" +project_hash = "f748fefc08ca7842dd24e70d6e4946003efbc336" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -55,7 +55,7 @@ weakdeps = ["SparseArrays", "StaticArrays"] [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.2" +version = "1.1.1" [[deps.ArnoldiMethod]] deps = ["LinearAlgebra", "Random", "StaticArrays"] @@ -99,7 +99,6 @@ version = "7.20.0" [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" -version = "1.11.0" [[deps.Atomix]] deps = ["UnsafeAtomics"] @@ -127,7 +126,6 @@ version = "0.5.1" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" -version = "1.11.0" [[deps.BitFlags]] git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" @@ -360,10 +358,10 @@ uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" version = "4.1.1" [[deps.CubedSphere]] -deps = ["Distances", "LinearAlgebra", "Printf", "Random", "Statistics", "TaylorSeries"] -git-tree-sha1 = "aa3c0d323eb110def3f1e634a24739ef9e989f4a" +deps = ["TaylorSeries"] +git-tree-sha1 = "afe9e8c11bf816a6fee878ddfc661e0bd138b747" uuid = "7445602f-e544-4518-8976-18f8e8ae6cdb" -version = "0.3.3" +version = "0.3.2" [[deps.CubicSplines]] deps = ["Random", "Test"] @@ -402,7 +400,6 @@ version = "1.0.0" [[deps.Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" -version = "1.11.0" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -439,7 +436,6 @@ version = "0.10.12" [[deps.Distributed]] deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" -version = "1.11.0" [[deps.DocStringExtensions]] git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" @@ -491,7 +487,6 @@ weakdeps = ["HTTP"] [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" -version = "1.11.0" [[deps.FixedPointNumbers]] deps = ["Statistics"] @@ -512,7 +507,6 @@ weakdeps = ["StaticArrays"] [[deps.Future]] deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" -version = "1.11.0" [[deps.GPUArrays]] deps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "ScopedValues", "Serialization", "Statistics"] @@ -626,7 +620,6 @@ version = "2025.2.0+0" [[deps.InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" -version = "1.11.0" [[deps.InverseFunctions]] git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb" @@ -757,7 +750,6 @@ version = "0.1.17" [[deps.LazyArtifacts]] deps = ["Artifacts", "Pkg"] uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" -version = "1.11.0" [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] @@ -767,17 +759,16 @@ 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.6.0+0" +version = "8.4.0+0" [[deps.LibGit2]] deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" -version = "1.11.0" [[deps.LibGit2_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.7.2+0" +version = "1.6.4+0" [[deps.LibSSH2_jll]] deps = ["Artifacts", "Libdl", "MbedTLS_jll"] @@ -792,7 +783,6 @@ version = "0.9.1+6" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" -version = "1.11.0" [[deps.Libiconv_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -803,7 +793,6 @@ version = "1.18.0+0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -version = "1.11.0" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] @@ -823,7 +812,6 @@ version = "0.3.29" [[deps.Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" -version = "1.11.0" [[deps.LoggingExtras]] deps = ["Dates", "Logging"] @@ -916,7 +904,6 @@ version = "0.4.2" [[deps.Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" -version = "1.11.0" [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] @@ -927,7 +914,7 @@ version = "1.1.9" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+0" +version = "2.28.2+1" [[deps.MeshArrays]] deps = ["CatViews", "Dates", "Distributed", "Glob", "LazyArtifacts", "NearestNeighbors", "Pkg", "Printf", "SharedArrays", "SparseArrays", "Statistics", "Unitful"] @@ -981,7 +968,6 @@ version = "1.2.0" [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" -version = "1.11.0" [[deps.MosaicViews]] deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] @@ -991,7 +977,7 @@ version = "0.3.4" [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2023.12.12" +version = "2023.1.10" [[deps.MuladdMacro]] git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" @@ -1040,8 +1026,8 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "e9ece90127caad63528602115f88fffb61baa8a6" -repo-rev = "xk/new-gm-updated" +git-tree-sha1 = "3d3a937ad3a7a1ec9452e230b3de7f38d84f9a5c" +repo-rev = "xk/cuda-backport-compat" repo-url = "https://github.com/CliMA/Oceananigans.jl.git" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" version = "0.100.3" @@ -1082,12 +1068,12 @@ weakdeps = ["Adapt"] [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.27+1" +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"] @@ -1125,15 +1111,9 @@ uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" version = "0.5.12" [[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +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.11.0" - - [deps.Pkg.extensions] - REPLExt = "REPL" - - [deps.Pkg.weakdeps] - REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.10.0" [[deps.PkgVersion]] deps = ["Pkg"] @@ -1174,7 +1154,6 @@ version = "2.4.0" [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" -version = "1.11.0" [[deps.Quaternions]] deps = ["LinearAlgebra", "Random", "RealDot"] @@ -1182,10 +1161,13 @@ 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" -version = "1.11.0" [[deps.Random123]] deps = ["Random", "RandomNumbers"] @@ -1307,12 +1289,10 @@ version = "1.4.8" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -version = "1.11.0" [[deps.SharedArrays]] deps = ["Distributed", "Mmap", "Random", "Serialization"] uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" -version = "1.11.0" [[deps.SimpleBufferStream]] git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" @@ -1327,7 +1307,6 @@ version = "0.9.5" [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" -version = "1.11.0" [[deps.SortingAlgorithms]] deps = ["DataStructures"] @@ -1338,7 +1317,7 @@ version = "1.2.2" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.11.0" +version = "1.10.0" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] @@ -1395,14 +1374,9 @@ uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" version = "1.4.3" [[deps.Statistics]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +deps = ["LinearAlgebra", "SparseArrays"] uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.11.1" -weakdeps = ["SparseArrays"] - - [deps.Statistics.extensions] - SparseArraysExt = ["SparseArrays"] +version = "1.10.0" [[deps.StatsAPI]] deps = ["LinearAlgebra"] @@ -1433,7 +1407,7 @@ weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "Sp [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.7.0+0" +version = "7.2.1+1" [[deps.TOML]] deps = ["Dates"] @@ -1480,7 +1454,6 @@ version = "0.1.1" [[deps.Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -version = "1.11.0" [[deps.Thermodynamics]] deps = ["DocStringExtensions", "ForwardDiff", "KernelAbstractions", "Random", "RootSolvers"] @@ -1531,7 +1504,6 @@ version = "1.6.1" [[deps.UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" -version = "1.11.0" [[deps.UnPack]] git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" @@ -1540,7 +1512,6 @@ version = "1.0.2" [[deps.Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" -version = "1.11.0" [[deps.Unitful]] deps = ["Dates", "LinearAlgebra", "Random"] @@ -1639,7 +1610,7 @@ version = "1.11.3+0" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.59.0+0" +version = "1.52.0+1" [[deps.oneTBB_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] From 8848dd15d2b386b44500ab1ebe48608c1856824c Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 16:23:41 -0700 Subject: [PATCH 244/258] Add CUDA version info output after command line argument parsing --- half_degree_omip.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/half_degree_omip.jl b/half_degree_omip.jl index 4d0d01897..1cc48f6c2 100644 --- a/half_degree_omip.jl +++ b/half_degree_omip.jl @@ -38,6 +38,8 @@ args = parse_commandline() κ_skew = args["kappa_skew"] κ_symmetric = args["kappa_symmetric"] +CUDA.versioninfo() + @info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s" function synch!(clock1::Clock, clock2) From f368383157635b9475a7b9c71574a272cbd86224 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 17:06:27 -0700 Subject: [PATCH 245/258] 20year run script to get samples faster --- ...egree_omip_calibrationsamples_20yearrun.jl | 269 ++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 half_degree_omip_calibrationsamples_20yearrun.jl diff --git a/half_degree_omip_calibrationsamples_20yearrun.jl b/half_degree_omip_calibrationsamples_20yearrun.jl new file mode 100644 index 000000000..a88bdc225 --- /dev/null +++ b/half_degree_omip_calibrationsamples_20yearrun.jl @@ -0,0 +1,269 @@ +using ClimaOcean +using ClimaSeaIce +using Oceananigans +using Oceananigans.Grids +using Oceananigans.Units +using Oceananigans.OrthogonalSphericalShellGrids +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency +using ClimaOcean.OceanSimulations +using ClimaOcean.ECCO +using ClimaOcean.JRA55 +using ClimaOcean.DataWrangling +using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using Printf +using Dates +using CUDA +using JLD2 +using ArgParse + +import Oceananigans.OutputWriters: checkpointer_address + +function parse_commandline() + s = ArgParseSettings() + + @add_arg_table! s begin + "--kappa_skew" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + "--kappa_symmetric" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + "--start_year" + help = "Start year of the simulation" + arg_type = Int + default = 1962 + end + return parse_args(s) +end + +args = parse_commandline() +κ_skew = args["kappa_skew"] +κ_symmetric = args["kappa_symmetric"] +start_year = args["start_year"] + +@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s" + +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) +# restart_iteration = "446000" +restart_iteration = nothing + +arch = GPU() + +Nx = 720 # longitudinal direction +Ny = 360 # meridional direction +Nz = 100 + +z_faces = ExponentialDiscretization(Nz, -6000, 0; scale=1800) +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=55) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +##### +##### A Propgnostic Ocean model +##### + +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization, AdvectiveFormulation, IsopycnalSkewSymmetricDiffusivity +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation + +momentum_advection = WENOVectorInvariant(order=5) +tracer_advection = WENO(order=7) +free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=50minutes) + +using Oceananigans.Operators: Δx, Δy + +@inline Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz) = 2 * (1 / (1 / Δx(i, j, k, grid, lx, ly, lz)^2 + 1 / Δy(i, j, k, grid, lx, ly, lz)^2)) +@inline geometric_νhb(i, j, k, grid, lx, ly, lz, clock, fields, λ) = Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz)^2 / λ + +eddy_closure = IsopycnalSkewSymmetricDiffusivity(; κ_skew, κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) +# obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() +obl_closure = RiBasedVerticalDiffusivity() +visc_closure = HorizontalScalarBiharmonicDiffusivity(ν=geometric_νhb, discrete_form=true, parameters=25days) + +closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=3e-4), visc_closure, eddy_closure) + +prefix = "halfdegree" +if obl_closure isa RiBasedVerticalDiffusivity + prefix *= "_RiBased" +else + prefix *= "_CATKE" +end + +prefix *= "_$(κ_skew)_$(κ_symmetric)" +prefix *= "_$(start_year)" +prefix *= "_advectiveGM_multiyearjra55_calibrationsamples_20yearrun" + +dir = joinpath(homedir(), "forcing_data_half_degree") +mkpath(dir) + +start_date = DateTime(start_year, 1, 1) +end_date = start_date + Year(20) +simulation_period = Dates.value(Second(end_date - start_date)) +yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) +decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) +sampling_endtimes = decadal_times[3:end] + +@info "Settting up salinity restoring..." +@inline mask(x, y, z, t) = z ≥ z_surf - 1 +Smetadata = Metadata(:salinity; dataset=EN4Monthly(), dir, start_date, end_date) +FS = DatasetRestoring(Smetadata, grid; rate = 1/30days, mask, time_indices_in_memory = 10) + +ocean = ocean_simulation(grid; Δt=1minutes, + momentum_advection, + tracer_advection, + timestepper = :SplitRungeKutta3, + free_surface, + forcing = (; S = FS), + closure) + +@info "Built ocean model $(ocean)" + +set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_date, dir), + S=Metadatum(:salinity; dataset=EN4Monthly(), date=start_date, dir)) +@info "Initialized T and S" + +##### +##### 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)) +sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) +@info "Built sea ice model $(sea_ice)" + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) + +@info "Initialized sea ice fields" + +##### +##### A Prescribed Atmosphere model +##### +jra55_dir = joinpath(homedir(), "JRA55_data") +mkpath(jra55_dir) +dataset = MultiYearJRA55() +backend = JRA55NetCDFBackend(100) + +@info "Setting up presctibed atmosphere $(dataset)" +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) +radiation = Radiation() + +@info "Built atmosphere model $(atmosphere)" + +##### +##### An ocean-sea ice coupled model +##### + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +@info "Built coupled model $(omip)" + +omip = Simulation(omip, Δt=30minutes, stop_time=simulation_period) +@info "Built simulation $(omip)" + +# Figure out the outputs.... +checkpointer_address(::SeaIceModel) = "SeaIceModel" + +FILE_DIR = "./Data/$(prefix)/" +mkpath(FILE_DIR) + +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/ocean_checkpoint", + overwrite_existing = true) + +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/sea_ice_checkpoint", + overwrite_existing = true) + +u, v, w = ocean.model.velocities +T, S = ocean.model.tracers +b = Field(buoyancy(ocean.model)) +N² = Field(buoyancy_frequency(ocean.model)) + +ocean_outputs = merge(ocean.model.tracers, ocean.model.velocities, (; b, N²)) +sea_ice_outputs = merge((h = sea_ice.model.ice_thickness, + ℵ = sea_ice.model.ice_concentration, + T = sea_ice.model.ice_thermodynamics.top_surface_temperature), + sea_ice.model.velocities) + +ocean.output_writers[:surface] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/ocean_surface_fields", + indices = (:, :, grid.Nz), + overwrite_existing = true) + +sea_ice.output_writers[:surface] = JLD2Writer(ocean.model, sea_ice_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/sea_ice_surface_fields", + overwrite_existing = true) + +ocean.output_writers[:full] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(1825days), + filename = "$(FILE_DIR)/ocean_complete_fields", + overwrite_existing = true) + +ocean.output_writers[:time_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(3650days, window=3650days), + filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", + overwrite_existing = true) + +sea_ice.output_writers[:time_average] = JLD2Writer(sea_ice.model, sea_ice_outputs; + schedule = AveragedTimeInterval(3650days, window=3650days), + filename = "$(FILE_DIR)/sea_ice_complete_fields_10year_average", + overwrite_existing = true) + +ocean.output_writers[:sample_decadal_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedSpecifiedTimes(sampling_endtimes, window=3650days), + filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", + 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(100)) + +run!(omip) \ No newline at end of file From a744e8109f034cb6988cd2a55f8eabb95b9b68fa Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 17:13:00 -0700 Subject: [PATCH 246/258] Enhance command line argument parsing for simulation parameters and remove 20-year run script --- half_degree_omip_calibrationsamples.jl | 17 +- ...egree_omip_calibrationsamples_20yearrun.jl | 269 ------------------ 2 files changed, 15 insertions(+), 271 deletions(-) delete mode 100644 half_degree_omip_calibrationsamples_20yearrun.jl diff --git a/half_degree_omip_calibrationsamples.jl b/half_degree_omip_calibrationsamples.jl index 7c757792b..c0a3819e8 100644 --- a/half_degree_omip_calibrationsamples.jl +++ b/half_degree_omip_calibrationsamples.jl @@ -15,6 +15,7 @@ using Dates using CUDA using JLD2 using ArgParse +using Oceananigans.OutputWriters: AveragedSpecifiedTimes import Oceananigans.OutputWriters: checkpointer_address @@ -30,6 +31,14 @@ function parse_commandline() help = "Isopycnal skew diffusivity (m^2/s)" arg_type = Float64 default = 5e2 + "--start_year" + help = "Start year of the simulation" + arg_type = Int + default = 1962 + "--simulation_length" + help = "Length of the simulation in years" + arg_type = Int + default = 20 end return parse_args(s) end @@ -37,6 +46,8 @@ end args = parse_commandline() κ_skew = args["kappa_skew"] κ_symmetric = args["kappa_symmetric"] +start_year = args["start_year"] +simulation_length = args["simulation_length"] @info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s" @@ -99,13 +110,15 @@ else end prefix *= "_$(κ_skew)_$(κ_symmetric)" +prefix *= "_$(start_year)" +prefix *= "_$(simulation_length)year" prefix *= "_advectiveGM_multiyearjra55_calibrationsamples" dir = joinpath(homedir(), "forcing_data_half_degree") mkpath(dir) -start_date = DateTime(1962, 1, 1) -end_date = start_date + Year(50) +start_date = DateTime(start_year, 1, 1) +end_date = start_date + Year(simulation_length) simulation_period = Dates.value(Second(end_date - start_date)) yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) diff --git a/half_degree_omip_calibrationsamples_20yearrun.jl b/half_degree_omip_calibrationsamples_20yearrun.jl deleted file mode 100644 index a88bdc225..000000000 --- a/half_degree_omip_calibrationsamples_20yearrun.jl +++ /dev/null @@ -1,269 +0,0 @@ -using ClimaOcean -using ClimaSeaIce -using Oceananigans -using Oceananigans.Grids -using Oceananigans.Units -using Oceananigans.OrthogonalSphericalShellGrids -using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency -using ClimaOcean.OceanSimulations -using ClimaOcean.ECCO -using ClimaOcean.JRA55 -using ClimaOcean.DataWrangling -using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium -using Printf -using Dates -using CUDA -using JLD2 -using ArgParse - -import Oceananigans.OutputWriters: checkpointer_address - -function parse_commandline() - s = ArgParseSettings() - - @add_arg_table! s begin - "--kappa_skew" - help = "Isopycnal skew diffusivity (m^2/s)" - arg_type = Float64 - default = 5e2 - "--kappa_symmetric" - help = "Isopycnal skew diffusivity (m^2/s)" - arg_type = Float64 - default = 5e2 - "--start_year" - help = "Start year of the simulation" - arg_type = Int - default = 1962 - end - return parse_args(s) -end - -args = parse_commandline() -κ_skew = args["kappa_skew"] -κ_symmetric = args["kappa_symmetric"] -start_year = args["start_year"] - -@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s" - -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) -# restart_iteration = "446000" -restart_iteration = nothing - -arch = GPU() - -Nx = 720 # longitudinal direction -Ny = 360 # meridional direction -Nz = 100 - -z_faces = ExponentialDiscretization(Nz, -6000, 0; scale=1800) -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=55) -grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) - -##### -##### A Propgnostic Ocean model -##### - -using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization, AdvectiveFormulation, IsopycnalSkewSymmetricDiffusivity -using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation - -momentum_advection = WENOVectorInvariant(order=5) -tracer_advection = WENO(order=7) -free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=50minutes) - -using Oceananigans.Operators: Δx, Δy - -@inline Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz) = 2 * (1 / (1 / Δx(i, j, k, grid, lx, ly, lz)^2 + 1 / Δy(i, j, k, grid, lx, ly, lz)^2)) -@inline geometric_νhb(i, j, k, grid, lx, ly, lz, clock, fields, λ) = Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz)^2 / λ - -eddy_closure = IsopycnalSkewSymmetricDiffusivity(; κ_skew, κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) -# obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() -obl_closure = RiBasedVerticalDiffusivity() -visc_closure = HorizontalScalarBiharmonicDiffusivity(ν=geometric_νhb, discrete_form=true, parameters=25days) - -closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=3e-4), visc_closure, eddy_closure) - -prefix = "halfdegree" -if obl_closure isa RiBasedVerticalDiffusivity - prefix *= "_RiBased" -else - prefix *= "_CATKE" -end - -prefix *= "_$(κ_skew)_$(κ_symmetric)" -prefix *= "_$(start_year)" -prefix *= "_advectiveGM_multiyearjra55_calibrationsamples_20yearrun" - -dir = joinpath(homedir(), "forcing_data_half_degree") -mkpath(dir) - -start_date = DateTime(start_year, 1, 1) -end_date = start_date + Year(20) -simulation_period = Dates.value(Second(end_date - start_date)) -yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) -decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) -sampling_endtimes = decadal_times[3:end] - -@info "Settting up salinity restoring..." -@inline mask(x, y, z, t) = z ≥ z_surf - 1 -Smetadata = Metadata(:salinity; dataset=EN4Monthly(), dir, start_date, end_date) -FS = DatasetRestoring(Smetadata, grid; rate = 1/30days, mask, time_indices_in_memory = 10) - -ocean = ocean_simulation(grid; Δt=1minutes, - momentum_advection, - tracer_advection, - timestepper = :SplitRungeKutta3, - free_surface, - forcing = (; S = FS), - closure) - -@info "Built ocean model $(ocean)" - -set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_date, dir), - S=Metadatum(:salinity; dataset=EN4Monthly(), date=start_date, dir)) -@info "Initialized T and S" - -##### -##### 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)) -sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) -@info "Built sea ice model $(sea_ice)" - -set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), - ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) - -@info "Initialized sea ice fields" - -##### -##### A Prescribed Atmosphere model -##### -jra55_dir = joinpath(homedir(), "JRA55_data") -mkpath(jra55_dir) -dataset = MultiYearJRA55() -backend = JRA55NetCDFBackend(100) - -@info "Setting up presctibed atmosphere $(dataset)" -atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) -radiation = Radiation() - -@info "Built atmosphere model $(atmosphere)" - -##### -##### An ocean-sea ice coupled model -##### - -omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) - -@info "Built coupled model $(omip)" - -omip = Simulation(omip, Δt=30minutes, stop_time=simulation_period) -@info "Built simulation $(omip)" - -# Figure out the outputs.... -checkpointer_address(::SeaIceModel) = "SeaIceModel" - -FILE_DIR = "./Data/$(prefix)/" -mkpath(FILE_DIR) - -ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, - schedule = SpecifiedTimes(decadal_times), - prefix = "$(FILE_DIR)/ocean_checkpoint", - overwrite_existing = true) - -sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, - schedule = SpecifiedTimes(decadal_times), - prefix = "$(FILE_DIR)/sea_ice_checkpoint", - overwrite_existing = true) - -u, v, w = ocean.model.velocities -T, S = ocean.model.tracers -b = Field(buoyancy(ocean.model)) -N² = Field(buoyancy_frequency(ocean.model)) - -ocean_outputs = merge(ocean.model.tracers, ocean.model.velocities, (; b, N²)) -sea_ice_outputs = merge((h = sea_ice.model.ice_thickness, - ℵ = sea_ice.model.ice_concentration, - T = sea_ice.model.ice_thermodynamics.top_surface_temperature), - sea_ice.model.velocities) - -ocean.output_writers[:surface] = JLD2Writer(ocean.model, ocean_outputs; - schedule = TimeInterval(180days), - filename = "$(FILE_DIR)/ocean_surface_fields", - indices = (:, :, grid.Nz), - overwrite_existing = true) - -sea_ice.output_writers[:surface] = JLD2Writer(ocean.model, sea_ice_outputs; - schedule = TimeInterval(180days), - filename = "$(FILE_DIR)/sea_ice_surface_fields", - overwrite_existing = true) - -ocean.output_writers[:full] = JLD2Writer(ocean.model, ocean_outputs; - schedule = TimeInterval(1825days), - filename = "$(FILE_DIR)/ocean_complete_fields", - overwrite_existing = true) - -ocean.output_writers[:time_average] = JLD2Writer(ocean.model, ocean_outputs; - schedule = AveragedTimeInterval(3650days, window=3650days), - filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", - overwrite_existing = true) - -sea_ice.output_writers[:time_average] = JLD2Writer(sea_ice.model, sea_ice_outputs; - schedule = AveragedTimeInterval(3650days, window=3650days), - filename = "$(FILE_DIR)/sea_ice_complete_fields_10year_average", - overwrite_existing = true) - -ocean.output_writers[:sample_decadal_average] = JLD2Writer(ocean.model, ocean_outputs; - schedule = AveragedSpecifiedTimes(sampling_endtimes, window=3650days), - filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", - 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(100)) - -run!(omip) \ No newline at end of file From aaac8331a009d57bfbc526e7938f522c5747689d Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 19:40:45 -0700 Subject: [PATCH 247/258] Add UCX library detection and logging for MPI+CUDA compatibility --- half_degree_omip.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/half_degree_omip.jl b/half_degree_omip.jl index 1cc48f6c2..6a8723594 100644 --- a/half_degree_omip.jl +++ b/half_degree_omip.jl @@ -18,6 +18,14 @@ using ArgParse import Oceananigans.OutputWriters: checkpointer_address +using Libdl +ucx_libs = filter(lib -> occursin("ucx", lowercase(lib)), Libdl.dllist()) +if isempty(ucx_libs) + @info "✓ No UCX - safe to run!" +else + @warn "✗ UCX libraries detected! This can cause issues with MPI+CUDA. Detected libs:\n$(join(ucx_libs, "\n"))" +end + function parse_commandline() s = ArgParseSettings() From 463901e92d66a819bac70111aaa43e3bff8cccfc Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 13 Oct 2025 21:34:10 -0700 Subject: [PATCH 248/258] Add UCX library detection and logging for MPI+CUDA compatibility --- half_degree_omip_calibrationsamples.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/half_degree_omip_calibrationsamples.jl b/half_degree_omip_calibrationsamples.jl index c0a3819e8..420b377ba 100644 --- a/half_degree_omip_calibrationsamples.jl +++ b/half_degree_omip_calibrationsamples.jl @@ -19,6 +19,14 @@ using Oceananigans.OutputWriters: AveragedSpecifiedTimes import Oceananigans.OutputWriters: checkpointer_address +using Libdl +ucx_libs = filter(lib -> occursin("ucx", lowercase(lib)), Libdl.dllist()) +if isempty(ucx_libs) + @info "✓ No UCX - safe to run!" +else + @warn "✗ UCX libraries detected! This can cause issues with MPI+CUDA. Detected libs:\n$(join(ucx_libs, "\n"))" +end + function parse_commandline() s = ArgParseSettings() @@ -49,7 +57,7 @@ args = parse_commandline() start_year = args["start_year"] simulation_length = args["simulation_length"] -@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s" +@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s, starting in year $(start_year) for a length of $(simulation_length) years." function synch!(clock1::Clock, clock2) # Synchronize the clocks From 036bf64ce44a4410ab6c492eb24bcf8e1f6f3461 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Wed, 15 Oct 2025 11:25:40 -0700 Subject: [PATCH 249/258] temporary hack to use AveragedTimeInterval to average calibration target --- half_degree_omip_calibrationsamples.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/half_degree_omip_calibrationsamples.jl b/half_degree_omip_calibrationsamples.jl index 420b377ba..6558553e7 100644 --- a/half_degree_omip_calibrationsamples.jl +++ b/half_degree_omip_calibrationsamples.jl @@ -130,7 +130,8 @@ end_date = start_date + Year(simulation_length) simulation_period = Dates.value(Second(end_date - start_date)) yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) -sampling_endtimes = decadal_times[3:end] +# sampling_endtimes = decadal_times[3:end] +sampling_window = Dates.value(Second(end_date - Year(10))) @info "Settting up salinity restoring..." @inline mask(x, y, z, t) = z ≥ z_surf - 1 @@ -244,8 +245,8 @@ sea_ice.output_writers[:time_average] = JLD2Writer(sea_ice.model, sea_ice_output overwrite_existing = true) ocean.output_writers[:sample_decadal_average] = JLD2Writer(ocean.model, ocean_outputs; - schedule = AveragedSpecifiedTimes(sampling_endtimes, window=3650days), - filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", + schedule = AveragedTimeInterval(simulation_period, window=sampling_window), + filename = "$(FILE_DIR)/ocean_complete_fields_10year_average_calibrationsample", overwrite_existing = true) wall_time = Ref(time_ns()) From e06d4945fc48e01285e7b9846a024360a2e5d737 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Wed, 15 Oct 2025 20:54:11 +0000 Subject: [PATCH 250/258] bump Oceananigans --- Manifest.toml | 8 +++----- Project.toml | 1 - 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 7eefb708a..3d7aa22e4 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.10" manifest_format = "2.0" -project_hash = "f748fefc08ca7842dd24e70d6e4946003efbc336" +project_hash = "fc5090dba0d641efaadaa43b2214980eadcc9eb9" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] @@ -1026,11 +1026,9 @@ version = "1.2.0" [[deps.Oceananigans]] deps = ["Adapt", "Crayons", "CubedSphere", "Dates", "Distances", "DocStringExtensions", "FFTW", "GPUArrays", "GPUArraysCore", "Glob", "InteractiveUtils", "JLD2", "KernelAbstractions", "Krylov", "KrylovPreconditioners", "LinearAlgebra", "Logging", "MPI", "MuladdMacro", "OffsetArrays", "OrderedCollections", "Pkg", "Printf", "Random", "ReactantCore", "Rotations", "SeawaterPolynomials", "SparseArrays", "StaticArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "3d3a937ad3a7a1ec9452e230b3de7f38d84f9a5c" -repo-rev = "xk/cuda-backport-compat" -repo-url = "https://github.com/CliMA/Oceananigans.jl.git" +git-tree-sha1 = "4780b18e5e966c85098ed576174cdf1cc94bf10b" uuid = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" -version = "0.100.3" +version = "0.100.5" [deps.Oceananigans.extensions] OceananigansAMDGPUExt = "AMDGPU" diff --git a/Project.toml b/Project.toml index 7c11975d2..c3f2a2e1f 100644 --- a/Project.toml +++ b/Project.toml @@ -19,7 +19,6 @@ ImageMorphology = "787d08f9-d448-5407-9aad-5290dd7ab264" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" -MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" MeshArrays = "cb8c808f-1acf-59a3-9d2b-6e38d009f683" NCDatasets = "85f8d34a-cbdd-5861-8df4-14fed0d494ab" Oceananigans = "9e8cae18-63c1-5223-a75c-80ca9d6e9a09" From 582f80dd97916f70ede21e6ac7b998129a75ff02 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 18 Oct 2025 02:29:22 -0700 Subject: [PATCH 251/258] a grave error! --- half_degree_omip_calibrationsamples.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/half_degree_omip_calibrationsamples.jl b/half_degree_omip_calibrationsamples.jl index 6558553e7..c8034b1f3 100644 --- a/half_degree_omip_calibrationsamples.jl +++ b/half_degree_omip_calibrationsamples.jl @@ -131,7 +131,8 @@ simulation_period = Dates.value(Second(end_date - start_date)) yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) # sampling_endtimes = decadal_times[3:end] -sampling_window = Dates.value(Second(end_date - Year(10))) +sampling_start_date = end_date - Year(10) +sampling_window = Dates.value(Second(end_date - sampling_start_date)) @info "Settting up salinity restoring..." @inline mask(x, y, z, t) = z ≥ z_surf - 1 From 8361e1dcbdce5abffd16778480fc20d0cfb2de77 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Sat, 18 Oct 2025 03:06:54 -0700 Subject: [PATCH 252/258] Add sampling length argument to command line parser and update related logging --- half_degree_omip_calibrationsamples.jl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/half_degree_omip_calibrationsamples.jl b/half_degree_omip_calibrationsamples.jl index c8034b1f3..26da8a410 100644 --- a/half_degree_omip_calibrationsamples.jl +++ b/half_degree_omip_calibrationsamples.jl @@ -47,6 +47,10 @@ function parse_commandline() help = "Length of the simulation in years" arg_type = Int default = 20 + "--sampling_length" + help = "Length of the sampling window in years" + arg_type = Int + default = 10 end return parse_args(s) end @@ -56,8 +60,9 @@ args = parse_commandline() κ_symmetric = args["kappa_symmetric"] start_year = args["start_year"] simulation_length = args["simulation_length"] +sampling_length = args["sampling_length"] -@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s, starting in year $(start_year) for a length of $(simulation_length) years." +@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s, starting in year $(start_year) for a length of $(simulation_length) years with a $(sampling_length)-year sample." function synch!(clock1::Clock, clock2) # Synchronize the clocks @@ -119,7 +124,7 @@ end prefix *= "_$(κ_skew)_$(κ_symmetric)" prefix *= "_$(start_year)" -prefix *= "_$(simulation_length)year" +prefix *= "_$(simulation_length)year_$(sampling_length)yearsample" prefix *= "_advectiveGM_multiyearjra55_calibrationsamples" dir = joinpath(homedir(), "forcing_data_half_degree") @@ -131,7 +136,7 @@ simulation_period = Dates.value(Second(end_date - start_date)) yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) # sampling_endtimes = decadal_times[3:end] -sampling_start_date = end_date - Year(10) +sampling_start_date = end_date - Year(sampling_length) sampling_window = Dates.value(Second(end_date - sampling_start_date)) @info "Settting up salinity restoring..." From c9ae84e2ce0e3efc4a4006c5188adf92830a195e Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 20 Oct 2025 14:20:04 -0700 Subject: [PATCH 253/258] Update filename for ocean output writer to include sampling length --- half_degree_omip_calibrationsamples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/half_degree_omip_calibrationsamples.jl b/half_degree_omip_calibrationsamples.jl index 26da8a410..1e61d09d2 100644 --- a/half_degree_omip_calibrationsamples.jl +++ b/half_degree_omip_calibrationsamples.jl @@ -252,7 +252,7 @@ sea_ice.output_writers[:time_average] = JLD2Writer(sea_ice.model, sea_ice_output ocean.output_writers[:sample_decadal_average] = JLD2Writer(ocean.model, ocean_outputs; schedule = AveragedTimeInterval(simulation_period, window=sampling_window), - filename = "$(FILE_DIR)/ocean_complete_fields_10year_average_calibrationsample", + filename = "$(FILE_DIR)/ocean_complete_fields_$(sampling_length)year_average_calibrationsample", overwrite_existing = true) wall_time = Ref(time_ns()) From 091f658fa15525e4df8339874879c868d5f2e5a8 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 20 Oct 2025 22:34:43 -0700 Subject: [PATCH 254/258] Add one-degree OMIP calibration samples script with command line parsing and output configuration --- one_degree_omip_calibrationsamples.jl | 288 ++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 one_degree_omip_calibrationsamples.jl diff --git a/one_degree_omip_calibrationsamples.jl b/one_degree_omip_calibrationsamples.jl new file mode 100644 index 000000000..3c0f520c9 --- /dev/null +++ b/one_degree_omip_calibrationsamples.jl @@ -0,0 +1,288 @@ +using ClimaOcean +using ClimaSeaIce +using Oceananigans +using Oceananigans.Grids +using Oceananigans.Units +using Oceananigans.OrthogonalSphericalShellGrids +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency +using ClimaOcean.OceanSimulations +using ClimaOcean.ECCO +using ClimaOcean.JRA55 +using ClimaOcean.DataWrangling +using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using Printf +using Dates +using CUDA +using JLD2 +using ArgParse +using Oceananigans.OutputWriters: AveragedSpecifiedTimes + +import Oceananigans.OutputWriters: checkpointer_address + +using Libdl +ucx_libs = filter(lib -> occursin("ucx", lowercase(lib)), Libdl.dllist()) +if isempty(ucx_libs) + @info "✓ No UCX - safe to run!" +else + @warn "✗ UCX libraries detected! This can cause issues with MPI+CUDA. Detected libs:\n$(join(ucx_libs, "\n"))" +end + +function parse_commandline() + s = ArgParseSettings() + + @add_arg_table! s begin + "--kappa_skew" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 1e3 + "--kappa_symmetric" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 1e3 + "--start_year" + help = "Start year of the simulation" + arg_type = Int + default = 1992 + "--simulation_length" + help = "Length of the simulation in years" + arg_type = Int + default = 25 + "--sampling_length" + help = "Length of the sampling window in years" + arg_type = Int + default = 10 + end + return parse_args(s) +end + +args = parse_commandline() +κ_skew = args["kappa_skew"] +κ_symmetric = args["kappa_symmetric"] +start_year = args["start_year"] +simulation_length = args["simulation_length"] +sampling_length = args["sampling_length"] + +@info "1-degree omip" +@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s, starting in year $(start_year) for a length of $(simulation_length) years with a $(sampling_length)-year sample." + +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) +# restart_iteration = "446000" +restart_iteration = nothing + +arch = GPU() + +Nx = 360 # longitudinal direction +Ny = 180 # meridional direction +Nz = 100 + +z_faces = ExponentialDiscretization(Nz, -6000, 0; scale=1800) +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=55) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +##### +##### A Propgnostic Ocean model +##### + +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization, AdvectiveFormulation, IsopycnalSkewSymmetricDiffusivity +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=50minutes) + +using Oceananigans.Operators: Δx, Δy + +eddy_closure = IsopycnalSkewSymmetricDiffusivity(; κ_skew, κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) +# obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() +obl_closure = RiBasedVerticalDiffusivity() + +closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=3e-4), eddy_closure) + +prefix = "onedegree" +if obl_closure isa RiBasedVerticalDiffusivity + prefix *= "_RiBased" +else + prefix *= "_CATKE" +end + +prefix *= "_$(κ_skew)_$(κ_symmetric)" +prefix *= "_$(start_year)" +prefix *= "_$(simulation_length)year_$(sampling_length)yearsample" +prefix *= "_advectiveGM_multiyearjra55_calibrationsamples" + +dir = joinpath(homedir(), "forcing_data_half_degree") +mkpath(dir) + +start_date = DateTime(start_year, 1, 1) +end_date = start_date + Year(simulation_length) +simulation_period = Dates.value(Second(end_date - start_date)) +yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) +decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) +# sampling_endtimes = decadal_times[3:end] +sampling_start_date = end_date - Year(sampling_length) +sampling_window = Dates.value(Second(end_date - sampling_start_date)) + +@info "Settting up salinity restoring..." +@inline mask(x, y, z, t) = z ≥ z_surf - 1 +Smetadata = Metadata(:salinity; dataset=ECCO4Monthly(), dir, start_date, end_date) +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) + +@info "Built ocean model $(ocean)" + +set!(ocean.model, T=Metadatum(:temperature; dataset=ECCO4Monthly(), date=start_date, dir), + S=Metadatum(:salinity; dataset=ECCO4Monthly(), date=start_date, dir)) +@info "Initialized T and S" + +##### +##### 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)) +sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) +@info "Built sea ice model $(sea_ice)" + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) + +@info "Initialized sea ice fields" + +##### +##### A Prescribed Atmosphere model +##### +jra55_dir = joinpath(homedir(), "JRA55_data") +mkpath(jra55_dir) +dataset = MultiYearJRA55() +backend = JRA55NetCDFBackend(100) + +@info "Setting up presctibed atmosphere $(dataset)" +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) +radiation = Radiation() + +@info "Built atmosphere model $(atmosphere)" + +##### +##### An ocean-sea ice coupled model +##### + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +@info "Built coupled model $(omip)" + +omip = Simulation(omip, Δt=40minutes, stop_time=simulation_period) +@info "Built simulation $(omip)" + +# Figure out the outputs.... +checkpointer_address(::SeaIceModel) = "SeaIceModel" + +FILE_DIR = "./Data/$(prefix)/" +mkpath(FILE_DIR) + +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/ocean_checkpoint", + overwrite_existing = true) + +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/sea_ice_checkpoint", + overwrite_existing = true) + +u, v, w = ocean.model.velocities +T, S = ocean.model.tracers +b = Field(buoyancy(ocean.model)) +N² = Field(buoyancy_frequency(ocean.model)) + +ocean_outputs = merge(ocean.model.tracers, ocean.model.velocities, (; b, N²)) +sea_ice_outputs = merge((h = sea_ice.model.ice_thickness, + ℵ = sea_ice.model.ice_concentration, + T = sea_ice.model.ice_thermodynamics.top_surface_temperature), + sea_ice.model.velocities) + +ocean.output_writers[:surface] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/ocean_surface_fields", + indices = (:, :, grid.Nz), + overwrite_existing = true) + +sea_ice.output_writers[:surface] = JLD2Writer(ocean.model, sea_ice_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/sea_ice_surface_fields", + overwrite_existing = true) + +ocean.output_writers[:full] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(1825days), + filename = "$(FILE_DIR)/ocean_complete_fields", + overwrite_existing = true) + +ocean.output_writers[:time_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(3650days, window=3650days), + filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", + overwrite_existing = true) + +sea_ice.output_writers[:time_average] = JLD2Writer(sea_ice.model, sea_ice_outputs; + schedule = AveragedTimeInterval(3650days, window=3650days), + filename = "$(FILE_DIR)/sea_ice_complete_fields_10year_average", + overwrite_existing = true) + +ocean.output_writers[:sample_decadal_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(simulation_period, window=sampling_window), + filename = "$(FILE_DIR)/ocean_complete_fields_$(sampling_length)year_average_calibrationsample", + 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(100)) + +run!(omip) \ No newline at end of file From 667c5da92fabb83888f257ceca5b21b65047d186 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Mon, 20 Oct 2025 22:38:09 -0700 Subject: [PATCH 255/258] Update bathymetry regrid interpolation passes and change salinity dataset to EN4Monthly --- one_degree_omip_calibrationsamples.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/one_degree_omip_calibrationsamples.jl b/one_degree_omip_calibrationsamples.jl index 3c0f520c9..ea1a3e9ec 100644 --- a/one_degree_omip_calibrationsamples.jl +++ b/one_degree_omip_calibrationsamples.jl @@ -90,7 +90,7 @@ grid = TripolarGrid(arch; z = z_faces, halo = (7, 7, 7)) -bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=55) +bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=75) grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) ##### @@ -138,7 +138,7 @@ sampling_window = Dates.value(Second(end_date - sampling_start_date)) @info "Settting up salinity restoring..." @inline mask(x, y, z, t) = z ≥ z_surf - 1 -Smetadata = Metadata(:salinity; dataset=ECCO4Monthly(), dir, start_date, end_date) +Smetadata = Metadata(:salinity; dataset=EN4Monthly(), dir, start_date, end_date) FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 10) ocean = ocean_simulation(grid; Δt=1minutes, @@ -151,8 +151,8 @@ ocean = ocean_simulation(grid; Δt=1minutes, @info "Built ocean model $(ocean)" -set!(ocean.model, T=Metadatum(:temperature; dataset=ECCO4Monthly(), date=start_date, dir), - S=Metadatum(:salinity; dataset=ECCO4Monthly(), date=start_date, dir)) +set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_date, dir), + S=Metadatum(:salinity; dataset=EN4Monthly(), date=start_date, dir)) @info "Initialized T and S" ##### From 0009799251380cb88819e3dc0d23b6ffd6ab58a6 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 21 Oct 2025 10:35:01 -0700 Subject: [PATCH 256/258] Update data directory paths to use EN4 and ECCO datasets --- one_degree_omip_calibrationsamples.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/one_degree_omip_calibrationsamples.jl b/one_degree_omip_calibrationsamples.jl index ea1a3e9ec..0c39047ee 100644 --- a/one_degree_omip_calibrationsamples.jl +++ b/one_degree_omip_calibrationsamples.jl @@ -124,7 +124,7 @@ prefix *= "_$(start_year)" prefix *= "_$(simulation_length)year_$(sampling_length)yearsample" prefix *= "_advectiveGM_multiyearjra55_calibrationsamples" -dir = joinpath(homedir(), "forcing_data_half_degree") +dir = joinpath(homedir(), "EN4_data") mkpath(dir) start_date = DateTime(start_year, 1, 1) @@ -164,6 +164,8 @@ set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_dat sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) @info "Built sea ice model $(sea_ice)" +dir = joinpath(homedir(), "ECCO_data") + set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) From 3fce1198cd1a13108c22e32ef97e2d0512b3e9f4 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 21 Oct 2025 13:12:25 -0700 Subject: [PATCH 257/258] Update data directory and salinity dataset to use ECCO4Monthly --- one_degree_omip_calibrationsamples.jl | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/one_degree_omip_calibrationsamples.jl b/one_degree_omip_calibrationsamples.jl index 0c39047ee..d6722022e 100644 --- a/one_degree_omip_calibrationsamples.jl +++ b/one_degree_omip_calibrationsamples.jl @@ -124,7 +124,7 @@ prefix *= "_$(start_year)" prefix *= "_$(simulation_length)year_$(sampling_length)yearsample" prefix *= "_advectiveGM_multiyearjra55_calibrationsamples" -dir = joinpath(homedir(), "EN4_data") +dir = joinpath(homedir(), "ECCO_data") mkpath(dir) start_date = DateTime(start_year, 1, 1) @@ -138,7 +138,7 @@ sampling_window = Dates.value(Second(end_date - sampling_start_date)) @info "Settting up salinity restoring..." @inline mask(x, y, z, t) = z ≥ z_surf - 1 -Smetadata = Metadata(:salinity; dataset=EN4Monthly(), dir, start_date, end_date) +Smetadata = Metadata(:salinity; dataset=ECCO4Monthly(), dir, start_date, end_date) FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 10) ocean = ocean_simulation(grid; Δt=1minutes, @@ -151,8 +151,8 @@ ocean = ocean_simulation(grid; Δt=1minutes, @info "Built ocean model $(ocean)" -set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_date, dir), - S=Metadatum(:salinity; dataset=EN4Monthly(), date=start_date, dir)) +set!(ocean.model, T=Metadatum(:temperature; dataset=ECCO4Monthly(), date=start_date, dir), + S=Metadatum(:salinity; dataset=ECCO4Monthly(), date=start_date, dir)) @info "Initialized T and S" ##### @@ -164,8 +164,6 @@ set!(ocean.model, T=Metadatum(:temperature; dataset=EN4Monthly(), date=start_dat sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) @info "Built sea ice model $(sea_ice)" -dir = joinpath(homedir(), "ECCO_data") - set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), dir), ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), dir)) From 3a2046f5caec26798a655bd4e4215f1e79e29049 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 24 Oct 2025 17:19:46 -0700 Subject: [PATCH 258/258] half degree omip with correct ecco initialization --- ...p_calibrationsamples_eccoinitialization.jl | 290 ++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 half_degree_omip_calibrationsamples_eccoinitialization.jl diff --git a/half_degree_omip_calibrationsamples_eccoinitialization.jl b/half_degree_omip_calibrationsamples_eccoinitialization.jl new file mode 100644 index 000000000..02c96a10a --- /dev/null +++ b/half_degree_omip_calibrationsamples_eccoinitialization.jl @@ -0,0 +1,290 @@ +using ClimaOcean +using ClimaSeaIce +using Oceananigans +using Oceananigans.Grids +using Oceananigans.Units +using Oceananigans.OrthogonalSphericalShellGrids +using Oceananigans.BuoyancyFormulations: buoyancy, buoyancy_frequency +using ClimaOcean.OceanSimulations +using ClimaOcean.ECCO +using ClimaOcean.JRA55 +using ClimaOcean.DataWrangling +using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium +using Printf +using Dates +using CUDA +using JLD2 +using ArgParse +using Oceananigans.OutputWriters: AveragedSpecifiedTimes + +import Oceananigans.OutputWriters: checkpointer_address + +using Libdl +ucx_libs = filter(lib -> occursin("ucx", lowercase(lib)), Libdl.dllist()) +if isempty(ucx_libs) + @info "✓ No UCX - safe to run!" +else + @warn "✗ UCX libraries detected! This can cause issues with MPI+CUDA. Detected libs:\n$(join(ucx_libs, "\n"))" +end + +function parse_commandline() + s = ArgParseSettings() + + @add_arg_table! s begin + "--kappa_skew" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + "--kappa_symmetric" + help = "Isopycnal skew diffusivity (m^2/s)" + arg_type = Float64 + default = 5e2 + "--start_year" + help = "Start year of the simulation" + arg_type = Int + default = 1962 + "--simulation_length" + help = "Length of the simulation in years" + arg_type = Int + default = 20 + "--sampling_length" + help = "Length of the sampling window in years" + arg_type = Int + default = 10 + end + return parse_args(s) +end + +args = parse_commandline() +κ_skew = args["kappa_skew"] +κ_symmetric = args["kappa_symmetric"] +start_year = args["start_year"] +simulation_length = args["simulation_length"] +sampling_length = args["sampling_length"] + +@info "Using κ_skew = $(κ_skew) m²/s and κ_symmetric = $(κ_symmetric) m²/s, starting in year $(start_year) for a length of $(simulation_length) years with a $(sampling_length)-year sample." + +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) +# restart_iteration = "446000" +restart_iteration = nothing + +arch = GPU() + +Nx = 720 # longitudinal direction +Ny = 360 # meridional direction +Nz = 100 + +z_faces = ExponentialDiscretization(Nz, -6000, 0; scale=1800) +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=55) +grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) + +##### +##### A Propgnostic Ocean model +##### + +using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization, AdvectiveFormulation, IsopycnalSkewSymmetricDiffusivity +using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation + +momentum_advection = WENOVectorInvariant(order=5) +tracer_advection = WENO(order=7) +free_surface = SplitExplicitFreeSurface(grid; cfl=0.8, fixed_Δt=50minutes) + +using Oceananigans.Operators: Δx, Δy + +@inline Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz) = 2 * (1 / (1 / Δx(i, j, k, grid, lx, ly, lz)^2 + 1 / Δy(i, j, k, grid, lx, ly, lz)^2)) +@inline geometric_νhb(i, j, k, grid, lx, ly, lz, clock, fields, λ) = Δ²ᵃᵃᵃ(i, j, k, grid, lx, ly, lz)^2 / λ + +eddy_closure = IsopycnalSkewSymmetricDiffusivity(; κ_skew, κ_symmetric, skew_flux_formulation=AdvectiveFormulation()) +obl_closure = ClimaOcean.OceanSimulations.default_ocean_closure() +visc_closure = HorizontalScalarBiharmonicDiffusivity(ν=geometric_νhb, discrete_form=true, parameters=25days) + +closure = (obl_closure, VerticalScalarDiffusivity(κ=1e-5, ν=3e-4), visc_closure, eddy_closure) + +prefix = "halfdegree_eccoinitial" +if obl_closure isa RiBasedVerticalDiffusivity + prefix *= "_RiBased" +else + prefix *= "_CATKE" +end + +prefix *= "_$(κ_skew)_$(κ_symmetric)" +prefix *= "_$(start_year)" +prefix *= "_$(simulation_length)year_$(sampling_length)yearsample" +prefix *= "_advectiveGM_multiyearjra55_calibrationsamples" + +dir = joinpath(homedir(), "ECCO_data") +mkpath(dir) + +start_date = DateTime(start_year, 1, 1) +end_date = start_date + Year(simulation_length) +simulation_period = Dates.value(Second(end_date - start_date)) +yearly_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(1):end_date))))) +decadal_times = cumsum(vcat([0.], Dates.value.(Second.(diff(start_date:Year(10):end_date))))) +# sampling_endtimes = decadal_times[3:end] +sampling_start_date = end_date - Year(sampling_length) +sampling_window = Dates.value(Second(end_date - sampling_start_date)) + +@info "Settting up salinity restoring..." +@inline mask(x, y, z, t) = z ≥ z_surf - 1 +Smetadata = Metadata(:salinity; dataset=ECCO4Monthly(), dir, start_date, end_date) +FS = DatasetRestoring(Smetadata, grid; rate = 1/30days, mask, time_indices_in_memory = 10) + +ocean = ocean_simulation(grid; Δt=1minutes, + momentum_advection, + tracer_advection, + timestepper = :SplitRungeKutta3, + free_surface, + forcing = (; S = FS), + closure) + +@info "Built ocean model $(ocean)" + +set!(ocean.model, T=Metadatum(:temperature; dataset=ECCO4Monthly(), date=start_date, dir), + S=Metadatum(:salinity; dataset=ECCO4Monthly(), date=start_date, dir)) +@info "Initialized T and S" + +##### +##### 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)) +sea_ice = sea_ice_simulation(grid, ocean; dynamics=nothing) +@info "Built sea ice model $(sea_ice)" + +set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly(), date=start_date, dir), + ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly(), date=start_date, dir)) + +@info "Initialized sea ice fields" + +##### +##### A Prescribed Atmosphere model +##### +jra55_dir = joinpath(homedir(), "JRA55_data") +mkpath(jra55_dir) +dataset = MultiYearJRA55() +backend = JRA55NetCDFBackend(100) + +@info "Setting up presctibed atmosphere $(dataset)" +atmosphere = JRA55PrescribedAtmosphere(arch; dir=jra55_dir, dataset, backend, include_rivers_and_icebergs=true, start_date, end_date) +radiation = Radiation() + +@info "Built atmosphere model $(atmosphere)" + +##### +##### An ocean-sea ice coupled model +##### + +omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) + +@info "Built coupled model $(omip)" + +omip = Simulation(omip, Δt=30minutes, stop_time=simulation_period) +@info "Built simulation $(omip)" + +# Figure out the outputs.... +checkpointer_address(::SeaIceModel) = "SeaIceModel" + +FILE_DIR = "./Data/$(prefix)/" +mkpath(FILE_DIR) + +ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/ocean_checkpoint", + overwrite_existing = true) + +sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, + schedule = SpecifiedTimes(decadal_times), + prefix = "$(FILE_DIR)/sea_ice_checkpoint", + overwrite_existing = true) + +u, v, w = ocean.model.velocities +T, S = ocean.model.tracers +b = Field(buoyancy(ocean.model)) +N² = Field(buoyancy_frequency(ocean.model)) + +ocean_outputs = merge(ocean.model.tracers, ocean.model.velocities, (; b, N²)) +sea_ice_outputs = merge((h = sea_ice.model.ice_thickness, + ℵ = sea_ice.model.ice_concentration, + T = sea_ice.model.ice_thermodynamics.top_surface_temperature), + sea_ice.model.velocities) + +ocean.output_writers[:surface] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/ocean_surface_fields", + indices = (:, :, grid.Nz), + overwrite_existing = true) + +sea_ice.output_writers[:surface] = JLD2Writer(ocean.model, sea_ice_outputs; + schedule = TimeInterval(180days), + filename = "$(FILE_DIR)/sea_ice_surface_fields", + overwrite_existing = true) + +ocean.output_writers[:full] = JLD2Writer(ocean.model, ocean_outputs; + schedule = TimeInterval(1825days), + filename = "$(FILE_DIR)/ocean_complete_fields", + overwrite_existing = true) + +ocean.output_writers[:time_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(3650days, window=3650days), + filename = "$(FILE_DIR)/ocean_complete_fields_10year_average", + overwrite_existing = true) + +sea_ice.output_writers[:time_average] = JLD2Writer(sea_ice.model, sea_ice_outputs; + schedule = AveragedTimeInterval(3650days, window=3650days), + filename = "$(FILE_DIR)/sea_ice_complete_fields_10year_average", + overwrite_existing = true) + +ocean.output_writers[:sample_decadal_average] = JLD2Writer(ocean.model, ocean_outputs; + schedule = AveragedTimeInterval(simulation_period, window=sampling_window), + filename = "$(FILE_DIR)/ocean_complete_fields_$(sampling_length)year_average_calibrationsample", + 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(100)) + +run!(omip) \ No newline at end of file