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

Refactor of spacings and correction of spacings-connected bugs #3955

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b19461b
small correction
simone-silvestri Nov 23, 2024
73b9b4a
correction
simone-silvestri Nov 23, 2024
1c1dea3
add a test
simone-silvestri Nov 23, 2024
7e5b287
weird
simone-silvestri Nov 23, 2024
b578440
introduce an error for dz
simone-silvestri Nov 23, 2024
63c374f
bugfix
simone-silvestri Nov 23, 2024
9d29ac6
Merge branch 'main' into ss/correct-spacing
simone-silvestri Nov 23, 2024
93e6305
improve grid metrics
simone-silvestri Nov 25, 2024
da88ed2
remove ψspacing...
simone-silvestri Nov 25, 2024
e129e21
remove `AbstractMetric`
simone-silvestri Nov 25, 2024
11ac809
better formatting
simone-silvestri Nov 25, 2024
ed636bc
continue with the spacings
simone-silvestri Nov 25, 2024
20c94d6
a bit of cleanup in the operators
simone-silvestri Nov 25, 2024
c495dd0
comment
simone-silvestri Nov 25, 2024
5f04304
fixes
simone-silvestri Nov 25, 2024
81db44b
last one
simone-silvestri Nov 25, 2024
3c37ee4
simplification
simone-silvestri Nov 25, 2024
235948a
Merge branch 'main' into ss/correct-spacing
simone-silvestri Nov 25, 2024
ae6ddeb
coorect import
simone-silvestri Nov 25, 2024
e1453f5
Merge branch 'ss/correct-spacing' of github.com:CliMA/Oceananigans.jl…
simone-silvestri Nov 25, 2024
ed5ef27
correct areas
simone-silvestri Nov 25, 2024
57890ec
better naming
simone-silvestri Nov 25, 2024
64235b9
correct grid metric
simone-silvestri Nov 25, 2024
5d030f1
space
simone-silvestri Nov 25, 2024
33ad600
bugfix
simone-silvestri Nov 25, 2024
5941eb6
correct 3D vertical areas
simone-silvestri Nov 25, 2024
35a8504
another bugfix
simone-silvestri Nov 25, 2024
75b5a13
remove all spacing functions
simone-silvestri Nov 25, 2024
cdaf207
tests should pass now
simone-silvestri Nov 25, 2024
2f924f8
correct bottom height
simone-silvestri Nov 25, 2024
b7a7971
fix tests
simone-silvestri Nov 25, 2024
9d2df2f
fix example
simone-silvestri Nov 26, 2024
70f0bbf
export the verbose versions
simone-silvestri Nov 27, 2024
da22227
revert partial cell bottom
simone-silvestri Nov 27, 2024
8cb1fc1
bugfix
simone-silvestri Nov 27, 2024
6d7f435
fix tests
simone-silvestri Nov 28, 2024
653b672
Update spacings_and_areas_and_volumes.jl
simone-silvestri Nov 29, 2024
01c0e4a
fix docstrings
navidcy Nov 30, 2024
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: 2 additions & 0 deletions src/AbstractOperations/binary_operations.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Oceananigans.Operators

const binary_operators = Set()

struct BinaryOperation{LX, LY, LZ, O, A, B, IA, IB, G, T} <: AbstractOperation{LX, LY, LZ, G, T}
Expand Down
175 changes: 57 additions & 118 deletions src/AbstractOperations/grid_metrics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,69 @@ using Adapt
using Oceananigans.Operators
using Oceananigans.Grids: AbstractGrid
using Oceananigans.Fields: AbstractField, default_indices, location
using Oceananigans.Operators: Δx, Δy, Δz, Ax, Δλ, Δφ, Ay, Az, volume

import Oceananigans.Grids: xspacings, yspacings, zspacings, λspacings, φspacings

abstract type AbstractGridMetric end
const AbstractGridMetric = Union{typeof(Δx),
typeof(Δy),
typeof(Δz),
typeof(Δλ),
typeof(Δφ),
typeof(Ax),
typeof(Ay),
typeof(Az),
typeof(volume)} # Do we want it to be `volume` or just `V` like in the Operators module?

