Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time averaging and FieldSlicer for NetCDFOutputWriter #1040

Merged
merged 36 commits into from
Oct 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
aee75a5
Teach Oceananigans about plural nouns
ali-ramadhan Oct 9, 2020
07be141
`filename` -> `filepath`
ali-ramadhan Oct 11, 2020
71213a9
More test sets for output writer tests
ali-ramadhan Oct 11, 2020
bb6aaf8
Refactor `NetCDFOutputWriter` to use `FieldSlicer`
ali-ramadhan Oct 11, 2020
f05e8fb
Fix `JLD2OutputWriter` docstring
ali-ramadhan Oct 12, 2020
b246e8d
`FieldSlicer.with_halos` should always be `Bool`
ali-ramadhan Oct 12, 2020
10718e6
Clean up `test_output_writers.jl`
ali-ramadhan Oct 12, 2020
b6e12d9
More thorough cleanup
ali-ramadhan Oct 12, 2020
ec3ccb3
Add time-averaging capability to `NetCDFOutputWriter`
ali-ramadhan Oct 12, 2020
fa647fd
Add missing exports and reorganize
ali-ramadhan Oct 12, 2020
fb0a90e
Test element type of NetCDF output
ali-ramadhan Oct 12, 2020
49d6b1d
Add useful metadata about intervals and time averaging
ali-ramadhan Oct 12, 2020
d516e53
Merge branch 'ar/moar-units' into ar/update-netcdf
ali-ramadhan Oct 12, 2020
2a4405e
Smarter `prettytime`
ali-ramadhan Oct 12, 2020
44b02ec
Test `prettytime`
ali-ramadhan Oct 12, 2020
3f3d47a
`dropdims` before saving `AveragedField` to NetCDF
ali-ramadhan Oct 12, 2020
ed43b09
Need to compute `AveragedField` at t = 0
ali-ramadhan Oct 12, 2020
fb21472
Test NetCDF time averaging
ali-ramadhan Oct 12, 2020
f18f6c9
Test strided windowed time average against analytic solution
ali-ramadhan Oct 12, 2020
1d66469
Couple of last fixes
ali-ramadhan Oct 12, 2020
9ec3e93
Poor NetCDF
ali-ramadhan Oct 12, 2020
2f42c04
Update jldoctests
ali-ramadhan Oct 12, 2020
1c52092
Gotta import prettytime into langmuir_turbulence.jl:
ali-ramadhan Oct 12, 2020
b6bbf5e
Merge branch 'master' into ar/update-netcdf
ali-ramadhan Oct 14, 2020
8519b7b
Update docstring
ali-ramadhan Oct 14, 2020
7e21545
Update jldoctests
ali-ramadhan Oct 14, 2020
dd6914e
Nuke average.jl and computations.jl
ali-ramadhan Oct 14, 2020
a24dc0e
Merge branch 'master' into ar/update-netcdf
ali-ramadhan Oct 14, 2020
90a3c14
Fix imports
ali-ramadhan Oct 14, 2020
085e554
More fixes
ali-ramadhan Oct 14, 2020
d7b0728
Nuke redundant tests and more fixes
ali-ramadhan Oct 14, 2020
0d2ea13
Stratified Couette flow fixes
ali-ramadhan Oct 14, 2020
f09c55e
More fixes
ali-ramadhan Oct 14, 2020
8456143
More fixes
ali-ramadhan Oct 14, 2020
67eedb7
Small fix to more fixes
glwagner Oct 14, 2020
1d8c70c
Import prettytime into eady turbulence example
glwagner Oct 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ steps:
- "$SVERDRUP_HOME/julia-$JULIA_VERSION/bin/julia --color=yes --project -e 'using Pkg; Pkg.test()'"
agents:
queue: Oceananigans
architecture: GPU'
architecture: GPU
depends_on: "init_gpu"

- label: "🦍 cpu scripts"
Expand Down
4 changes: 2 additions & 2 deletions docs/src/model_setup/background_fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ model.background_fields.velocities.u
FunctionField located at (Face, Cell, Cell)
├── func: U
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=1, Ny=1, Nz=1)
├── clock: Clock(time=0.000 s, iteration=0)
├── clock: Clock(time=0 seconds, iteration=0)
└── parameters: nothing
```

Expand Down Expand Up @@ -96,6 +96,6 @@ model.background_fields.tracers.b
FunctionField located at (Cell, Cell, Cell)
├── func: B
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=1, Ny=1, Nz=1)
├── clock: Clock(time=0.000 s, iteration=0)
├── clock: Clock(time=0 seconds, iteration=0)
└── parameters: (α = 3.14, N = 1.0, f = 0.1)
```
2 changes: 1 addition & 1 deletion docs/src/model_setup/boundary_conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ julia> T_bcs = TracerBoundaryConditions(grid, top = ValueBoundaryCondition(20),
bottom = GradientBoundaryCondition(0.01));

