From 48aa15c656238e212618f8d037b11a16ad0e27c0 Mon Sep 17 00:00:00 2001 From: Tomas Chor Date: Thu, 2 May 2024 10:29:26 -0700 Subject: [PATCH 01/21] Update netcdf_output_writer.jl --- src/OutputWriters/netcdf_output_writer.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 0fb468a117..802b98f5b4 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -355,7 +355,7 @@ NetCDFOutputWriter scheduled on IterationInterval(1): └── file size: 17.8 KiB ``` """ -function NetCDFOutputWriter(model, outputs; filename, schedule, +function NetCDFOutputWriter(model, outputs, grid = model.grid; filename, schedule, dir = ".", array_type = Array{Float64}, indices = (:, :, :), @@ -394,7 +394,7 @@ function NetCDFOutputWriter(model, outputs; filename, schedule, # with LagrangianParticles output (see the end of the file). # We shouldn't support this in the future; we should require users to 'name' LagrangianParticles output. outputs = dictify(outputs) - outputs = Dict(string(name) => construct_output(outputs[name], model.grid, indices, with_halos) for name in keys(outputs)) + outputs = Dict(string(name) => construct_output(outputs[name], grid, indices, with_halos) for name in keys(outputs)) output_attributes = dictify(output_attributes) global_attributes = dictify(global_attributes) From f0143e18849136bf09944567c89f4d22f6d1c9d7 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Fri, 3 May 2024 10:52:31 -0600 Subject: [PATCH 02/21] Add grid as property to NetCDFOutputWriter and use it during file initialization --- src/OutputWriters/netcdf_output_writer.jl | 39 +++++++++++++---------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 802b98f5b4..9fbef4661d 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -10,7 +10,8 @@ using Oceananigans.Utils: versioninfo_with_gpu, oceananigans_versioninfo, pretty using Oceananigans.TimeSteppers: float_or_date_time using Oceananigans.Fields: reduced_dimensions, reduced_location, location, validate_indices -mutable struct NetCDFOutputWriter{D, O, T, A, FS} <: AbstractOutputWriter +mutable struct NetCDFOutputWriter{G, D, O, T, A, FS} <: AbstractOutputWriter + grid :: G filepath :: String dataset :: D outputs :: O @@ -355,19 +356,21 @@ NetCDFOutputWriter scheduled on IterationInterval(1): └── file size: 17.8 KiB ``` """ -function NetCDFOutputWriter(model, outputs, grid = model.grid; filename, schedule, - dir = ".", - array_type = Array{Float64}, - indices = (:, :, :), - with_halos = false, +function NetCDFOutputWriter(model, outputs, grid=model.grid; + filename, + schedule, + dir = ".", + array_type = Array{Float64}, + indices = (:, :, :), + with_halos = false, global_attributes = Dict(), output_attributes = Dict(), - dimensions = Dict(), - overwrite_existing = nothing, - deflatelevel = 0, - part = 1, - file_splitting = NoFileSplitting(), - verbose = false) + dimensions = Dict(), + overwrite_existing = nothing, + deflatelevel = 0, + part = 1, + file_splitting = NoFileSplitting(), + verbose = false) mkpath(dir) filename = auto_extension(filename, ".nc") filepath = joinpath(dir, filename) @@ -414,9 +417,11 @@ function NetCDFOutputWriter(model, outputs, grid = model.grid; filename, schedul dimensions, overwrite_existing, deflatelevel, + grid, model) - return NetCDFOutputWriter(filepath, + return NetCDFOutputWriter(grid, + filepath, dataset, outputs, schedule, @@ -633,6 +638,7 @@ function initialize_nc_file!(filepath, dimensions, overwrite_existing, deflatelevel, + grid, model) mode = overwrite_existing ? "c" : "a" @@ -648,12 +654,12 @@ function initialize_nc_file!(filepath, # schedule::AveragedTimeInterval schedule, outputs = time_average_outputs(schedule, outputs, model) - dims = default_dimensions(outputs, model.grid, indices, with_halos) + dims = default_dimensions(outputs, grid, indices, with_halos) # Open the NetCDF dataset file dataset = NCDataset(filepath, mode, attrib=global_attributes) - default_dimension_attributes = get_default_dimension_attributes(model.grid) + default_dimension_attributes = get_default_dimension_attributes(grid) # Define variables for each dimension and attributes if this is a new file. if mode == "c" @@ -669,7 +675,7 @@ function initialize_nc_file!(filepath, # Creates an unlimited dimension "time" defDim(dataset, "time", Inf) - defVar(dataset, "time", eltype(model.grid), ("time",), attrib=time_attrib) + defVar(dataset, "time", eltype(grid), ("time",), attrib=time_attrib) # Use default output attributes for known outputs if the user has not specified any. # Unknown outputs get an empty tuple (no output attributes). @@ -704,4 +710,5 @@ initialize_nc_file!(ow::NetCDFOutputWriter, model) = ow.dimensions, ow.overwrite_existing, ow.deflatelevel, + ow.grid, model) From 296ab22bb7d8f58f52768c8b21a3eedfa2963c1c Mon Sep 17 00:00:00 2001 From: iury simoes-sousa Date: Fri, 3 May 2024 17:31:56 -0400 Subject: [PATCH 03/21] paragraph explaining that netcdf writer also accepts an output grid --- docs/src/model_setup/output_writers.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index 8d1ee230b3..e7d6bd7955 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -158,6 +158,9 @@ NetCDFOutputWriter scheduled on IterationInterval(1): └── file size: 17.8 KiB ``` +`NetCDFOutputWriter` also accepts an arbitrary `grid` for input that can be used to interpolate or subset the output fields. The output `grid` must be in the same architecture as the original grid. + + See [`NetCDFOutputWriter`](@ref) for more information. ## JLD2 output writer From 1ce9908ddb9497c94bb4eddf24f3d66676b9b109 Mon Sep 17 00:00:00 2001 From: iury simoes-sousa Date: Mon, 6 May 2024 11:13:48 -0400 Subject: [PATCH 04/21] change wording and add jldoctest --- docs/src/model_setup/output_writers.md | 40 +++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index e7d6bd7955..ef941c9f13 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -158,8 +158,46 @@ NetCDFOutputWriter scheduled on IterationInterval(1): └── file size: 17.8 KiB ``` -`NetCDFOutputWriter` also accepts an arbitrary `grid` for input that can be used to interpolate or subset the output fields. The output `grid` must be in the same architecture as the original grid. +`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded to a different grid than `model.grid`. To use this functionality, the `output_grid` must be passed explicitly when constructing `NetCDFOutputWriter` along with the regridded / interpolated `outputs`. +```jldoctest +using Oceananigans + +grid = RectilinearGrid(size = (1, 1, 8), extent = (1,1,1)); +model = NonhydrostaticModel(; grid, closure = ScalarDiffusivity(ν=1e-2)) + +set!(model, u=(x, y, z,) -> z) + +simulation = Simulation(model, + Δt=0.5*maximum(zspacings(grid, Center())) / maximum(abs, model.velocities.u), + stop_time=20) + +simulation.output_writers[:fullfields] = NetCDFOutputWriter(model, (; model.velocities.u), + filename = "fullfields.nc", + schedule = TimeInterval(5), + overwrite_existing = true,) + +coarse_grid = RectilinearGrid(size = (grid.Nx, grid.Ny, grid.Nz÷2), extent = (grid.Lx, grid.Ly, grid.Lz)) +coarse_u = Field{Face, Center, Center}(coarse_grid) + +using Oceananigans.Fields: interpolate! +update_coarse_u(simulation) = interpolate!(coarse_u, simulation.model.velocities.u) +simulation.callbacks[:update_interp] = Callback(update_coarse_u) + +simulation.output_writers[:coarsefields] = NetCDFOutputWriter(model, (; coarse_u,), coarse_grid; + filename="coarsefields.nc", + schedule=TimeInterval(5), + overwrite_existing=true,) + +# output +NetCDFOutputWriter scheduled on TimeInterval(5 seconds): +├── filepath: ./coarsefields.nc +├── dimensions: zC(4), zF(5), xC(1), yF(1), xF(1), yC(1), time(0) +├── 1 outputs: coarse_u +└── array type: Array{Float64} +├── file_splitting: NoFileSplitting +└── file size: 14.6 KiB +``` See [`NetCDFOutputWriter`](@ref) for more information. From fa97a72a3a13f5a2fe4f6c22a11814c00182b21c Mon Sep 17 00:00:00 2001 From: Iury Simoes-Sousa Date: Mon, 6 May 2024 11:21:04 -0400 Subject: [PATCH 05/21] Update docs/src/model_setup/output_writers.md Co-authored-by: Gregory L. Wagner --- docs/src/model_setup/output_writers.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index ef941c9f13..d2dc15136e 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -158,7 +158,8 @@ NetCDFOutputWriter scheduled on IterationInterval(1): └── file size: 17.8 KiB ``` -`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded to a different grid than `model.grid`. To use this functionality, the `output_grid` must be passed explicitly when constructing `NetCDFOutputWriter` along with the regridded / interpolated `outputs`. +`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded to a different grid than `model.grid`. +To use this functionality, the `output_grid` must be passed explicitly when constructing `NetCDFOutputWriter` along with the regridded / interpolated `outputs`. ```jldoctest using Oceananigans From 077fea67e41810f3e8d29c46097affccff2b2665 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Mon, 6 May 2024 14:33:36 -0600 Subject: [PATCH 06/21] Do a little better with function output for NetCDF output writer --- src/OutputWriters/netcdf_output_writer.jl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 9fbef4661d..968aba20f5 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -451,6 +451,10 @@ get_default_dimension_attributes(grid::ImmersedBoundaryGrid) = ##### Variable definition ##### +materialize_output(func, model) = func(model) +materialize_output(field::AbstractField, model) = field +materialize_output(particles::LagrangianParticles, model) = particles + """ Defines empty variables for 'custom' user-supplied `output`. """ function define_output_variable!(dataset, output, name, array_type, deflatelevel, output_attributes, dimensions) name ∉ keys(dimensions) && error("Custom output $name needs dimensions!") @@ -687,7 +691,9 @@ function initialize_nc_file!(filepath, for (name, output) in outputs attributes = try output_attributes[name]; catch; Dict(); end - define_output_variable!(dataset, output, name, array_type, deflatelevel, attributes, dimensions) + materialized = materialize_output(output, model) + define_output_variable!(dataset, materialized, name, array_type, + deflatelevel, attributes, dimensions) end sync(dataset) From c61729bbe8c3329be3cdcc8759dbee8293f41f5c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Tue, 7 May 2024 10:27:56 -0600 Subject: [PATCH 07/21] Fixes interpolate! plus some improvements to NetCDFOutputWriter --- src/Fields/interpolate.jl | 2 +- src/OutputWriters/netcdf_output_writer.jl | 42 ++++++++++++++++------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/Fields/interpolate.jl b/src/Fields/interpolate.jl index f34fb73f3f..85a5cdf10b 100644 --- a/src/Fields/interpolate.jl +++ b/src/Fields/interpolate.jl @@ -354,5 +354,5 @@ function interpolate!(to_field::Field, from_field::AbstractField) fill_halo_regions!(to_field) - return nothing + return to_field end diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 968aba20f5..8599e8a42b 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -456,21 +456,29 @@ materialize_output(field::AbstractField, model) = field materialize_output(particles::LagrangianParticles, model) = particles """ Defines empty variables for 'custom' user-supplied `output`. """ -function define_output_variable!(dataset, output, name, array_type, deflatelevel, output_attributes, dimensions) +function define_output_variable!(dataset, output, name, array_type, + deflatelevel, attrib, dimensions) + name ∉ keys(dimensions) && error("Custom output $name needs dimensions!") - defVar(dataset, name, eltype(array_type), (dimensions[name]..., "time"), - deflatelevel=deflatelevel, attrib=output_attributes) + dims = dimensions[name] + FT = eltype(array_type) + defVar(dataset, name, FT, (dims..., "time"); deflatelevel, attrib) return nothing end """ Defines empty field variable. """ -define_output_variable!(dataset, output::AbstractField, name, array_type, deflatelevel, output_attributes, dimensions) = - defVar(dataset, name, eltype(array_type), - (netcdf_spatial_dimensions(output)..., "time"), - deflatelevel=deflatelevel, attrib=output_attributes) +function define_output_variable!(dataset, output::AbstractField, name, array_type, + deflatelevel, attrib, dimensions) + + dims = netcdf_spatial_dimensions(output) + FT = eltype(array_type) + defVar(dataset, name, FT, (dims..., "time"); deflatelevel, attrib) + + return nothing +end """ Defines empty field variable for `WindowedTimeAverage`s over fields. """ define_output_variable!(dataset, output::WindowedTimeAverage{<:AbstractField}, args...) = @@ -589,12 +597,17 @@ end ##### """ Defines empty variable for particle trackting. """ -function define_output_variable!(dataset, output::LagrangianParticles, name, array_type, deflatelevel, output_attributes, dimensions) +function define_output_variable!(dataset, output::LagrangianParticles, name, array_type, + deflatelevel, output_attributes, dimensions) + particle_fields = eltype(output.properties) |> fieldnames .|> string + T = eltype(array_type) + for particle_field in particle_fields - defVar(dataset, particle_field, eltype(array_type), - ("particle_id", "time"), deflatelevel=deflatelevel) + defVar(dataset, particle_field, T, ("particle_id", "time"); deflatelevel) end + + return nothing end dictify(outputs::LagrangianParticles) = Dict("particles" => outputs) @@ -692,8 +705,13 @@ function initialize_nc_file!(filepath, for (name, output) in outputs attributes = try output_attributes[name]; catch; Dict(); end materialized = materialize_output(output, model) - define_output_variable!(dataset, materialized, name, array_type, - deflatelevel, attributes, dimensions) + define_output_variable!(dataset, + materialized, + name, + array_type, + deflatelevel, + attributes, + dimensions) end sync(dataset) From 4134b5b69a3b2e70d9c0518e062e9f75ecbd2075 Mon Sep 17 00:00:00 2001 From: iury simoes-sousa Date: Tue, 7 May 2024 12:48:12 -0400 Subject: [PATCH 08/21] add new example for docs --- docs/src/model_setup/output_writers.md | 37 ++++++++--------------- src/OutputWriters/netcdf_output_writer.jl | 35 +++++++++++++++++++-- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index d2dc15136e..e7c997a453 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -163,38 +163,27 @@ To use this functionality, the `output_grid` must be passed explicitly when cons ```jldoctest using Oceananigans +using Oceananigans.Fields: interpolate! -grid = RectilinearGrid(size = (1, 1, 8), extent = (1,1,1)); -model = NonhydrostaticModel(; grid, closure = ScalarDiffusivity(ν=1e-2)) - -set!(model, u=(x, y, z,) -> z) - -simulation = Simulation(model, - Δt=0.5*maximum(zspacings(grid, Center())) / maximum(abs, model.velocities.u), - stop_time=20) - -simulation.output_writers[:fullfields] = NetCDFOutputWriter(model, (; model.velocities.u), - filename = "fullfields.nc", - schedule = TimeInterval(5), - overwrite_existing = true,) +grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1)); +model = NonhydrostaticModel(; grid) +simulation = Simulation(model, Δt=1, stop_iteration=1) -coarse_grid = RectilinearGrid(size = (grid.Nx, grid.Ny, grid.Nz÷2), extent = (grid.Lx, grid.Ly, grid.Lz)) +coarse_grid = RectilinearGrid(size=(grid.Nx, grid.Ny, grid.Nz÷2), extent=(grid.Lx, grid.Ly, grid.Lz)) coarse_u = Field{Face, Center, Center}(coarse_grid) -using Oceananigans.Fields: interpolate! -update_coarse_u(simulation) = interpolate!(coarse_u, simulation.model.velocities.u) -simulation.callbacks[:update_interp] = Callback(update_coarse_u) +interpolate_u(model) = interpolate!(coarse_u, model.velocities.u) +outputs = (; u = interpolate_u) -simulation.output_writers[:coarsefields] = NetCDFOutputWriter(model, (; coarse_u,), coarse_grid; - filename="coarsefields.nc", - schedule=TimeInterval(5), - overwrite_existing=true,) +simulation.output_writers[:coarse_u] = NetCDFOutputWriter(model, outputs, coarse_grid; + filename = "coarse_u.nc", + schedule = IterationInterval(1)) # output -NetCDFOutputWriter scheduled on TimeInterval(5 seconds): -├── filepath: ./coarsefields.nc +NetCDFOutputWriter scheduled on IterationInterval(1): +├── filepath: ./coarse_u.nc ├── dimensions: zC(4), zF(5), xC(1), yF(1), xF(1), yC(1), time(0) -├── 1 outputs: coarse_u +├── 1 outputs: u └── array type: Array{Float64} ├── file_splitting: NoFileSplitting └── file size: 14.6 KiB diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 8599e8a42b..0605b276bb 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -163,7 +163,7 @@ function add_schedule_metadata!(global_attributes, schedule::AveragedTimeInterva end """ - NetCDFOutputWriter(model, outputs; filename, schedule + NetCDFOutputWriter(model, outputs, grid; filename, schedule dir = ".", array_type = Array{Float64}, indices = nothing, @@ -181,7 +181,7 @@ Construct a `NetCDFOutputWriter` that writes `(label, output)` pairs in `outputs be a `Dict`) to a NetCDF file, where `label` is a string that labels the output and `output` is either a `Field` (e.g. `model.velocities.u`) or a function `f(model)` that returns something to be written to disk. Custom output requires the spatial `dimensions` (a -`Dict`) to be manually specified (see examples). +`Dict`) or `grid` to be manually specified (see examples). Keyword arguments ================= @@ -355,6 +355,37 @@ NetCDFOutputWriter scheduled on IterationInterval(1): ├── file_splitting: NoFileSplitting └── file size: 17.8 KiB ``` + +`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded to a different grid than `model.grid`. +To use this functionality, the `output_grid` must be passed explicitly when constructing `NetCDFOutputWriter` along with the regridded / interpolated `outputs`. + +```jldoctest +using Oceananigans +using Oceananigans.Fields: interpolate! + +grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1)); +model = NonhydrostaticModel(; grid) +simulation = Simulation(model, Δt=1, stop_iteration=1) + +coarse_grid = RectilinearGrid(size=(grid.Nx, grid.Ny, grid.Nz÷2), extent=(grid.Lx, grid.Ly, grid.Lz)) +coarse_u = Field{Face, Center, Center}(coarse_grid) + +interpolate_u(model) = interpolate!(coarse_u, model.velocities.u) +outputs = (; u = interpolate_u) + +simulation.output_writers[:coarse_u] = NetCDFOutputWriter(model, outputs, coarse_grid; + filename = "coarse_u.nc", + schedule = IterationInterval(1)) + +# output +NetCDFOutputWriter scheduled on IterationInterval(1): +├── filepath: ./coarse_u.nc +├── dimensions: zC(4), zF(5), xC(1), yF(1), xF(1), yC(1), time(0) +├── 1 outputs: u +└── array type: Array{Float64} +├── file_splitting: NoFileSplitting +└── file size: 14.6 KiB +``` """ function NetCDFOutputWriter(model, outputs, grid=model.grid; filename, From ed5ce3e0e2cbbad36fe79ecc3ff3d3a147cf2cc1 Mon Sep 17 00:00:00 2001 From: iury simoes-sousa Date: Tue, 7 May 2024 16:09:59 -0400 Subject: [PATCH 09/21] simplify example --- docs/src/model_setup/output_writers.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index e7c997a453..ad9f43955c 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -167,7 +167,6 @@ using Oceananigans.Fields: interpolate! grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1)); model = NonhydrostaticModel(; grid) -simulation = Simulation(model, Δt=1, stop_iteration=1) coarse_grid = RectilinearGrid(size=(grid.Nx, grid.Ny, grid.Nz÷2), extent=(grid.Lx, grid.Ly, grid.Lz)) coarse_u = Field{Face, Center, Center}(coarse_grid) @@ -175,9 +174,9 @@ coarse_u = Field{Face, Center, Center}(coarse_grid) interpolate_u(model) = interpolate!(coarse_u, model.velocities.u) outputs = (; u = interpolate_u) -simulation.output_writers[:coarse_u] = NetCDFOutputWriter(model, outputs, coarse_grid; - filename = "coarse_u.nc", - schedule = IterationInterval(1)) +output_writer = NetCDFOutputWriter(model, outputs, coarse_grid; + filename = "coarse_u.nc", + schedule = IterationInterval(1)) # output NetCDFOutputWriter scheduled on IterationInterval(1): From 373f15a6dfeefc30137057c316769514d70bf3cc Mon Sep 17 00:00:00 2001 From: iury simoes-sousa Date: Tue, 7 May 2024 16:11:25 -0400 Subject: [PATCH 10/21] simplify example in the docstring --- src/OutputWriters/netcdf_output_writer.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 0605b276bb..dd59279baa 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -359,13 +359,16 @@ NetCDFOutputWriter scheduled on IterationInterval(1): `NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded to a different grid than `model.grid`. To use this functionality, the `output_grid` must be passed explicitly when constructing `NetCDFOutputWriter` along with the regridded / interpolated `outputs`. +```jldoctest +`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded to a different grid than `model.grid`. +To use this functionality, the `output_grid` must be passed explicitly when constructing `NetCDFOutputWriter` along with the regridded / interpolated `outputs`. + ```jldoctest using Oceananigans using Oceananigans.Fields: interpolate! grid = RectilinearGrid(size=(1, 1, 8), extent=(1, 1, 1)); model = NonhydrostaticModel(; grid) -simulation = Simulation(model, Δt=1, stop_iteration=1) coarse_grid = RectilinearGrid(size=(grid.Nx, grid.Ny, grid.Nz÷2), extent=(grid.Lx, grid.Ly, grid.Lz)) coarse_u = Field{Face, Center, Center}(coarse_grid) @@ -373,9 +376,9 @@ coarse_u = Field{Face, Center, Center}(coarse_grid) interpolate_u(model) = interpolate!(coarse_u, model.velocities.u) outputs = (; u = interpolate_u) -simulation.output_writers[:coarse_u] = NetCDFOutputWriter(model, outputs, coarse_grid; - filename = "coarse_u.nc", - schedule = IterationInterval(1)) +output_writer = NetCDFOutputWriter(model, outputs, coarse_grid; + filename = "coarse_u.nc", + schedule = IterationInterval(1)) # output NetCDFOutputWriter scheduled on IterationInterval(1): From 6f0b9fbc560685be31cae507a53df78b54fc45ca Mon Sep 17 00:00:00 2001 From: Iury Simoes-Sousa Date: Tue, 7 May 2024 21:34:03 -0400 Subject: [PATCH 11/21] Update docs/src/model_setup/output_writers.md Co-authored-by: Gregory L. Wagner --- docs/src/model_setup/output_writers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index ad9f43955c..9a5e73c721 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -175,8 +175,8 @@ interpolate_u(model) = interpolate!(coarse_u, model.velocities.u) outputs = (; u = interpolate_u) output_writer = NetCDFOutputWriter(model, outputs, coarse_grid; - filename = "coarse_u.nc", - schedule = IterationInterval(1)) + filename = "coarse_u.nc", + schedule = IterationInterval(1)) # output NetCDFOutputWriter scheduled on IterationInterval(1): From 42ccd033e0570e28bf589d73313c5b31e0bd832c Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 8 May 2024 06:48:44 -0600 Subject: [PATCH 12/21] Make grid a kwarg and update language --- docs/src/model_setup/output_writers.md | 6 ++- src/OutputWriters/netcdf_output_writer.jl | 55 ++++++++++++----------- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index 9a5e73c721..ea924ba8b3 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -158,8 +158,9 @@ NetCDFOutputWriter scheduled on IterationInterval(1): └── file size: 17.8 KiB ``` -`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded to a different grid than `model.grid`. -To use this functionality, the `output_grid` must be passed explicitly when constructing `NetCDFOutputWriter` along with the regridded / interpolated `outputs`. +`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded +to a different grid than `model.grid`. To use this functionality, include the keyword argument +`grid = output_grid`. ```jldoctest using Oceananigans @@ -312,3 +313,4 @@ JLD2OutputWriter scheduled on TimeInterval(4 days): ├── file_splitting: NoFileSplitting └── file size: 26.5 KiB ``` + diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index dd59279baa..56f694893a 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -163,29 +163,35 @@ function add_schedule_metadata!(global_attributes, schedule::AveragedTimeInterva end """ - NetCDFOutputWriter(model, outputs, grid; filename, schedule - dir = ".", - array_type = Array{Float64}, - indices = nothing, - with_halos = false, - global_attributes = Dict(), - output_attributes = Dict(), - dimensions = Dict(), - overwrite_existing = false, - deflatelevel = 0, - part = 1, - file_splitting = NoFileSplitting(), - verbose = false) + NetCDFOutputWriter(model, outputs; filename, schedule + grid = model.grid, + dir = ".", + array_type = Array{Float64}, + indices = nothing, + with_halos = false, + global_attributes = Dict(), + output_attributes = Dict(), + dimensions = Dict(), + overwrite_existing = false, + deflatelevel = 0, + part = 1, + file_splitting = NoFileSplitting(), + verbose = false) Construct a `NetCDFOutputWriter` that writes `(label, output)` pairs in `outputs` (which should be a `Dict`) to a NetCDF file, where `label` is a string that labels the output and `output` is either a `Field` (e.g. `model.velocities.u`) or a function `f(model)` that -returns something to be written to disk. Custom output requires the spatial `dimensions` (a -`Dict`) or `grid` to be manually specified (see examples). +returns something to be written to disk. + +If any of `outputs` are not `AbstractField`, their spatial `dimensions` must be provided. + +To use `outputs` on a `grid` not equal to `model.grid`, provide the keyword argument `grid.` Keyword arguments ================= +- `grid`: The grid associated with `outputs`. Defaults to `model.grid`. + ## Filenaming - `filename` (required): Descriptive filename. `".nc"` is appended to `filename` if `filename` does @@ -356,12 +362,9 @@ NetCDFOutputWriter scheduled on IterationInterval(1): └── file size: 17.8 KiB ``` -`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded to a different grid than `model.grid`. -To use this functionality, the `output_grid` must be passed explicitly when constructing `NetCDFOutputWriter` along with the regridded / interpolated `outputs`. - -```jldoctest -`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded to a different grid than `model.grid`. -To use this functionality, the `output_grid` must be passed explicitly when constructing `NetCDFOutputWriter` along with the regridded / interpolated `outputs`. +`NetCDFOutputWriter` can also be configured for `outputs` that are interpolated or regridded +to a different grid than `model.grid`. To use this functionality, include the keyword argument +`grid = output_grid`. ```jldoctest using Oceananigans @@ -376,9 +379,10 @@ coarse_u = Field{Face, Center, Center}(coarse_grid) interpolate_u(model) = interpolate!(coarse_u, model.velocities.u) outputs = (; u = interpolate_u) -output_writer = NetCDFOutputWriter(model, outputs, coarse_grid; - filename = "coarse_u.nc", - schedule = IterationInterval(1)) +output_writer = NetCDFOutputWriter(model, outputs; + grid = coarse_grid, + filename = "coarse_u.nc", + schedule = IterationInterval(1)) # output NetCDFOutputWriter scheduled on IterationInterval(1): @@ -390,9 +394,10 @@ NetCDFOutputWriter scheduled on IterationInterval(1): └── file size: 14.6 KiB ``` """ -function NetCDFOutputWriter(model, outputs, grid=model.grid; +function NetCDFOutputWriter(model, outputs; filename, schedule, + grid = model.grid; dir = ".", array_type = Array{Float64}, indices = (:, :, :), From 70e459aa8c06b3b26f84f6dcfd66036fb27c088d Mon Sep 17 00:00:00 2001 From: Iury Simoes-Sousa Date: Wed, 8 May 2024 12:35:04 -0400 Subject: [PATCH 13/21] Update src/OutputWriters/netcdf_output_writer.jl Co-authored-by: Tomas Chor --- src/OutputWriters/netcdf_output_writer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 56f694893a..8381991b60 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -163,7 +163,7 @@ function add_schedule_metadata!(global_attributes, schedule::AveragedTimeInterva end """ - NetCDFOutputWriter(model, outputs; filename, schedule + NetCDFOutputWriter(model, outputs; filename, schedule, grid = model.grid, dir = ".", array_type = Array{Float64}, From 940324315efd3fa5fe920bd22545ac3d74956b76 Mon Sep 17 00:00:00 2001 From: Iury Simoes-Sousa Date: Wed, 8 May 2024 12:35:15 -0400 Subject: [PATCH 14/21] Update docs/src/model_setup/output_writers.md Co-authored-by: Tomas Chor --- docs/src/model_setup/output_writers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index ea924ba8b3..aa894431a6 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -175,7 +175,7 @@ coarse_u = Field{Face, Center, Center}(coarse_grid) interpolate_u(model) = interpolate!(coarse_u, model.velocities.u) outputs = (; u = interpolate_u) -output_writer = NetCDFOutputWriter(model, outputs, coarse_grid; +output_writer = NetCDFOutputWriter(model, outputs; grid = coarse_grid; filename = "coarse_u.nc", schedule = IterationInterval(1)) From 45f0293c2da2672e7b9ffcfa10f2fc3c2243bfa0 Mon Sep 17 00:00:00 2001 From: Iury Simoes-Sousa Date: Wed, 8 May 2024 12:52:00 -0400 Subject: [PATCH 15/21] Update netcdf_output_writer.jl --- src/OutputWriters/netcdf_output_writer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 8381991b60..5f9f34b85c 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -397,7 +397,7 @@ NetCDFOutputWriter scheduled on IterationInterval(1): function NetCDFOutputWriter(model, outputs; filename, schedule, - grid = model.grid; + grid = model.grid, dir = ".", array_type = Array{Float64}, indices = (:, :, :), From 8c141ded3a0dee0a1a36b48e6f9910a72c75d327 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 8 May 2024 12:21:51 -0600 Subject: [PATCH 16/21] Bugfix plus better error message --- src/OutputWriters/netcdf_output_writer.jl | 15 ++++++++++----- test/test_output_writers.jl | 14 ++++++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 5f9f34b85c..b8bae8acc1 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -493,12 +493,17 @@ get_default_dimension_attributes(grid::ImmersedBoundaryGrid) = materialize_output(func, model) = func(model) materialize_output(field::AbstractField, model) = field materialize_output(particles::LagrangianParticles, model) = particles +materialize_output(output::WindowedTimeAverage{<:AbstractField}, model) = output """ Defines empty variables for 'custom' user-supplied `output`. """ function define_output_variable!(dataset, output, name, array_type, - deflatelevel, attrib, dimensions) + deflatelevel, attrib, dimensions, filepath) - name ∉ keys(dimensions) && error("Custom output $name needs dimensions!") + if name ∉ keys(dimensions) + msg = string("dimensions[$name] for output $name=", typeof(output), " into ", filepath, '\n', + " must be provided when constructing NetCDFOutputWriter") + throw(ArgumentError(msg)) + end dims = dimensions[name] FT = eltype(array_type) @@ -510,7 +515,7 @@ end """ Defines empty field variable. """ function define_output_variable!(dataset, output::AbstractField, name, array_type, - deflatelevel, attrib, dimensions) + deflatelevel, attrib, dimensions, filepath) dims = netcdf_spatial_dimensions(output) FT = eltype(array_type) @@ -523,7 +528,6 @@ end define_output_variable!(dataset, output::WindowedTimeAverage{<:AbstractField}, args...) = define_output_variable!(dataset, output.operand, args...) - ##### ##### Write output ##### @@ -750,7 +754,8 @@ function initialize_nc_file!(filepath, array_type, deflatelevel, attributes, - dimensions) + dimensions, + filepath) # for better error messages end sync(dataset) diff --git a/test/test_output_writers.jl b/test/test_output_writers.jl index bd9f56efb3..0b4ee23ee6 100644 --- a/test/test_output_writers.jl +++ b/test/test_output_writers.jl @@ -68,7 +68,11 @@ function test_dependency_adding(model) dimensions = Dict("time_average" => ("xF", "yC", "zC")) # JLD2 dependencies test - jld2_output_writer = JLD2OutputWriter(model, output, schedule=TimeInterval(4), dir=".", filename="test.jld2", overwrite_existing=true) + jld2_output_writer = JLD2OutputWriter(model, output, + schedule = TimeInterval(4), + dir = ".", + filename = "test.jld2", + overwrite_existing = true) windowed_time_average = jld2_output_writer.outputs.time_average @test dependencies_added_correctly!(model, windowed_time_average, jld2_output_writer) @@ -148,7 +152,8 @@ function test_windowed_time_averaging_simulation(model) # https://github.com/Alexander-Barth/NCDatasets.jl/issues/105 nc_filepath1 = "windowed_time_average_test1.nc" nc_outputs = Dict(string(name) => field for (name, field) in pairs(model.velocities)) - nc_output_writer = NetCDFOutputWriter(model, nc_outputs, filename=nc_filepath1, + nc_output_writer = NetCDFOutputWriter(model, nc_outputs, + filename = nc_filepath1, schedule = AveragedTimeInterval(π, window=1)) jld2_outputs_are_time_averaged = Tuple(typeof(out) <: WindowedTimeAverage for out in jld2_output_writer.outputs) @@ -202,8 +207,9 @@ function test_windowed_time_averaging_simulation(model) nc_filepath2 = "windowed_time_average_test2.nc" nc_outputs = Dict(string(name) => field for (name, field) in pairs(model.velocities)) - simulation.output_writers[:nc] = NetCDFOutputWriter(model, nc_outputs, filename=nc_filepath2, - schedule=AveragedTimeInterval(π, window=π)) + simulation.output_writers[:nc] = NetCDFOutputWriter(model, nc_outputs, + filename = nc_filepath2, + schedule = AveragedTimeInterval(π, window=π)) run!(simulation) From c4357e575a89399b92d81ff5b089b25aa8da55cd Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Wed, 8 May 2024 13:38:05 -0600 Subject: [PATCH 17/21] Correctly define_output_variable for LagrangianParticles --- src/OutputWriters/netcdf_output_writer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index b8bae8acc1..2bcb50f009 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -641,7 +641,7 @@ end """ Defines empty variable for particle trackting. """ function define_output_variable!(dataset, output::LagrangianParticles, name, array_type, - deflatelevel, output_attributes, dimensions) + deflatelevel, output_attributes, dimensions, filepath) particle_fields = eltype(output.properties) |> fieldnames .|> string T = eltype(array_type) From aa5e65cbf1761e6062ca6aa72eaeba79afca5c2a Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 9 May 2024 10:54:40 -0600 Subject: [PATCH 18/21] Fix znodes in output writers docs --- docs/src/model_setup/output_writers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index aa894431a6..ab83275376 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -122,7 +122,7 @@ simulation = Simulation(model, Δt=1.25, stop_iteration=3) f(model) = model.clock.time^2; # scalar output -g(model) = model.clock.time .* exp.(znodes(Center, grid)) # single-column profile output (vector) +g(model) = model.clock.time .* exp.(znodes(grid, Center())) # single-column profile output (vector) xC, yF = xnodes(grid, Center()), ynodes(grid, Face()) From ab73354c24a459e5626477281d742c27a27c7a5f Mon Sep 17 00:00:00 2001 From: Iury Simoes-Sousa Date: Thu, 9 May 2024 15:04:53 -0400 Subject: [PATCH 19/21] fix znodes --- src/OutputWriters/netcdf_output_writer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index 2bcb50f009..bbaa6f3bf1 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -326,7 +326,7 @@ simulation = Simulation(model, Δt=1.25, stop_iteration=3) f(model) = model.clock.time^2; # scalar output -g(model) = model.clock.time .* exp.(znodes(Center, grid)) # vector/profile output +g(model) = model.clock.time .* exp.(znodes(grid, Center())) # vector/profile output xC, yF = xnodes(grid, Center()), ynodes(grid, Face()) From a3a2f7ecc33053f809212ddb6347e7b2fd9f67d8 Mon Sep 17 00:00:00 2001 From: Iury Simoes-Sousa Date: Thu, 9 May 2024 15:07:40 -0400 Subject: [PATCH 20/21] fix double semicolon --- docs/src/model_setup/output_writers.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index ab83275376..49bf6045c9 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -175,7 +175,8 @@ coarse_u = Field{Face, Center, Center}(coarse_grid) interpolate_u(model) = interpolate!(coarse_u, model.velocities.u) outputs = (; u = interpolate_u) -output_writer = NetCDFOutputWriter(model, outputs; grid = coarse_grid; +output_writer = NetCDFOutputWriter(model, outputs; + grid = coarse_grid, filename = "coarse_u.nc", schedule = IterationInterval(1)) From 4850ddc8777d1d46f1e099640468258884795180 Mon Sep 17 00:00:00 2001 From: Gregory Wagner Date: Thu, 9 May 2024 17:27:04 -0600 Subject: [PATCH 21/21] 14.5 kB --- docs/src/model_setup/output_writers.md | 2 +- src/OutputWriters/netcdf_output_writer.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/model_setup/output_writers.md b/docs/src/model_setup/output_writers.md index 49bf6045c9..98f78cbb07 100644 --- a/docs/src/model_setup/output_writers.md +++ b/docs/src/model_setup/output_writers.md @@ -187,7 +187,7 @@ NetCDFOutputWriter scheduled on IterationInterval(1): ├── 1 outputs: u └── array type: Array{Float64} ├── file_splitting: NoFileSplitting -└── file size: 14.6 KiB +└── file size: 14.5 KiB ``` See [`NetCDFOutputWriter`](@ref) for more information. diff --git a/src/OutputWriters/netcdf_output_writer.jl b/src/OutputWriters/netcdf_output_writer.jl index bbaa6f3bf1..56d328296b 100644 --- a/src/OutputWriters/netcdf_output_writer.jl +++ b/src/OutputWriters/netcdf_output_writer.jl @@ -391,7 +391,7 @@ NetCDFOutputWriter scheduled on IterationInterval(1): ├── 1 outputs: u └── array type: Array{Float64} ├── file_splitting: NoFileSplitting -└── file size: 14.6 KiB +└── file size: 14.5 KiB ``` """ function NetCDFOutputWriter(model, outputs;