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

Completely overhaul grid utils + min_Δx/y/z -> minimum_spacing + move x/y/zspacing to Grids #2991

Merged
merged 39 commits into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ad2d638
min_Δx/y/z -> minimum_spacing + move x/y/zspacing to Grids
navidcy Mar 21, 2023
67614bd
cleaner min_Δz for diffusive model
navidcy Mar 21, 2023
c89a30f
Completely overhaul grid utils
glwagner Mar 16, 2023
2165f2d
remove duplicates
navidcy Mar 21, 2023
4101a3f
no fallback for total_length
navidcy Mar 16, 2023
a9a0e01
Marie Kondo comes to Oceananigans
glwagner Mar 21, 2023
41be8df
new args for minimum_xyzspacing
navidcy Mar 21, 2023
fb4bb2a
use minimum_zspacing
navidcy Mar 21, 2023
4fa2d38
more docstrings
navidcy Mar 21, 2023
01b116f
use new total_size
navidcy Mar 21, 2023
5e903ea
export minimum xyzspacing
navidcy Mar 21, 2023
b026ede
fix tests
navidcy Mar 21, 2023
4a0d75d
some fixes
navidcy Mar 22, 2023
153ae03
move validate_mode_halo in Models + fix tests
navidcy Mar 22, 2023
2d54f82
Merge branch 'main' into ncc/miminum_spacing
navidcy Mar 22, 2023
b9156a6
instantiate more
navidcy Mar 22, 2023
ff2d992
Merge branch 'ncc/miminum_spacing' of github.com:CliMA/Oceananigans.j…
navidcy Mar 22, 2023
cdb6762
more fixes
navidcy Mar 22, 2023
b362d6b
fix fix fix
navidcy Mar 22, 2023
42630b3
some more fixes
navidcy Mar 22, 2023
334f417
more fix
navidcy Mar 22, 2023
21c7565
fix fix fix
navidcy Mar 22, 2023
8d3c0d1
fixes
navidcy Mar 22, 2023
bba6448
fix
navidcy Mar 22, 2023
9cc7205
more fixes
navidcy Mar 22, 2023
4291703
more fixes
navidcy Mar 22, 2023
ef8f344
more fixes
navidcy Mar 22, 2023
58f08b7
remove stray ]
navidcy Mar 22, 2023
e88a10b
back to normal
navidcy Mar 22, 2023
50c0f93
simpler minΔz
navidcy Mar 22, 2023
3c251d3
more instantiations
navidcy Mar 22, 2023
5272106
compute Nx/y_source_faces outside of kernel
navidcy Mar 22, 2023
bc32818
eliminate ::Type{Nothing}
navidcy Mar 22, 2023
997b55f
add allowscalar in equality between grids
navidcy Mar 22, 2023
531e62a
some more instantiations
navidcy Mar 22, 2023
c5cc7ad
ensure that figures are shown in docs
navidcy Mar 22, 2023
e764b13
fix mistake
navidcy Mar 23, 2023
2ddb509
Merge branch 'main' into ncc/miminum_spacing
glwagner Mar 23, 2023
34ec39a
Merge branch 'main' into ncc/miminum_spacing
navidcy Mar 23, 2023
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
4 changes: 2 additions & 2 deletions examples/one_dimensional_diffusion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ current_figure() # hide
# Next we set-up a `Simulation` that time-steps the model forward and manages output.

## Time-scale for diffusion across a grid cell
using Oceananigans.Grids: min_Δz
diffusion_time_scale = min_Δz(model.grid)^2 / model.closure.κ.T
min_Δz = minimum_spacing(:z, (Face, Face, Face), model.grid)
diffusion_time_scale = min_Δz^2 / model.closure.κ.T

simulation = Simulation(model, Δt = 0.1 * diffusion_time_scale, stop_iteration = 1000)

