Skip to content

Meridian cutting issue #18

@simone-silvestri

Description

@simone-silvestri

I think we are still hitting a meridian-cutting issue. Here is a minimum working example (unfortunately I need to write here the methods to get the faces)

using Oceananigans
using Oceananigans.Grids: λnode, φnode
using SpeedyWeather
using ConservativeRegridding

function get_faces(grid::Oceananigans.AbstractGrid)
    Nx, Ny, _ = size(grid)
    cell_matrix = Array{Tuple{Float64, Float64}}(undef, 5, Nx*Ny)

    @inbounds for i in 1:Nx, j in 1:Ny
        linear_idx = i + (j - 1) * Nx
    
        λ⁻⁻ = λnode(i,   j,   1, grid, Face(), Face(), nothing)
        λ⁺⁻ = λnode(i,   j+1, 1, grid, Face(), Face(), nothing)
        λ⁻⁺ = λnode(i+1, j,   1, grid, Face(), Face(), nothing)
        λ⁺⁺ = λnode(i+1, j+1, 1, grid, Face(), Face(), nothing)
        φ⁻⁻ = φnode(i,   j,   1, grid, Face(), Face(), nothing)
        φ⁺⁻ = φnode(i,   j+1, 1, grid, Face(), Face(), nothing)
        φ⁻⁺ = φnode(i+1, j,   1, grid, Face(), Face(), nothing)
        φ⁺⁺ = φnode(i+1, j+1, 1, grid, Face(), Face(), nothing)

        cell_matrix[1, linear_idx] = (λ⁻⁻, φ⁻⁻)
        cell_matrix[2, linear_idx] = (λ⁻⁺, φ⁻⁺)
        cell_matrix[3, linear_idx] = (λ⁺⁺, φ⁺⁺)
        cell_matrix[4, linear_idx] = (λ⁺⁻, φ⁺⁻)
        cell_matrix[5, linear_idx] = (λ⁻⁻, φ⁻⁻)
    end
    
    return cell_matrix
end

function get_faces(Grid, nlat_half::Integer)
    npoints = RingGrids.get_npoints2D(Grid, nlat_half)
    E, S, W, N = RingGrids.get_vertices(Grid, nlat_half)
    faces = Matrix{NTuple{2, Float64}}(undef, 5, npoints)

    @inbounds for ij in 1:npoints
        faces[1, ij] = (E[1, ij], E[2, ij])  # clockwise
        faces[2, ij] = (S[1, ij], S[2, ij])
        faces[3, ij] = (W[1, ij], W[2, ij])
        faces[4, ij] = (N[1, ij], N[2, ij])
        faces[5, ij] = (E[1, ij], E[2, ij])  # back to east to close the polygon        
    end

    return faces
end

get_faces(grid::SpeedyWeather.AbstractGridArray) = get_faces(typeof(grid), grid.nlat_half)

grid = LatitudeLongitudeGrid(Oceananigans.CPU(); size=(50, 50, 1), latitude=(-80, 80), longitude=(0, 360), z = (0, 1))

src = rand(OctaHEALPixGrid, 5 + 100) .+ 100
dst = CenterField(grid)

src_cells = get_faces(src)
dst_cells = get_faces(grid)

regridder = ConservativeRegridding.Regridder(dst_cells, src_cells)
ConservativeRegridding.regrid!(vec(interior(dst)), regridder, src)

heatmap(dst)
heatmap(src)

The output of this regridding is:

Image
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions