Skip to content

Improving Oceananigans' split barotropic solver - #5812

Open
simone-silvestri wants to merge 188 commits into
mainfrom
ss/sm05-barotropic
Open

simone-silvestri wants to merge 188 commits into
mainfrom
ss/sm05-barotropic

Conversation

@simone-silvestri

@simone-silvestri simone-silvestri commented Jul 23, 2026 •

Copy link
Copy Markdown
Collaborator

This PR includes some nice implementations to improve order and accuracy of the split explicit barotropic solver:

  • adds second order and third order filters (which have second and third order moments equal to zero)
  • adds higher order barotropic stepping for the barotropic solver, required to achieve overall higher temporal order (RK3 and AB3)
  • adds a slow forcing interpolation which is required for RK4 and improves the accuracy for RK3
  • adds a strong stability preserving RK3 version coupled with the barotropic solver

@codecov

codecov Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.08886% with 231 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.35%. Comparing base (71effed) to head (2955347).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...SurfaceModels/hydrostatic_free_surface_ssp_step.jl 48.21% 58 Missing ⚠️
...dVerticalDiffusivities/time_step_catke_equation.jl 0.00% 52 Missing ⚠️
src/TimeSteppers/ssp_runge_kutta.jl 55.71% 31 Missing ⚠️
src/Advection/ghost_cell_reconstruction.jl 66.66% 16 Missing ⚠️
...itFreeSurfaces/step_split_explicit_free_surface.jl 92.48% 13 Missing ⚠️
src/Advection/immersed_advective_fluxes.jl 42.10% 11 Missing ⚠️
...itFreeSurfaces/split_explicit_averaging_kernels.jl 87.77% 11 Missing ⚠️
...xplicitFreeSurfaces/slow_forcing_reconstruction.jl 88.88% 7 Missing ⚠️
...xplicitFreeSurfaces/split_explicit_timesteppers.jl 68.18% 7 Missing ⚠️
...ceDissipationComputations/advective_dissipation.jl 72.72% 6 Missing ⚠️
... and 8 more
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #5812       +/-   ##
===========================================
+ Coverage   25.96%   74.35%   +48.38%     
===========================================
  Files         439      444        +5     
  Lines       27275    28255      +980     
===========================================
+ Hits         7083    21009    +13926     
+ Misses      20192     7246    -12946     
Flag Coverage Δ
buildkite 70.21% <75.23%> (?)
distributed/output_combining 19.75% <12.65%> (-0.30%) ⬇️
distributed/tripolar 19.75% <12.65%> (-0.30%) ⬇️
julia 70.21% <75.23%> (?)
makie 20.20% <13.04%> (?)
metal 16.22% <10.71%> (-0.23%) ⬇️
reactant 20.20% <13.04%> (?)
sharding 20.20% <13.04%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Improves split-explicit barotropic accuracy, filtering, topology handling, and Runge–Kutta integration.

Changes:

  • Adds higher-order averaging kernels and slow-forcing reconstruction.
  • Introduces SSPRK3 and higher-order barotropic substepping.
  • Extends diagnostics, tripolar, multi-region, and implicit-advection support.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