struct XSpacingMetric <: AbstractGridMetric end
struct YSpacingMetric <: AbstractGridMetric end
struct ZSpacingMetric <: AbstractGridMetric end
"""
metric_function(loc, metric::AbstractGridMetric)

metric_function_prefix(::XSpacingMetric) = :Δx
metric_function_prefix(::YSpacingMetric) = :Δy
metric_function_prefix(::ZSpacingMetric) = :Δz
Return the function associated with `metric::AbstractGridMetric` at `loc`ation.
"""
function metric_function(loc, metric)
code = Tuple(interpolation_code(ℓ) for ℓ in loc)
if metric isa typeof(volume)
metric_function_symbol = Symbol(:V, code...)
else
metric_function_symbol = Symbol(metric, code...)
end
return getglobal(@__MODULE__, metric_function_symbol)
end

struct XAreaMetric <: AbstractGridMetric end
struct YAreaMetric <: AbstractGridMetric end
struct ZAreaMetric <: AbstractGridMetric end
struct GridMetricOperation{LX, LY, LZ, G, T, M} <: AbstractOperation{LX, LY, LZ, G, T}
metric :: M
grid :: G
function GridMetricOperation{LX, LY, LZ}(metric::M, grid::G) where {LX, LY, LZ, M, G}
T = eltype(grid)
return new{LX, LY, LZ, G, T, M}(metric, grid)
end
end

metric_function_prefix(::XAreaMetric) = :Ax
metric_function_prefix(::YAreaMetric) = :Ay
metric_function_prefix(::ZAreaMetric) = :Az
Adapt.adapt_structure(to, gm::GridMetricOperation{LX, LY, LZ}) where {LX, LY, LZ} =
GridMetricOperation{LX, LY, LZ}(Adapt.adapt(to, gm.metric),
Adapt.adapt(to, gm.grid))

struct VolumeMetric <: AbstractGridMetric end
on_architecture(to, gm::GridMetricOperation{LX, LY, LZ}) where {LX, LY, LZ} =
GridMetricOperation{LX, LY, LZ}(on_architecture(to, gm.metric),
on_architecture(to, gm.grid))

metric_function_prefix(::VolumeMetric) = :V
@inline Base.getindex(gm::GridMetricOperation, i, j, k) = gm.metric(i, j, k, gm.grid)

# Convenient instances for users
const Δx = XSpacingMetric()
const Δy = YSpacingMetric()
indices(::GridMetricOperation) = default_indices(3)

"""
Δz = ZSpacingMetric()
GridMetricOperation(L, metric, grid)

Instance of `ZSpacingMetric` that generates `BinaryOperation`s
between `AbstractField`s and the vertical grid spacing evaluated
Instance of `GridMetricOperation` that generates `BinaryOperation`s between `AbstractField`s and the metric `metric`
at the same location as the `AbstractField`.

`Δx` and `Δy` play a similar role for horizontal grid spacings.

Example
=======

```jldoctest

julia> using Oceananigans

julia> using Oceananigans.AbstractOperations: Δz
julia> using Oceananigans.Operators: Δz

julia> c = CenterField(RectilinearGrid(size=(1, 1, 1), extent=(1, 2, 3)));

Expand All @@ -55,94 +73,15 @@ BinaryOperation at (Center, Center, Center)
├── grid: 1×1×1 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 1×1×1 halo
└── tree:
* at (Center, Center, Center)
   ├── 1×1×1 Field{Center, Center, Center} on RectilinearGrid on CPU
   └── Δzᶜᶜᶜ at (Center, Center, Center)
   ├── 1×1×1 Field{Center, Center, Center} on RectilinearGrid on CPU
   └── Δzᶜᶜᶜ at (Center, Center, Center)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this missing a space


julia> c .= 1;

julia> c_dz[1, 1, 1]
3.0
```
"""
const Δz = ZSpacingMetric()

const Ax = XAreaMetric()
const Ay = YAreaMetric()
const Az = ZAreaMetric()

"""
volume = VolumeMetric()

Instance of `VolumeMetric` that generates `BinaryOperation`s
between `AbstractField`s and their cell volumes. Summing
this `BinaryOperation` yields an integral of `AbstractField`
over the domain.

Example
=======

```jldoctest
julia> using Oceananigans

julia> using Oceananigans.AbstractOperations: volume

julia> c = CenterField(RectilinearGrid(size=(2, 2, 2), extent=(1, 2, 3)));

julia> c .= 1;

julia> c_dV = c * volume
BinaryOperation at (Center, Center, Center)
├── grid: 2×2×2 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 2×2×2 halo
└── tree:
* at (Center, Center, Center)
   ├── 2×2×2 Field{Center, Center, Center} on RectilinearGrid on CPU
   └── Vᶜᶜᶜ at (Center, Center, Center)

julia> c_dV[1, 1, 1]
0.75

julia> sum(c_dV)
6.0
```
"""
const volume = VolumeMetric()

"""
metric_function(loc, metric::AbstractGridMetric)

Return the function associated with `metric::AbstractGridMetric`
at `loc`ation.
"""
function metric_function(loc, metric::AbstractGridMetric)
code = Tuple(interpolation_code(ℓ) for ℓ in loc)
prefix = metric_function_prefix(metric)
metric_function_symbol = Symbol(prefix, code...)
return getglobal(@__MODULE__, metric_function_symbol)
end

struct GridMetricOperation{LX, LY, LZ, G, T, M} <: AbstractOperation{LX, LY, LZ, G, T}
metric :: M
grid :: G
function GridMetricOperation{LX, LY, LZ}(metric::M, grid::G) where {LX, LY, LZ, M, G}
T = eltype(grid)
return new{LX, LY, LZ, G, T, M}(metric, grid)
end
end

Adapt.adapt_structure(to, gm::GridMetricOperation{LX, LY, LZ}) where {LX, LY, LZ} =
GridMetricOperation{LX, LY, LZ}(Adapt.adapt(to, gm.metric),
Adapt.adapt(to, gm.grid))

on_architecture(to, gm::GridMetricOperation{LX, LY, LZ}) where {LX, LY, LZ} =
GridMetricOperation{LX, LY, LZ}(on_architecture(to, gm.metric),
on_architecture(to, gm.grid))


@inline Base.getindex(gm::GridMetricOperation, i, j, k) = gm.metric(i, j, k, gm.grid)

indices(::GridMetricOperation) = default_indices(3)

# Special constructor for BinaryOperation
GridMetricOperation(L, metric, grid) = GridMetricOperation{L[1], L[2], L[3]}(metric_function(L, metric), grid)

#####
Expand All @@ -165,13 +104,13 @@ julia> grid = RectilinearGrid(size=(2, 4, 8), extent=(1, 1, 1));
julia> xspacings(grid, Center(), Center(), Center())
KernelFunctionOperation at (Center, Center, Center)
├── grid: 2×4×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 2×3×3 halo
├── kernel_function: xspacing (generic function with 27 methods)
├── kernel_function: Δx (generic function with 27 methods)
└── arguments: ("Center", "Center", "Center")
```
"""
function xspacings(grid, ℓx, ℓy, ℓz)
LX, LY, LZ = map(typeof, (ℓx, ℓy, ℓz))
Δx_op = KernelFunctionOperation{LX, LY, LZ}(xspacing, grid, ℓx, ℓy, ℓz)
Δx_op = KernelFunctionOperation{LX, LY, LZ}(Δx, grid, ℓx, ℓy, ℓz)
return Δx_op
end

Expand All @@ -191,13 +130,13 @@ julia> grid = RectilinearGrid(size=(2, 4, 8), extent=(1, 1, 1));
julia> yspacings(grid, Center(), Face(), Center())
KernelFunctionOperation at (Center, Face, Center)
├── grid: 2×4×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 2×3×3 halo
├── kernel_function: yspacing (generic function with 27 methods)
├── kernel_function: Δy (generic function with 27 methods)
└── arguments: ("Center", "Face", "Center")
```
"""
function yspacings(grid, ℓx, ℓy, ℓz)
LX, LY, LZ = map(typeof, (ℓx, ℓy, ℓz))
Δy_op = KernelFunctionOperation{LX, LY, LZ}(yspacing, grid, ℓx, ℓy, ℓz)
Δy_op = KernelFunctionOperation{LX, LY, LZ}(Δy, grid, ℓx, ℓy, ℓz)
return Δy_op
end

Expand All @@ -217,21 +156,21 @@ julia> grid = RectilinearGrid(size=(2, 4, 8), extent=(1, 1, 1));
julia> zspacings(grid, Center(), Center(), Face())
KernelFunctionOperation at (Center, Center, Face)
├── grid: 2×4×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 2×3×3 halo
├── kernel_function: zspacing (generic function with 27 methods)
├── kernel_function: Δz (generic function with 27 methods)
└── arguments: ("Center", "Center", "Face")
```
"""
function zspacings(grid, ℓx, ℓy, ℓz)
LX, LY, LZ = map(typeof, (ℓx, ℓy, ℓz))
Δz_op = KernelFunctionOperation{LX, LY, LZ}(zspacing, grid, ℓx, ℓy, ℓz)
Δz_op = KernelFunctionOperation{LX, LY, LZ}(Δz, grid, ℓx, ℓy, ℓz)
return Δz_op
end