Expand Down
3 changes: 1 addition & 2 deletions examples/tilted_bottom_boundary_layer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ model = NonhydrostaticModel(; grid, buoyancy, coriolis, closure,
# conservatively, based on the smallest grid size of our domain and set-up a

using Oceananigans.Units
using Oceananigans.Grids: min_Δz

simulation = Simulation(model, Δt = 0.5 * min_Δz(grid) / V∞, stop_time = 2days)
simulation = Simulation(model, Δt = 0.5 * minimum_spacing(:z, (Face, Face, Face), grid) / V∞, stop_time = 2days)

# We use `TimeStepWizard` to adapt our time-step and print a progress message,

Expand Down
1 change: 1 addition & 0 deletions src/Advection/Advection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@ include("topologically_conditional_interpolation.jl")
include("momentum_advection_operators.jl")
include("tracer_advection_operators.jl")
include("positivity_preserving_tracer_advection_operators.jl")
include("cell_advection_timescale.jl")

end # module
18 changes: 18 additions & 0 deletions src/Advection/cell_advection_timescale.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Oceananigans.Grids: topology, min_Δx, min_Δy, min_Δz

function cell_advection_timescale(grid, velocities)
u, v, w = velocities
τ = KernelFunctionOperation{Center, Center, Center}(cell_advection_timescaleᶜᶜᶜ, grid, u, v, w)
return minimum(τ)
end

@inline function cell_advection_timescaleᶜᶜᶜ(i, j, k, grid, u, v, w)
Δx = Δxᶠᶜᶜ(i, j, k, grid)
Δy = Δyᶜᶠᶜ(i, j, k, grid)
Δz = Δzᶜᶜᶠ(i, j, k, grid)

return @inbounds min(Δx / abs(u[i, j, k]),
Δy / abs(v[i, j, k]),
Δz / abs(w[i, j, k]))
end

2 changes: 1 addition & 1 deletion src/Diagnostics/cfl.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Oceananigans.Utils: cell_advection_timescale
using Oceananigans.Advection: cell_advection_timescale
using Oceananigans.TurbulenceClosures: cell_diffusion_timescale

"""
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/abstract_field.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Returns the size of an `AbstractField{LX, LY, LZ}` located at `LX, LY, LZ`.
This is a 3-tuple of integers corresponding to the number of interior nodes
of `f` along `x, y, z`.
"""
Base.size(f::AbstractField) = size(location(f), f.grid)
Base.size(f::AbstractField) = size(f.grid, location(f))
Base.length(f::AbstractField) = prod(size(f))
Base.parent(f::AbstractField) = f

Expand All @@ -63,7 +63,7 @@ Base.parent(f::AbstractField) = f
Returns a 3-tuple that gives the "total" size of a field including
both interior points and halo points.
"""
total_size(f::AbstractField) = total_size(location(f), f.grid)
total_size(f::AbstractField) = total_size(f.grid, location(f))

interior(f::AbstractField) = f

Expand Down
37 changes: 20 additions & 17 deletions src/Fields/field.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ end
#####

function validate_field_data(loc, data, grid, indices)
Fx, Fy, Fz = total_size(loc, grid, indices)
Fx, Fy, Fz = total_size(grid, loc, indices)

if size(data) != (Fx, Fy, Fz)
LX, LY, LZ = loc
Expand Down Expand Up @@ -234,18 +234,20 @@ Return an `OffsetArray` of a `view` of `parent(data)` with `indices`.

If `indices === (:, :, :)`, return an `OffsetArray` of `parent(data)`.
"""
function offset_windowed_data(data, loc, grid, indices)
function offset_windowed_data(data, Loc, grid, indices)
halo = halo_size(grid)
topo = topology(grid)
topo = map(instantiate, topology(grid))
loc = map(instantiate, Loc)

if indices isa typeof(default_indices(3))
windowed_parent = parent(data)
else
parent_indices = parent_index_range.(indices, loc, topo, halo)
parent_indices = map(parent_index_range, indices, loc, topo, halo)
windowed_parent = view(parent(data), parent_indices...)
end

sz = size(grid)

return offset_data(windowed_parent, loc, topo, sz, halo, indices)
end

Expand Down Expand Up @@ -345,9 +347,7 @@ function boundary_conditions(f::Field)
end

immersed_boundary_condition(f::Field) = f.boundary_conditions.immersed

data(field::Field) = field.data

indices(obj, i=default_indices(3)) = i
indices(f::Field, i=default_indices(3)) = f.indices
indices(a::SubArray, i=default_indices(ndims(a))) = a.indices
Expand All @@ -357,15 +357,20 @@ indices(a::OffsetArray, i=default_indices(ndims(a))) = indices(parent(a), i)
interior_view_indices(field_indices, interior_indices) = Colon()
interior_view_indices(::Colon, interior_indices) = interior_indices

instantiate(T::Type) = T()
instantiate(t) = t

function interior(a::OffsetArray,
loc::Tuple,
topo::Tuple,
size::NTuple{N, Int},
halo_size::NTuple{N, Int},
Loc::Tuple,
Topo::Tuple,
sz::NTuple{N, Int},
halo_sz::NTuple{N, Int},
ind::Tuple=default_indices(3)) where N

i_interior = interior_parent_indices.(loc, topo, size, halo_size)
i_view = interior_view_indices.(ind, i_interior)
loc = map(instantiate, Loc)
topo = map(instantiate, Topo)
i_interior = map(interior_parent_indices, loc, topo, sz, halo_sz)
i_view = map(interior_view_indices, ind, i_interior)
return view(parent(a), i_view...)
end

Expand Down Expand Up @@ -399,11 +404,8 @@ Base.fill!(f::Field, val) = fill!(parent(f), val)
Base.parent(f::Field) = parent(f.data)
Adapt.adapt_structure(to, f::Field) = Adapt.adapt(to, f.data)

length_indices(N, i::Colon) = N
length_indices(N, i::UnitRange) = length(i)

total_size(f::Field) = length_indices.(total_size(location(f), f.grid), f.indices)
Base.size(f::Field) = length_indices.( size(location(f), f.grid), f.indices)
total_size(f::Field) = total_size(f.grid, location(f), f.indices)
Base.size(f::Field) = size(f.grid, location(f), f.indices)

==(f::Field, a) = interior(f) == a
==(a, f::Field) = a == interior(f)
Expand Down Expand Up @@ -723,3 +725,4 @@ function fill_halo_regions!(field::Field, args...; kwargs...)

return nothing
end

2 changes: 1 addition & 1 deletion src/Grids/Grids.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export AbstractCurvilinearGrid, AbstractHorizontallyCurvilinearGrid
export LatitudeLongitudeGrid, XRegLatLonGrid, YRegLatLonGrid, ZRegLatLonGrid
export OrthogonalSphericalShellGrid, ConformalCubedSphereGrid
export node, xnode, ynode, znode, xnodes, ynodes, znodes, nodes
export xspacings, yspacings, zspacings
export xspacings, yspacings, zspacings, xspacing, yspacing, zspacing, minimum_spacing
export offset_data, new_data
export on_architecture

Expand Down
37 changes: 19 additions & 18 deletions src/Grids/grid_generation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,21 @@ get_coord_face(coord::Nothing, i) = 1
get_coord_face(coord::Function, i) = coord(i)
get_coord_face(coord::AbstractVector, i) = CUDA.@allowscalar coord[i]

lower_exterior_Δcoordᶠ(topology, Fi, Hcoord) = [Fi[end - Hcoord + i] - Fi[end - Hcoord + i - 1] for i = 1:Hcoord]
lower_exterior_Δcoordᶠ(::Type{<:BoundedTopology}, Fi, Hcoord) = [Fi[2] - Fi[1] for i = 1:Hcoord]
const AT = AbstractTopology
lower_exterior_Δcoordᶠ(::AT, Fi, Hcoord) = [Fi[end - Hcoord + i] - Fi[end - Hcoord + i - 1] for i = 1:Hcoord]
lower_exterior_Δcoordᶠ(::BoundedTopology, Fi, Hcoord) = [Fi[2] - Fi[1] for i = 1:Hcoord]

upper_exterior_Δcoordᶠ(topology, Fi, Hcoord) = [Fi[i + 1] - Fi[i] for i = 1:Hcoord]
upper_exterior_Δcoordᶠ(::Type{<:BoundedTopology}, Fi, Hcoord) = [Fi[end] - Fi[end - 1] for i = 1:Hcoord]
upper_exterior_Δcoordᶠ(::AT, Fi, Hcoord) = [Fi[i + 1] - Fi[i] for i = 1:Hcoord]
upper_exterior_Δcoordᶠ(::BoundedTopology, Fi, Hcoord) = [Fi[end] - Fi[end - 1] for i = 1:Hcoord]

upper_interior_F(topology, coord, Δ) = coord - Δ
upper_interior_F(::Type{<:BoundedTopology}, coord) = coord
upper_interior_F(::AT, coord, Δ) = coord - Δ
upper_interior_F(::BoundedTopology, coord) = coord

total_interior_length(topology, N) = N
total_interior_length(::Type{<:BoundedTopology}, N) = N + 1
total_interior_length(::AT, N) = N
total_interior_length(::BoundedTopology, N) = N + 1

# generate a stretched coordinate passing the explicit coord faces as vector of functionL
function generate_coordinate(FT, topology, N, H, coord, arch)
function generate_coordinate(FT, topo::AT, N, H, coord, arch)

# Ensure correct type for F and derived quantities
interiorF = zeros(FT, N+1)
Expand All @@ -37,8 +38,8 @@ function generate_coordinate(FT, topology, N, H, coord, arch)
L = interiorF[N+1] - interiorF[1]

# Build halo regions
Δᶠ₋ = lower_exterior_Δcoordᶠ(topology, interiorF, H)
Δᶠ₊ = reverse(upper_exterior_Δcoordᶠ(topology, interiorF, H))
Δᶠ₋ = lower_exterior_Δcoordᶠ(topo, interiorF, H)
Δᶠ₊ = reverse(upper_exterior_Δcoordᶠ(topo, interiorF, H))

c¹, cᴺ⁺¹ = interiorF[1], interiorF[N+1]

Expand All @@ -48,12 +49,12 @@ function generate_coordinate(FT, topology, N, H, coord, arch)
F = vcat(F₋, interiorF, F₊)

# Build cell centers, cell center spacings, and cell interface spacings
TC = total_length(Center, topology, N, H)
TC = total_length(Center(), topo, N, H)
C = [ (F[i + 1] + F[i]) / 2 for i = 1:TC ]
Δᶠ = [ C[i] - C[i - 1] for i = 2:TC ]

# Trim face locations for periodic domains
TF = total_length(Face, topology, N, H)
TF = total_length(Face(), topo, N, H)
F = F[1:TF]

Δᶜ = [F[i + 1] - F[i] for i = 1:TF-1]
Expand All @@ -77,7 +78,7 @@ function generate_coordinate(FT, topology, N, H, coord, arch)
end

# generate a regular coordinate passing the domain extent (2-tuple) and number of points
function generate_coordinate(FT, topology, N, H, coord::Tuple{<:Number, <:Number}, arch)
function generate_coordinate(FT, topo::AT, N, H, coord::Tuple{<:Number, <:Number}, arch)

@assert length(coord) == 2

Expand All @@ -89,13 +90,13 @@ function generate_coordinate(FT, topology, N, H, coord::Tuple{<:Number, <:Number
Δᶠ = Δᶜ = Δ = L / N

F₋ = c₁ - H * Δ
F₊ = F₋ + total_extent(topology, H, Δ, L)
F₊ = F₋ + total_extent(topo, H, Δ, L)

C₋ = F₋ + Δ / 2
C₊ = C₋ + L + Δ * (2H - 1)

TF = total_length(Face, topology, N, H)
TC = total_length(Center, topology, N, H)
TF = total_length(Face(), topo, N, H)
TC = total_length(Center(), topo, N, H)

F = range(FT(F₋), FT(F₊), length = TF)
C = range(FT(C₋), FT(C₊), length = TC)
Expand All @@ -107,6 +108,6 @@ function generate_coordinate(FT, topology, N, H, coord::Tuple{<:Number, <:Number
end

# Flat domains
function generate_coordinate(FT, ::Type{Flat}, N, H, coord::Tuple{<:Number, <:Number}, arch)
function generate_coordinate(FT, ::Flat, N, H, coord::Tuple{<:Number, <:Number}, arch)
return FT(1), range(1, 1, length=N), range(1, 1, length=N), FT(1), FT(1)
end
Loading