julia> model = IncompressibleModel(grid=grid, boundary_conditions=(u=u_bcs, T=T_bcs))
IncompressibleModel{CPU, Float64}(time = 0.000 s, iteration = 0)
IncompressibleModel{CPU, Float64}(time = 0 seconds, iteration = 0)
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=16, Ny=16, Nz=16)
├── tracers: (:T, :S)
├── closure: IsotropicDiffusivity{Float64,NamedTuple{(:T, :S),Tuple{Float64,Float64}}}
Expand Down
10 changes: 5 additions & 5 deletions docs/src/model_setup/buoyancy_and_equation_of_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ end
julia> grid = RegularCartesianGrid(size=(64, 64, 64), extent=(1, 1, 1));

julia> model = IncompressibleModel(grid=grid, buoyancy=nothing)
IncompressibleModel{CPU, Float64}(time = 0.000 s, iteration = 0)
IncompressibleModel{CPU, Float64}(time = 0 seconds, iteration = 0)
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=64, Ny=64, Nz=64)
├── tracers: (:T, :S)
├── closure: IsotropicDiffusivity{Float64,NamedTuple{(:T, :S),Tuple{Float64,Float64}}}
Expand All @@ -35,7 +35,7 @@ also pass`tracers = ()` to the model constructor.

```jldoctest buoyancy
julia> model = IncompressibleModel(grid=grid, buoyancy=nothing, tracers=())
IncompressibleModel{CPU, Float64}(time = 0.000 s, iteration = 0)
IncompressibleModel{CPU, Float64}(time = 0 seconds, iteration = 0)
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=64, Ny=64, Nz=64)
├── tracers: ()
├── closure: IsotropicDiffusivity{Float64,NamedTuple{(),Tuple{}}}
Expand All @@ -50,7 +50,7 @@ constructor. Buoyancy `:b` must be included as a tracer, for example,

```jldoctest buoyancy
julia> model = IncompressibleModel(grid=grid, buoyancy=BuoyancyTracer(), tracers=(:b))
IncompressibleModel{CPU, Float64}(time = 0.000 s, iteration = 0)
IncompressibleModel{CPU, Float64}(time = 0 seconds, iteration = 0)
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=64, Ny=64, Nz=64)
├── tracers: (:b,)
├── closure: IsotropicDiffusivity{Float64,NamedTuple{(:b,),Tuple{Float64}}}
Expand All @@ -65,7 +65,7 @@ To evolve temperature $T$ and salinity $S$ and diagnose the buoyancy, you can pa

```jldoctest buoyancy
julia> model = IncompressibleModel(grid=grid, buoyancy=SeawaterBuoyancy())
IncompressibleModel{CPU, Float64}(time = 0.000 s, iteration = 0)
IncompressibleModel{CPU, Float64}(time = 0 seconds, iteration = 0)
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=64, Ny=64, Nz=64)
├── tracers: (:T, :S)
├── closure: IsotropicDiffusivity{Float64,NamedTuple{(:T, :S),Tuple{Float64,Float64}}}
Expand All @@ -86,7 +86,7 @@ SeawaterBuoyancy{Float64}: g = 1.3
└── equation of state: LinearEquationOfState{Float64}: α = 1.67e-04, β = 7.80e-04

julia> model = IncompressibleModel(grid=grid, buoyancy=buoyancy)
IncompressibleModel{CPU, Float64}(time = 0.000 s, iteration = 0)
IncompressibleModel{CPU, Float64}(time = 0 seconds, iteration = 0)
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=64, Ny=64, Nz=64)
├── tracers: (:T, :S)
├── closure: IsotropicDiffusivity{Float64,NamedTuple{(:T, :S),Tuple{Float64,Float64}}}
Expand Down
4 changes: 2 additions & 2 deletions docs/src/model_setup/clock.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ end

```jldoctest
julia> clock = Clock(time=0.0)
Clock{Float64}: time = 0.000 s, iteration = 0, stage = 1
Clock{Float64}: time = 0 seconds, iteration = 0, stage = 1
```

but can be modified to start the model clock at some other time.
For example, passing

```jldoctest
julia> clock = Clock(time=3600.0)
Clock{Float64}: time = 1.000 hr, iteration = 0, stage = 1
Clock{Float64}: time = 1 hour, iteration = 0, stage = 1
```

to the constructor for `IncompressibleModel` causes the simulation
Expand Down
86 changes: 0 additions & 86 deletions docs/src/model_setup/diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,89 +11,3 @@ time or be specified at any later time and appended (or assigned with a key valu
Most diagnostics can be run at specified frequencies (e.g. every 25 time steps) or specified intervals (e.g. every
15 minutes of simulation time). If you'd like to run a diagnostic on demand then do not specify any intervals
(and do not add it to `simulation.diagnostics`).

We describe the [`Average`](@ref) diagnostic in detail below but see the API documentation for other diagnostics such
as [`TimeSeries`](@ref), [`FieldMaximum`](@ref), [`CFL`](@ref), and [`NaNChecker`](@ref).

## Horizontal averages

You can create a horizontal `Average` diagnostic by passing a field to the constructor, e.g.

```@meta
DocTestSetup = quote
using Oceananigans
using Oceananigans.Diagnostics
end
```

```jldoctest
julia> model = IncompressibleModel(grid=RegularCartesianGrid(size=(4, 4, 4), extent=(1, 1, 1)));