"""
λspacings(grid, ℓx, ℓy, ℓz)

Return a `KernelFunctionOperation` that computes the grid spacings for `grid`
in the ``z`` direction at location `ℓx, ℓy, ℓz`.
in the ``λ`` direction at location `ℓx, ℓy, ℓz`.

Examples
========
Expand All @@ -246,21 +185,21 @@ julia> grid = LatitudeLongitudeGrid(size=(36, 34, 25),
julia> λspacings(grid, Center(), Face(), Center())
KernelFunctionOperation at (Center, Face, Center)
├── grid: 36×34×25 LatitudeLongitudeGrid{Float64, Periodic, Bounded, Bounded} on CPU with 3×3×3 halo and with precomputed metrics
├── kernel_function: λspacing (generic function with 5 methods)
├── kernel_function: Δλ (generic function with 5 methods)
└── arguments: ("Center", "Face", "Center")
```
"""
function λspacings(grid, ℓx, ℓy, ℓz)
LX, LY, LZ = map(typeof, (ℓx, ℓy, ℓz))
Δλ_op = KernelFunctionOperation{LX, LY, LZ}(λspacing, grid, ℓx, ℓy, ℓz)
Δλ_op = KernelFunctionOperation{LX, LY, LZ}(Δλ, grid, ℓx, ℓy, ℓz)
return Δλ_op
end

"""
φspacings(grid, ℓx, ℓy, ℓz)

Return a `KernelFunctionOperation` that computes the grid spacings for `grid`
in the ``z`` direction at location `ℓx, ℓy, ℓz`.
in the ``φ`` direction at location `ℓx, ℓy, ℓz`.

Examples
========
Expand All @@ -275,13 +214,13 @@ julia> grid = LatitudeLongitudeGrid(size=(36, 34, 25),
julia> φspacings(grid, Center(), Face(), Center())
KernelFunctionOperation at (Center, Face, Center)
├── grid: 36×34×25 LatitudeLongitudeGrid{Float64, Periodic, Bounded, Bounded} on CPU with 3×3×3 halo and with precomputed metrics
├── kernel_function: φspacing (generic function with 5 methods)
├── kernel_function: Δφ (generic function with 5 methods)
└── arguments: ("Center", "Face", "Center")
```
"""
function φspacings(grid, ℓx, ℓy, ℓz)
LX, LY, LZ = map(typeof, (ℓx, ℓy, ℓz))
Δφ_op = KernelFunctionOperation{LX, LY, LZ}(φspacing, grid, ℓx, ℓy, ℓz)
Δφ_op = KernelFunctionOperation{LX, LY, LZ}(Δφ, grid, ℓx, ℓy, ℓz)
return Δφ_op
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Oceananigans.Grids: xspacing, yspacing, zspacing
using Oceananigans.Operators: Δx, Δy, Δz

