Skip to content

Commit

Permalink
Merge pull request #2105 from CliMA/cnh/cg_solver_perf_test
Browse files Browse the repository at this point in the history
Matrix based implicit solver
  • Loading branch information
simone-silvestri committed Dec 17, 2021
2 parents a465c05 + 211c963 commit 4f80c38
Show file tree
Hide file tree
Showing 30 changed files with 1,670 additions and 196 deletions.
29 changes: 23 additions & 6 deletions Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ git-tree-sha1 = "28e837ff3e7a6c3cdb252ce49fb412c8eb3caeef"
uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
version = "0.1.0"

[[IncompleteLU]]
deps = ["LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "a22b92ffedeb499383720dfedcd473deb9608b62"
uuid = "40713840-3770-5561-ab4c-a76e7d0d7895"
version = "0.2.0"

[[IntelOpenMP_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d979e54b71da82f3a65b62553da4fc3d18c9004c"
Expand All @@ -209,6 +215,12 @@ git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.1"

[[IterativeSolvers]]
deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"]
git-tree-sha1 = "1169632f425f79429f245113b775a0e3d121457c"
uuid = "42fd0dbc-a981-5370-80f2-aaf504508153"
version = "0.9.2"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
Expand Down Expand Up @@ -300,9 +312,9 @@ version = "0.19.1"

[[MPICH_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "09864c823da1a606dbc151534c1a134fd5506170"
git-tree-sha1 = "480a8be51647c9dec19ff2211e26c9f30787840b"
uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4"
version = "3.4.2+1"
version = "3.4.2+2"

[[MacroTools]]
deps = ["Markdown", "Random"]
Expand All @@ -320,9 +332,9 @@ uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"

[[MicrosoftMPI_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "bb2fe65544e6efd883bb2060088df7dfb7273b41"
git-tree-sha1 = "a16aa086d335ed7e0170c5265247db29172af2f9"
uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf"
version = "10.1.3+1"
version = "10.1.3+2"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
Expand Down Expand Up @@ -362,9 +374,9 @@ uuid = "05823500-19ac-5b8b-9628-191a04bc5112"

[[OpenMPI_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "872077914c8a8cab9ea1430f338ae6b59258577d"
git-tree-sha1 = "08334c7cd6cb033274bc90918ece2174b5f84cc7"
uuid = "fe0851c0-eecd-5654-98d4-656369965a5c"
version = "4.1.1+3"
version = "4.1.1+5"

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
Expand Down Expand Up @@ -435,6 +447,11 @@ git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111"
uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143"
version = "1.5.3"

[[RecipesBase]]
git-tree-sha1 = "6bf3f380ff52ce0832ddd3a2a7b9538ed1bcca7d"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.2.1"

[[Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
Expand Down
3 changes: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
Glob = "c27321d9-0574-5035-807b-f59d2c89b15c"
IncompleteLU = "40713840-3770-5561-ab4c-a76e7d0d7895"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153"
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand All @@ -28,6 +30,7 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Rotations = "6038ab10-8711-5258-84ad-4b1120ba62dc"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
Tullio = "bc48ee85-29a4-5162-ae0b-a64e1601d4bc"
Expand Down
42 changes: 27 additions & 15 deletions benchmark/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ version = "1.4.1"

[[FFTW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "5a0d4b6a22a34d17d53543bd124f4b08ed78e8b0"
git-tree-sha1 = "3676abafff7e4ff07bbd2c42b3d8201f31653dcc"
uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a"
version = "3.3.9+7"
version = "3.3.9+8"

[[FileIO]]
deps = ["Pkg", "Requires", "UUIDs"]
Expand Down Expand Up @@ -244,9 +244,9 @@ uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"

[[GLFW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"]
git-tree-sha1 = "dba1e8614e98949abfa60480b13653813d8f0157"
git-tree-sha1 = "0c603255764a1fa0b61752d2bec14cfbd18f7fe8"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.5+0"
version = "3.3.5+1"

[[GPUArrays]]
deps = ["AbstractFFTs", "Adapt", "LinearAlgebra", "Printf", "Random", "Serialization", "Statistics"]
Expand Down Expand Up @@ -301,6 +301,12 @@ git-tree-sha1 = "86ed84701fbfd1142c9786f8e53c595ff5a4def9"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.9.10"

[[IncompleteLU]]
deps = ["LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "a22b92ffedeb499383720dfedcd473deb9608b62"
uuid = "40713840-3770-5561-ab4c-a76e7d0d7895"
version = "0.2.0"

[[IniFile]]
deps = ["Test"]
git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
Expand Down Expand Up @@ -328,6 +334,12 @@ git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.3.0"

[[IterativeSolvers]]
deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"]
git-tree-sha1 = "1169632f425f79429f245113b775a0e3d121457c"
uuid = "42fd0dbc-a981-5370-80f2-aaf504508153"
version = "0.9.2"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
Expand Down Expand Up @@ -423,9 +435,9 @@ uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[Libffi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "761a393aeccd6aa92ec3515e428c26bf99575b3b"
git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290"
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
version = "3.2.2+0"
version = "3.2.2+1"

[[Libgcrypt_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
Expand Down Expand Up @@ -484,9 +496,9 @@ uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[MKL_jll]]
deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"]
git-tree-sha1 = "c253236b0ed414624b083e6b72bfe891fbd2c7af"
git-tree-sha1 = "5455aef09b40e5020e1520f551fa3135040d4ed0"
uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
version = "2021.1.1+1"
version = "2021.1.1+2"

[[MPI]]
deps = ["Distributed", "DocStringExtensions", "Libdl", "MPICH_jll", "MicrosoftMPI_jll", "OpenMPI_jll", "Pkg", "Random", "Requires", "Serialization", "Sockets"]
Expand All @@ -496,9 +508,9 @@ version = "0.17.2"

[[MPICH_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c6cafe3f9747c0a0740611e2dffc4d37248fb691"
git-tree-sha1 = "480a8be51647c9dec19ff2211e26c9f30787840b"
uuid = "7cb0a576-ebde-5e09-9194-50597f1243b4"
version = "3.4.2+0"
version = "3.4.2+2"

[[MacroTools]]
deps = ["Markdown", "Random"]
Expand Down Expand Up @@ -533,9 +545,9 @@ version = "0.1.12"

[[MicrosoftMPI_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "e5c90234b3967684c9c6f87b4a54549b4ce21836"
git-tree-sha1 = "a16aa086d335ed7e0170c5265247db29172af2f9"
uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf"
version = "10.1.3+0"
version = "10.1.3+2"

[[Missings]]
deps = ["DataAPI"]
Expand Down Expand Up @@ -564,10 +576,10 @@ uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.5+0"

[[OpenMPI_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4a3c5819d496790e8cd664045c7fbe295ff6ae07"
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "04f95bf6987a4a29253427b4c59e30fd94fbc16f"
uuid = "fe0851c0-eecd-5654-98d4-656369965a5c"
version = "4.1.1+0"
version = "4.1.1+4"

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
Expand Down
2 changes: 2 additions & 0 deletions benchmark/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
IncompleteLU = "40713840-3770-5561-ab4c-a76e7d0d7895"
IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153"
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
Expand Down
66 changes: 50 additions & 16 deletions benchmark/benchmark_hydrostatic_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ using CUDA
using DataDeps
using Oceananigans
using Benchmarks

using Statistics
using Oceananigans.TimeSteppers: update_state!
using Oceananigans.Diagnostics: accurate_cell_advection_timescale
# Need a grid

ENV["DATADEPS_ALWAYS_ACCEPT"] = "true"
Expand All @@ -19,45 +21,76 @@ DataDeps.register(dd)

# Benchmark function

Nx = 256
Ny = 128

function set_simple_divergent_velocity!(model)
# Create a divergent velocity
grid = model.grid

u, v, w = model.velocities
η = model.free_surface.η

u .= 0
v .= 0
η .= 0

imid = Int(floor(grid.Nx / 2)) + 1
jmid = Int(floor(grid.Ny / 2)) + 1
CUDA.@allowscalar u[imid, jmid, 1] = 1

update_state!(model)

return nothing
end


# All grids have 6 * 510^2 = 1,560,600 grid points.
grids = Dict(
(CPU, :RectilinearGrid) => RectilinearGrid(size=(1445, 1080, 1), extent=(1, 1, 1)),
(CPU, :LatitudeLongitudeGrid) => LatitudeLongitudeGrid(size=(1445, 1080, 1), longitude=(-180, 180), latitude=(-80, 80), z=(-1, 0)),
(CPU, :ConformalCubedSphereFaceGrid) => ConformalCubedSphereFaceGrid(size=(1445, 1080, 1), z=(-1, 0)),
(CPU, :ConformalCubedSphereGrid) => ConformalCubedSphereGrid(datadep"cubed_sphere_510_grid/cubed_sphere_510_grid.jld2", Nz=1, z=(-1, 0)),
(GPU, :RectilinearGrid) => RectilinearGrid(size=(1445, 1080, 1), extent=(1, 1, 1), architecture=GPU()),
(GPU, :LatitudeLongitudeGrid) => LatitudeLongitudeGrid(size=(1445, 1080, 1), longitude=(-180, 180), latitude=(-80, 80), z=(-1, 0), architecture=GPU()),
# Uncomment when ConformalCubedSphereFaceGrids of any size can be built natively without loading from file:
(CPU, :RectilinearGrid) => RectilinearGrid(CPU(), size=(Nx, Ny, 1), extent=(1, 1, 1)),
(CPU, :LatitudeLongitudeGrid) => LatitudeLongitudeGrid(CPU(), size=(Nx, Ny, 1), longitude=(-180, 180), latitude=(-80, 80), z=(-1, 0), precompute_metrics=true),
# (CPU, :ConformalCubedSphereFaceGrid) => ConformalCubedSphereFaceGrid(size=(1445, 1080, 1), z=(-1, 0)),
# (CPU, :ConformalCubedSphereGrid) => ConformalCubedSphereGrid(datadep"cubed_sphere_510_grid/cubed_sphere_510_grid.jld2", Nz=1, z=(-1, 0)),
(GPU, :RectilinearGrid) => RectilinearGrid(GPU(), size=(Nx, Ny, 1), extent=(1, 1, 1)),
(GPU, :LatitudeLongitudeGrid) => LatitudeLongitudeGrid(GPU(), size=(Nx, Ny, 1), longitude=(-160, 160), latitude=(-80, 80), z=(-1, 0), precompute_metrics=true),
# Uncomment when ConformalCubedSphereFaceGrids of any size can be built natively without loading from file:
# (GPU, :ConformalCubedSphereFaceGrid) => ConformalCubedSphereFaceGrid(size=(1445, 1080, 1), z=(-1, 0), architecture=GPU()),
# (GPU, :ConformalCubedSphereGrid) => ConformalCubedSphereGrid(datadep"cubed_sphere_510_grid/cubed_sphere_510_grid.jld2", Nz=1, z=(-1, 0), architecture=GPU()),
)

free_surfaces = Dict(
:ExplicitFreeSurface => ExplicitFreeSurface(),
:ImplicitFreeSurface => ImplicitFreeSurface(maximum_iterations=1, tolerance=-Inf) # Force it to take exactly 1 iteration.
:FFTImplicitFreeSurface => ImplicitFreeSurface(),
:ImplicitFreeSurface => ImplicitFreeSurface(solver_method = :PreconditionedConjugateGradient),
:MatrixImplicitFreeSurface => ImplicitFreeSurface(solver_method = :MatrixIterativeSolver)
)

function benchmark_hydrostatic_model(Arch, grid_type, free_surface_type)

grid = grids[(Arch, grid_type)]

model = HydrostaticFreeSurfaceModel(
architecture = Arch(),
grid = grids[(Arch, grid_type)],
grid = grid,
momentum_advection = VectorInvariant(),
free_surface = free_surfaces[free_surface_type]
)

time_step!(model, 1) # warmup
set_simple_divergent_velocity!(model)

Δt = accurate_cell_advection_timescale(grid, model.velocities)

time_step!(model, Δt) # warmup

trial = @benchmark begin
CUDA.@sync blocking = true time_step!($model, 1)
CUDA.@sync blocking = true time_step!($model, $Δt)
end samples = 10

return trial
end

# Benchmark parameters

Architectures = has_cuda() ? [CPU, GPU] : [CPU]
Architectures = has_cuda() ? [GPU, CPU] : [CPU]

grid_types = [
:RectilinearGrid,
Expand All @@ -68,16 +101,17 @@ grid_types = [
]

free_surface_types = [
:MatrixImplicitFreeSurface,
:ExplicitFreeSurface,
# ImplicitFreeSurface doesn't yet work on MultiRegionGrids like the ConformalCubedSphereGrid:
:FFTImplicitFreeSurface,
:ImplicitFreeSurface,
# :ImplicitFreeSurface
]

# Run and summarize benchmarks

print_system_info()
suite = run_benchmarks(benchmark_hydrostatic_model; Architectures, grid_types, free_surface_types)

df = benchmarks_dataframe(suite)
# sort!(df, [:Architectures, :Float_types, :Ns], by=(string, string, identity))
benchmarks_pretty_table(df, title="Hydrostatic model benchmarks")
42 changes: 42 additions & 0 deletions benchmark/benchmark_spai_preconditioner.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
push!(LOAD_PATH, joinpath(@__DIR__, ".."))

using BenchmarkTools
using CUDA
using DataDeps
using Oceananigans
using Benchmarks
using Statistics
using Oceananigans.Solvers: spai_preconditioner

function benchmark_spai_preconditioner(N, ε, nzrel)

grid = RectilinearGrid(CPU(), size=(N, N, 1), extent=(1, 1, 1))

model = HydrostaticFreeSurfaceModel(
grid = grid,
free_surface = ImplicitFreeSurface(solver_method=:MatrixIterativeSolver, precondition = false)
)

# to correctly create the matrix
time_step!(model, 1)

matrix = model.free_surface.implicit_step_solver.matrix_iterative_solver.matrix

trial = @benchmark begin
CUDA.@sync blocking = true spai_preconditioner($matrix, ε = $ε, nzrel = $nzrel)
end samples = 5

return trial
end

N = [64, 128, 256]
ε = [0.1, 0.3, 0.6]
nzrel = [0.5, 1.0, 2.0]

# Run and summarize benchmarks
print_system_info()
suite = run_benchmarks(benchmark_spai_preconditioner; N, ε, nzrel)

df = benchmarks_dataframe(suite)
benchmarks_pretty_table(df, title="SPAI preconditioner benchmarks")

8 changes: 4 additions & 4 deletions src/Grids/latitude_longitude_grid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,10 @@ Adapt.adapt_structure(to, grid::LatitudeLongitudeGrid{FT, TX, TY, TZ}) where {FT
@inline Δxᶜᶜᵃ(i, j, k, grid::XRegLatLonGrid) = @inbounds grid.radius * hack_cosd(grid.φᵃᶜᵃ[j]) * deg2rad(grid.Δλᶜᵃᵃ)
@inline Δyᶜᶠᵃ(i, j, k, grid::YRegLatLonGrid) = @inbounds grid.radius * deg2rad(grid.Δφᵃᶠᵃ)
@inline Δyᶠᶜᵃ(i, j, k, grid::YRegLatLonGrid) = @inbounds grid.radius * deg2rad(grid.Δφᵃᶜᵃ)
@inline Azᶠᶜᵃ(i, j, k, grid::XRegLatLonGrid) = @inbounds grid.radius^2 * deg2rad(grid.Δλᶠᵃᵃ) * (hack_sind(grid.φᵃᶠᵃ[j+1]) - hack_sind(grid.φᵃᶠᵃ[j]))
@inline Azᶜᶠᵃ(i, j, k, grid::XRegLatLonGrid) = @inbounds grid.radius^2 * deg2rad(grid.Δλᶜᵃᵃ) * (hack_sind(grid.φᵃᶜᵃ[j]) - hack_sind(grid.φᵃᶜᵃ[j-1]))
@inline Azᶠᶠᵃ(i, j, k, grid::XRegLatLonGrid) = @inbounds grid.radius^2 * deg2rad(grid.Δλᶠᵃᵃ) * (hack_sind(grid.φᵃᶜᵃ[j]) - hack_sind(grid.φᵃᶜᵃ[j-1]))
@inline Azᶜᶜᵃ(i, j, k, grid::XRegLatLonGrid) = @inbounds grid.radius^2 * deg2rad(grid.Δλᶜᵃᵃ) * (hack_sind(grid.φᵃᶠᵃ[j+1]) - hack_sind(grid.φᵃᶠᵃ[j]))
@inline Azᶠᶜᵃ(i, j, k, grid::XRegLatLonGrid) = @inbounds grid.radius^2 * deg2rad(grid.Δλᶠᵃᵃ) * (hack_sind(grid.φᵃᶠᵃ[j+1]) - hack_sind(grid.φᵃᶠᵃ[j]))
@inline Azᶜᶠᵃ(i, j, k, grid::XRegLatLonGrid) = @inbounds grid.radius^2 * deg2rad(grid.Δλᶜᵃᵃ) * (hack_sind(grid.φᵃᶜᵃ[j]) - hack_sind(grid.φᵃᶜᵃ[j-1]))
@inline Azᶠᶠᵃ(i, j, k, grid::XRegLatLonGrid) = @inbounds grid.radius^2 * deg2rad(grid.Δλᶠᵃᵃ) * (hack_sind(grid.φᵃᶜᵃ[j]) - hack_sind(grid.φᵃᶜᵃ[j-1]))
@inline Azᶜᶜᵃ(i, j, k, grid::XRegLatLonGrid) = @inbounds grid.radius^2 * deg2rad(grid.Δλᶜᵃᵃ) * (hack_sind(grid.φᵃᶠᵃ[j+1]) - hack_sind(grid.φᵃᶠᵃ[j]))

#######
####### Utilities to precompute Metrics
Expand Down
Loading

0 comments on commit 4f80c38

Please sign in to comment.