julia> T_avg = Average(model.tracers.T, dims=(1, 2));

julia> T_avg(model) # Compute horizontal average of T on demand
1×1×6 Array{Float64,3}:
[:, :, 1] =
0.0

[:, :, 2] =
0.0

[:, :, 3] =
0.0

[:, :, 4] =
0.0

[:, :, 5] =
0.0

[:, :, 6] =
0.0
```

which can then be called on-demand via `T_avg(model)` to return the horizontally averaged temperature. Notice that
halo regions are included in the output of the horizontal average. When running on the GPU you may want it to return
an `Array` instead of a `CuArray` in case you want to save the horizontal average to disk in which case you'd want to
construct it like

```jldoctest
julia> model = IncompressibleModel(grid=RegularCartesianGrid(size=(4, 4, 4), extent=(1, 1, 1)));

julia> T_avg = Average(model.tracers.T, dims=(1, 2), return_type=Array);

julia> T_avg(model) # Will always return an Array
1×1×6 Array{Float64,3}:
[:, :, 1] =
0.0

[:, :, 2] =
0.0

[:, :, 3] =
0.0

[:, :, 4] =
0.0

[:, :, 5] =
0.0

[:, :, 6] =
0.0
```

You can also use pass an abstract operator to take the horizontal average of any diagnosed quantity. For example, to
compute the horizontal average of the vertical component of vorticity:

```julia
model = IncompressibleModel(grid=RegularCartesianGrid(size=(16, 16, 16), extent=(1, 1, 1)))
simulation = Simulation(model, Δt=6, stop_iteration=10)

u, v, w = model.velocities
ζ = ∂x(v) - ∂y(u)
ζ_avg = Average(ζ, dims=(1, 2))
simulation.diagnostics[:vorticity_profile] = ζ_avg
```

See [`Average`](@ref) for more details and options.
10 changes: 5 additions & 5 deletions docs/src/model_setup/output_writers.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ simulation = Simulation(model, Δt=12, stop_time=3600);
fields = Dict("u" => model.velocities.u, "T" => model.tracers.T);

simulation.output_writers[:field_writer] =
NetCDFOutputWriter(model, fields, filename="output_fields.nc", time_interval=60)
NetCDFOutputWriter(model, fields, filepath="output_fields.nc", time_interval=60)

# output
NetCDFOutputWriter (time_interval=60): output_fields.nc
Expand All @@ -38,8 +38,8 @@ NetCDFOutputWriter (time_interval=60): output_fields.nc

```jldoctest netcdf1
simulation.output_writers[:surface_slice_writer] =
NetCDFOutputWriter(model, fields, filename="output_surface_xy_slice.nc",
time_interval=60, zC=grid.Nz, zF=grid.Nz+1)
NetCDFOutputWriter(model, fields, filepath="output_surface_xy_slice.nc",
time_interval=60, field_slicer=FieldSlicer(k=grid.Nz))

# output
NetCDFOutputWriter (time_interval=60): output_surface_xy_slice.nc
Expand Down Expand Up @@ -79,7 +79,7 @@ global_attributes = Dict("location" => "Bay of Fundy", "onions" => 7);