"""
FlatExtrapolation
Expand Down Expand Up @@ -62,9 +62,9 @@ end
const c = Center()

@inline function _fill_west_open_halo!(j, k, grid, ϕ, bc::FEOBC, loc, clock, model_fields)
Δx₁ = xspacing(1, j, k, grid, c, c, c)
Δx₂ = xspacing(2, j, k, grid, c, c, c)
Δx₃ = xspacing(3, j, k, grid, c, c, c)
Δx₁ = Δx(1, j, k, grid, c, c, c)
Δx₂ = Δx(2, j, k, grid, c, c, c)
Δx₃ = Δx(3, j, k, grid, c, c, c)

spacing_factor = Δx₁ / (Δx₂ + Δx₃)

Expand All @@ -78,9 +78,9 @@ end
@inline function _fill_east_open_halo!(j, k, grid, ϕ, bc::FEOBC, loc, clock, model_fields)
i = grid.Nx + 1

Δx₁ = xspacing(i-1, j, k, grid, c, c, c)
Δx₂ = xspacing(i-2, j, k, grid, c, c, c)
Δx₃ = xspacing(i-3, j, k, grid, c, c, c)
Δx₁ = Δx(i-1, j, k, grid, c, c, c)
Δx₂ = Δx(i-2, j, k, grid, c, c, c)
Δx₃ = Δx(i-3, j, k, grid, c, c, c)

spacing_factor = Δx₁ / (Δx₂ + Δx₃)

Expand All @@ -92,9 +92,9 @@ end
end

@inline function _fill_south_open_halo!(i, k, grid, ϕ, bc::FEOBC, loc, clock, model_fields)
Δy₁ = yspacing(i, 1, k, grid, c, c, c)
Δy₂ = yspacing(i, 2, k, grid, c, c, c)
Δy₃ = yspacing(i, 3, k, grid, c, c, c)
Δy₁ = Δy(i, 1, k, grid, c, c, c)
Δy₂ = Δy(i, 2, k, grid, c, c, c)
Δy₃ = Δy(i, 3, k, grid, c, c, c)

spacing_factor = Δy₁ / (Δy₂ + Δy₃)

Expand All @@ -108,9 +108,9 @@ end
@inline function _fill_north_open_halo!(i, k, grid, ϕ, bc::FEOBC, loc, clock, model_fields)
j = grid.Ny + 1

Δy₁ = yspacing(i, j-1, k, grid, c, c, c)
Δy₂ = yspacing(i, j-2, k, grid, c, c, c)
Δy₃ = yspacing(i, j-3, k, grid, c, c, c)
Δy₁ = Δy(i, j-1, k, grid, c, c, c)
Δy₂ = Δy(i, j-2, k, grid, c, c, c)
Δy₃ = Δy(i, j-3, k, grid, c, c, c)

spacing_factor = Δy₁ / (Δy₂ + Δy₃)

Expand All @@ -122,9 +122,9 @@ end
end

@inline function _fill_bottom_open_halo!(i, j, grid, ϕ, bc::FEOBC, loc, clock, model_fields)
Δz₁ = zspacing(i, j, 1, grid, c, c, c)
Δz₂ = zspacing(i, j, 2, grid, c, c, c)
Δz₃ = zspacing(i, j, 3, grid, c, c, c)
Δz₁ = Δz(i, j, 1, grid, c, c, c)
Δz₂ = Δz(i, j, 2, grid, c, c, c)
Δz₃ = Δz(i, j, 3, grid, c, c, c)

spacing_factor = Δz₁ / (Δz₂ + Δz₃)

Expand All @@ -138,9 +138,9 @@ end
@inline function _fill_top_open_halo!(i, j, grid, ϕ, bc::FEOBC, loc, clock, model_fields)
k = grid.Nz + 1

Δz₁ = zspacing(i, j, k-1, grid, c, c, c)
Δz₂ = zspacing(i, j, k-2, grid, c, c, c)
Δz₃ = zspacing(i, j, k-3, grid, c, c, c)
Δz₁ = Δz(i, j, k-1, grid, c, c, c)
Δz₂ = Δz(i, j, k-2, grid, c, c, c)
Δz₃ = Δz(i, j, k-3, grid, c, c, c)

spacing_factor = Δz₁ / (Δz₂ + Δz₃)

Expand Down
1 change: 0 additions & 1 deletion src/Grids/Grids.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export ξnode, ηnode, rnode
export xnode, ynode, znode, λnode, φnode
export xnodes, ynodes, znodes, λnodes, φnodes
export spacings
export xspacing, yspacing, zspacing, λspacing, φspacing
export xspacings, yspacings, zspacings, λspacings, φspacings
export minimum_xspacing, minimum_yspacing, minimum_zspacing
export static_column_depthᶜᶜᵃ, static_column_depthᶠᶜᵃ, static_column_depthᶜᶠᵃ, static_column_depthᶠᶠᵃ
Expand Down
Loading