Skip to content

Commit

Permalink
Grid cell average bug fixes (#673)
Browse files Browse the repository at this point in the history
* grid cell average bug fixes

* changelog updated
  • Loading branch information
milankl authored Feb 11, 2025
1 parent 898f997 commit e43d3a7
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Fix grid_cell_average! bugs for some grids and resolutions [#673](https://github.com/SpeedyWeather/SpeedyWeather.jl/pull/673)
- Interfaces for interpolation of AbstractGridArray [#671](https://github.com/SpeedyWeather/SpeedyWeather.jl/pull/671)
- Test folder sorted into subfolders [#671](https://github.com/SpeedyWeather/SpeedyWeather.jl/pull/671)
- Land model modularised + land netCDF output [#671](https://github.com/SpeedyWeather/SpeedyWeather.jl/pull/671)
Expand Down
12 changes: 8 additions & 4 deletions src/RingGrids/interpolation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -533,24 +533,28 @@ function grid_cell_average!(
j1 = findlast( θ -> θ < θ1, colat_in)

for ij in ring
ϕ0 = mod(lons_out[ij] - Δϕ/2, 2π) # western edge
ϕ0 = mod(lons_out[ij] - Δϕ/2, 2π) # western edge
ϕ1 = ϕ0 + Δϕ # eastern edge
# the last line does not require a mod and in fact throws
# an error if, as long as the offset from prime meridian
# is at most Δϕ/2 (true for HEALPixGrids, offset 0 for
# Gaussian and Clenshaw grids)

# matrix indices for input grid that lie in output grid cell
a = findfirst-> ϕ >= ϕ0, lon_in)
b = findlast( ϕ -> ϕ < ϕ1, lon_in)
a = findlast( ϕ -> ϕ < ϕ0, lon_in) # western edge
b = findfirst-> ϕ >= ϕ1, lon_in) # eastern edge

# map around prime meridian if coordinates outside of range
a = isnothing(a) ? nlon_in : a
b = isnothing(b) ? 1 : b

# in most cases we will have 1 <= a < b <=n, then loop i in a:b (b:a isn't looping)
# however at the edges we have a < 1 or n < b the mod turns this into
# 1 <= b < a <= n, for which we want to loop 1:b AND a:n
ab, ba = b < a ? (1:b, a:nlon_in) : (a:b, b:a)

sum_of_weights = 0
@inbounds for j′ in j0:j1
for j′ in j0:j1

for i in ab
w = coslat[j′]
Expand Down
2 changes: 2 additions & 0 deletions src/physics/land_sea_mask.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ function initialize!(land_sea_mask::LandSeaMask, model::PrimitiveEquation)
RingGrids.grid_cell_average!(land_sea_mask.mask, lsm_highres)

# TODO this shoudln't be necessary, but at the moment grid_cell_average! can return values > 1
# lo, hi = extrema(land_sea_mask.mask)
# (lo < 0 || hi > 1) && @warn "Land-sea mask has values in [$lo, $hi], clamping to [0, 1]."
clamp!(land_sea_mask.mask, 0, 1)
end

Expand Down
19 changes: 19 additions & 0 deletions test/grids/interpolation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,23 @@ end
RingGrids.interpolate!(C, A, interpolator)

@test B == C
end

@testset "Grid cell average" begin
for Grid in ( FullGaussianGrid,
FullClenshawGrid,
OctahedralGaussianGrid,
OctahedralClenshawGrid,
OctaminimalGaussianGrid,
HEALPixGrid,
OctaHEALPixGrid)

for trunc in (31, 42, 63)

spectral_grid = SpectralGrid(; trunc, Grid)

land_sea_mask = LandSeaMask(spectral_grid)
initialize!(land_sea_mask, PrimitiveDryModel(spectral_grid))
end
end
end

0 comments on commit e43d3a7

Please sign in to comment.