simulation.output_writers[:stuff] =
NetCDFOutputWriter(model, outputs,
iteration_interval=1, filename="stuff.nc", dimensions=dims, verbose=true,
iteration_interval=1, filepath="stuff.nc", dimensions=dims, verbose=true,
global_attributes=global_attributes, output_attributes=output_attributes)

# output
Expand Down Expand Up @@ -114,7 +114,7 @@ function init_save_some_metadata(file, model)
file["parameters/density"] = 1027
end

T_avg = Average(model.tracers.T, dims=(1, 2))
T_avg = AveragedField(model.tracers.T, dims=(1, 2))

outputs = Dict(
:w => model -> model.velocities.u,
Expand Down
4 changes: 2 additions & 2 deletions docs/src/model_setup/tracers.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ end
julia> grid = RegularCartesianGrid(size=(64, 64, 64), extent=(1, 1, 1));

julia> model = IncompressibleModel(grid=grid)
IncompressibleModel{CPU, Float64}(time = 0.000 s, iteration = 0)
IncompressibleModel{CPU, Float64}(time = 0 seconds, iteration = 0)
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=64, Ny=64, Nz=64)
├── tracers: (:T, :S)
├── closure: IsotropicDiffusivity{Float64,NamedTuple{(:T, :S),Tuple{Float64,Float64}}}
Expand Down Expand Up @@ -43,7 +43,7 @@ quantities $C_1$, CO₂, and nitrogen as additional passive tracers you could se

```jldoctest tracers
julia> model = IncompressibleModel(grid=grid, tracers=(:T, :S, :C₁, :CO₂, :nitrogen))
IncompressibleModel{CPU, Float64}(time = 0.000 s, iteration = 0)
IncompressibleModel{CPU, Float64}(time = 0 seconds, iteration = 0)
├── grid: RegularCartesianGrid{Float64, Periodic, Periodic, Bounded}(Nx=64, Ny=64, Nz=64)
├── tracers: (:T, :S, :C₁, :CO₂, :nitrogen)
├── closure: IsotropicDiffusivity{Float64,NamedTuple{(:T, :S, :C₁, :CO₂, :nitrogen),NTuple{5,Float64}}}
Expand Down
5 changes: 3 additions & 2 deletions examples/eady_turbulence.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,11 @@
# | $ κ_z $ | Laplacian vertical diffusivity | $ 10^{-2} $ | $ \mathrm{m^2 s^{-1}} $ |
# | $ \varkappa_h $ | Biharmonic horizontal diffusivity | $ 10^{-2} \times \Delta x^4 / \mathrm{day} $ | $ \mathrm{m^4 s^{-1}} $ |
#
# We start off by importing `Oceananigans` and some convenient aliases for dimensions:
# We start off by importing `Oceananigans`, some convenient aliases for dimensions, and a function
# that generates a pretty string from a number that represents 'time' in seconds:

using Oceananigans, Printf
using Oceananigans.Utils: hour, day
using Oceananigans.Utils: hour, day, prettytime

# ## The grid
#
Expand Down
1 change: 1 addition & 0 deletions examples/langmuir_turbulence.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ nothing # hide
# maximum absolute value of $u, v, w$ and the current wall clock time.

using Oceananigans.Diagnostics, Printf
using Oceananigans.Utils: prettytime

umax = FieldMaximum(abs, model.velocities.u)
vmax = FieldMaximum(abs, model.velocities.v)
Expand Down
4 changes: 1 addition & 3 deletions src/AbstractOperations/AbstractOperations.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module AbstractOperations

export ∂x, ∂y, ∂z, @at, Computation, compute!, @unary, @binary, @multiary
export ∂x, ∂y, ∂z, @at, @unary, @binary, @multiary

using Base: @propagate_inbounds

Expand All @@ -20,7 +20,6 @@ using Oceananigans.Fields: gpufriendly
using Oceananigans.Operators: interpolation_operator
using Oceananigans.Architectures: device
using Oceananigans.Models: AbstractModel
using Oceananigans.Diagnostics: Average, normalize_sum!

import Oceananigans.Architectures: architecture
import Oceananigans.Fields: data, compute!
Expand Down Expand Up @@ -52,7 +51,6 @@ include("binary_operations.jl")
include("multiary_operations.jl")
include("derivatives.jl")

include("computations.jl")
include("show_abstract_operations.jl")
include("averages_of_operations.jl")

Expand Down
Loading