test/test_tripolar_grid.jl Updates serial-fold expectations.
test/test_split_explicit_free_surface_solver.jl Tests kernels, reconstruction, and RK3 substeps.
test/test_implicit_diffusion_diagnostic.jl Adds SSPRK3 coverage.
src/TurbulenceClosures/.../time_step_catke_equation.jl Adds SSP CATKE stepping.
src/TimeSteppers/TimeSteppers.jl Exports and registers new steppers.
src/TimeSteppers/ssp_runge_kutta.jl Implements SSP Runge–Kutta.
src/TimeSteppers/split_runge_kutta.jl Adds modified RK4 composition.
src/Operators/topology_aware_operators.jl Adds tripolar-fold operators.
src/MultiRegion/multi_region_models.jl Integrates new free-surface state.
src/MultiRegion/multi_region_grid.jl Sizes multi-stage halos.
src/MultiRegion/cubed_sphere_grid.jl Sizes cubed-sphere halos.
src/Models/VarianceDissipationComputations/VarianceDissipationComputations.jl Adds scaling caches.
src/Models/VarianceDissipationComputations/update_fluxes.jl Accumulates SSP fluxes.
src/Models/VarianceDissipationComputations/diffusive_dissipation.jl Adds SSP diffusion accumulation.
src/Models/VarianceDissipationComputations/compute_dissipation.jl Assembles SSP diagnostics.
src/Models/VarianceDissipationComputations/advective_dissipation.jl Adds SSP advection accumulation.
src/Models/HydrostaticFreeSurfaceModels/SplitExplicitFreeSurfaces/step_split_explicit_free_surface.jl Refactors barotropic subcycling.
src/Models/HydrostaticFreeSurfaceModels/SplitExplicitFreeSurfaces/SplitExplicitFreeSurfaces.jl Exposes new solver APIs.
src/Models/HydrostaticFreeSurfaceModels/SplitExplicitFreeSurfaces/split_explicit_timesteppers.jl Implements barotropic RK3.
src/Models/HydrostaticFreeSurfaceModels/SplitExplicitFreeSurfaces/split_explicit_free_surface.jl Adds forcing and halo configuration.
src/Models/HydrostaticFreeSurfaceModels/SplitExplicitFreeSurfaces/split_explicit_averaging_kernels.jl Implements higher-order filters.
src/Models/HydrostaticFreeSurfaceModels/SplitExplicitFreeSurfaces/slow_forcing_reconstruction.jl Implements forcing interpolation.
src/Models/HydrostaticFreeSurfaceModels/SplitExplicitFreeSurfaces/initialize_split_explicit_substepping.jl Generalizes stage initialization.
src/Models/HydrostaticFreeSurfaceModels/SplitExplicitFreeSurfaces/compute_slow_tendencies.jl Caches stage forcing.
src/Models/HydrostaticFreeSurfaceModels/prescribed_hydrostatic_velocity_fields.jl Adds SSP no-op dispatch.
src/Models/HydrostaticFreeSurfaceModels/implicit_free_surface.jl Generalizes multi-stage dispatch.
src/Models/HydrostaticFreeSurfaceModels/HydrostaticFreeSurfaceModels.jl Includes SSP implementation.
src/Models/HydrostaticFreeSurfaceModels/hydrostatic_free_surface_ssp_step.jl Implements hydrostatic SSP stages.
src/Models/HydrostaticFreeSurfaceModels/hydrostatic_free_surface_model.jl Registers and validates steppers.
src/Models/HydrostaticFreeSurfaceModels/explicit_free_surface.jl Supports multi-stage stepping.
src/ImmersedBoundaries/mutable_immersed_grid.jl Handles folded column depths.
src/Advection/implicit_vertical_advection.jl Uses previous vertical spacing.
src/Advection/adaptive_implicit_vertical_advection.jl Supports SSP stage durations.
Suppressed comments (1)

src/Models/HydrostaticFreeSurfaceModels/SplitExplicitFreeSurfaces/slow_forcing_reconstruction.jl:123

  • This method ignores both ts.Nstages and the supplied Shu–Osher coefficients. Since SSPRungeKuttaTimeStepper publicly accepts arbitrary coefficient tuples, a four-stage reconstruction indexes past this three-element tuple, while other custom schemes receive incorrect sample nodes. Derive the stage abscissae from the recursion, or reject non-SSPRK3 coefficients before exposing reconstruction for them.
@inline stage_sample_times(::SSPRungeKuttaTimeStepper) = (0.0, 1.0, 1/2)

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/MultiRegion/multi_region_models.jl Resolved
Comment thread src/TimeSteppers/ssp_runge_kutta.jl Resolved
@aklocker42

Copy link
Copy Markdown
Collaborator

Hi Simone, I ran into a z★ tracer-constancy problem at open boundaries, and this PR fixes part of it, so flagging it here.

Setup: c ≡ 1, ZStarCoordinate, SplitRungeKutta3, open north/south boundaries with GravityWaveRadiationBoundaryCondition carrying a zero-net inflow. On main, c drifts by ~2e-5 within 200 steps.

Cause: σ is advanced with η, but w̃ comes from Ũ/Ṽ, and the two disagree at the boundary faces:

  1. Ũ/Ṽ are accumulated from U/V before the substep halo fill and transport pin, so the face at index 1 gets pre-fill values and the face at N+1 is never accumulated.
  2. After substepping, fill_halo_regions!((Ũ, Ṽ)) overwrites the boundary faces with the open-boundary value.

This PR fixes (1) for the faces inside the kernel range by accumulating U★/V★ in the η kernel. On its own, though, the result is bit-identical to main, because (2) overwrites the boundary faces anyway. With both fixed (also accumulate the N+1 face on a closed right side, and give Ũ/Ṽ boundary conditions that skip normal-flow sides), c − 1 drops to ~3e-15.

I have a minimal version of both on top of main, with a test that fails on main (|c − 1| ≈ 7e-6) and passes with the fix. I'll open it as a draft PR once the GPU tests pass. Since it touches the same kernel, I'm happy to fold it into this PR instead if you'd rather.

(Under AB2 there is a separate, larger z★ non-constancy, ~3e-4 in the same setup, that this doesn't address.)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants