From 187d6862a497c2e3000863bdb0e255554891e966 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Thu, 11 Sep 2025 13:33:17 -0400 Subject: [PATCH 1/7] fix clock argument --- .../isopycnal_skew_symmetric_diffusivity_with_triads.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/TurbulenceClosures/turbulence_closure_implementations/isopycnal_skew_symmetric_diffusivity_with_triads.jl b/src/TurbulenceClosures/turbulence_closure_implementations/isopycnal_skew_symmetric_diffusivity_with_triads.jl index 45d44f6273..e59e6c1100 100644 --- a/src/TurbulenceClosures/turbulence_closure_implementations/isopycnal_skew_symmetric_diffusivity_with_triads.jl +++ b/src/TurbulenceClosures/turbulence_closure_implementations/isopycnal_skew_symmetric_diffusivity_with_triads.jl @@ -282,7 +282,7 @@ end ϵκʸ⁻⁺ * Sy⁻⁺(i, j, k-1, grid, b, C) * ∂yᶜᶠᶜ(i, j, k-1, grid, c) + ϵκʸ⁺⁺ * Sy⁺⁺(i, j, k-1, grid, b, C) * ∂yᶜᶠᶜ(i, j+1, k-1, grid, c)) / 4 - κϵ_R₃₃_∂z_c = explicit_R₃₃_∂z_c(i, j, k, grid, TD(), c, closure, b, C) + κϵ_R₃₃_∂z_c = explicit_R₃₃_∂z_c(i, j, k, grid, TD(), clock, c, closure, b, C) return - κR₃₁_∂x_c - κR₃₂_∂y_c - κϵ_R₃₃_∂z_c end @@ -308,13 +308,13 @@ end return ϵκR₃₃ end -@inline function explicit_R₃₃_∂z_c(i, j, k, grid, ::ExplicitTimeDiscretization, c, closure, b, C) +@inline function explicit_R₃₃_∂z_c(i, j, k, grid, ::ExplicitTimeDiscretization, clock, c, closure, b, C) κ = closure.κ_symmetric sl = closure.slope_limiter return ϵκR₃₃(i, j, k, grid, κ, clock, sl, b, C) * ∂zᶜᶜᶠ(i, j, k, grid, c) end -@inline explicit_R₃₃_∂z_c(i, j, k, grid, ::VerticallyImplicitTimeDiscretization, c, closure, b, C) = zero(grid) +@inline explicit_R₃₃_∂z_c(i, j, k, grid, ::VerticallyImplicitTimeDiscretization, clock, c, closure, b, C) = zero(grid) @inline κzᶜᶜᶠ(i, j, k, grid, closure::FlavorOfTISSD, K, ::Val{id}, clock) where id = @inbounds K.ϵκR₃₃[i, j, k] From 1e3e80a664e0fa65395326097b5dd159b78d6648 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 18 Nov 2025 13:52:01 -0500 Subject: [PATCH 2/7] another missing argument, and missing method for diffusivity --- .../abstract_scalar_diffusivity_closure.jl | 1 + ...l_skew_symmetric_diffusivity_with_triads.jl | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/TurbulenceClosures/abstract_scalar_diffusivity_closure.jl b/src/TurbulenceClosures/abstract_scalar_diffusivity_closure.jl index 6aa978c3bb..104b890c4f 100644 --- a/src/TurbulenceClosures/abstract_scalar_diffusivity_closure.jl +++ b/src/TurbulenceClosures/abstract_scalar_diffusivity_closure.jl @@ -312,6 +312,7 @@ end @inline νᶜᶠᶠ(i, j, k, grid, loc, ν::Number, clk, fields) = ν @inline νᶠᶠᶜ(i, j, k, grid, loc, ν::Number, clk, fields) = ν +@inline κᶜᶜᶜ(i, j, k, grid, loc, κ::Number, clk, fields) = κ @inline κᶠᶜᶜ(i, j, k, grid, loc, κ::Number, clk, fields) = κ @inline κᶜᶠᶜ(i, j, k, grid, loc, κ::Number, clk, fields) = κ @inline κᶜᶜᶠ(i, j, k, grid, loc, κ::Number, clk, fields) = κ diff --git a/src/TurbulenceClosures/turbulence_closure_implementations/isopycnal_skew_symmetric_diffusivity_with_triads.jl b/src/TurbulenceClosures/turbulence_closure_implementations/isopycnal_skew_symmetric_diffusivity_with_triads.jl index e59e6c1100..7d4131bc4e 100644 --- a/src/TurbulenceClosures/turbulence_closure_implementations/isopycnal_skew_symmetric_diffusivity_with_triads.jl +++ b/src/TurbulenceClosures/turbulence_closure_implementations/isopycnal_skew_symmetric_diffusivity_with_triads.jl @@ -164,15 +164,15 @@ end @inline triad_mask_y(i, jy, jz, ky, kz, grid) = !peripheral_node(i, jy, ky, grid, Center(), Face(), Center()) & !peripheral_node(i, jz, kz, grid, Center(), Center(), Face()) -@inline ϵκx⁺⁺(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_x(i+1, i, j, k, k+1, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) -@inline ϵκx⁺⁻(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_x(i+1, i, j, k, k, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) -@inline ϵκx⁻⁺(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_x(i, i, j, k, k+1, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) -@inline ϵκx⁻⁻(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_x(i, i, j, k, k, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) - -@inline ϵκy⁺⁺(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_y(i, j+1, j, k, k+1, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) -@inline ϵκy⁺⁻(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_y(i, j+1, j, k, k, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) -@inline ϵκy⁻⁺(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_y(i, j, j, k, k+1, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) -@inline ϵκy⁻⁻(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_y(i, j, j, k, k, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) +@inline ϵκx⁺⁺(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_x(i+1, i, j, k, k+1, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock, C) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) +@inline ϵκx⁺⁻(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_x(i+1, i, j, k, k, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock, C) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) +@inline ϵκx⁻⁺(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_x(i, i, j, k, k+1, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock, C) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) +@inline ϵκx⁻⁻(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_x(i, i, j, k, k, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock, C) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) + +@inline ϵκy⁺⁺(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_y(i, j+1, j, k, k+1, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock, C) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) +@inline ϵκy⁺⁻(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_y(i, j+1, j, k, k, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock, C) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) +@inline ϵκy⁻⁺(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_y(i, j, j, k, k+1, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock, C) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) +@inline ϵκy⁻⁻(i, j, k, grid, loc, κ, clock, sl, b, C) = triad_mask_y(i, j, j, k, k, grid) * κᶜᶜᶜ(i, j, k, grid, loc, κ, clock, C) * tapering_factorᶜᶜᶜ(i, j, k, grid, sl, b, C) # Triad diagram key # ================= From f9cba318bdfc59332cc98aacbf4ce568150ff12e Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Tue, 18 Nov 2025 13:56:47 -0500 Subject: [PATCH 3/7] Add tests for TriadIsopycnalSkewSymmetricDiffusivity and include clock argument checks --- test/runtests.jl | 1 + test/test_triad_isopycnal_diffusivity.jl | 189 +++++++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 test/test_triad_isopycnal_diffusivity.jl diff --git a/test/runtests.jl b/test/runtests.jl index b498ad0080..7a1c7e69ec 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -137,6 +137,7 @@ CUDA.allowscalar() do if group == :turbulence_closures || group == :all @testset "Turbulence closures tests" begin include("test_turbulence_closures.jl") + include("test_triad_isopycnal_diffusivity.jl") end end diff --git a/test/test_triad_isopycnal_diffusivity.jl b/test/test_triad_isopycnal_diffusivity.jl new file mode 100644 index 0000000000..b313a50bf9 --- /dev/null +++ b/test/test_triad_isopycnal_diffusivity.jl @@ -0,0 +1,189 @@ +include("dependencies_for_runtests.jl") + +using Oceananigans.TurbulenceClosures: TriadIsopycnalSkewSymmetricDiffusivity +using Oceananigans.TurbulenceClosures: diffusive_flux_x, diffusive_flux_y, diffusive_flux_z, + ExplicitTimeDiscretization, VerticallyImplicitTimeDiscretization, + compute_diffusivities! + +""" +Test that TriadIsopycnalSkewSymmetricDiffusivity can be constructed and time-stepped +with both explicit and vertically implicit time discretizations. +""" +function time_step_with_triad_isopycnal_diffusivity(arch, time_disc) + grid = RectilinearGrid(arch, size=(4, 4, 8), extent=(100, 100, 100)) + + closure = TriadIsopycnalSkewSymmetricDiffusivity(time_disc, Float64, + κ_skew = 100.0, + κ_symmetric = 100.0) + + # TriadIsopycnalSkewSymmetricDiffusivity only works with HydrostaticFreeSurfaceModel + model = HydrostaticFreeSurfaceModel(; grid, closure, + buoyancy = BuoyancyTracer(), + tracers = (:b, :c)) + + # Set up a simple stratified initial condition + bᵢ(x, y, z) = 1e-5 * z + set!(model, b=bᵢ) + + # Attempt to time-step + time_step!(model, 1) + + return true +end + +""" +Test that flux calculations work correctly and receive the clock argument. +This specifically tests for the bug where the clock argument was missing in +the explicit_R₃₃_∂z_c function call. +""" +function test_triad_flux_calculations_with_clock(arch, time_disc) + grid = RectilinearGrid(arch, size=(4, 4, 8), extent=(100, 100, 100)) + + closure = TriadIsopycnalSkewSymmetricDiffusivity(time_disc, Float64, + κ_skew = 100.0, + κ_symmetric = 100.0) + + # Create necessary fields + tracers = TracerFields((:b, :c), grid) + clock = Clock(time=0.0) + buoyancy = BuoyancyTracer() + + # Set up a stratified state with lateral gradients + b = tracers.b + c = tracers.c + + # Create a tilted isopycnal surface: b = α*x + β*z + for k in 1:grid.Nz, j in 1:grid.Ny, i in 1:grid.Nx + x, y, z = nodes((Center, Center, Center), grid, i, j, k) + b[i, j, k] = 1e-5 * x + 1e-4 * z + c[i, j, k] = 1.0 + 0.1 * sin(2π * x / 100) * sin(2π * z / 100) + end + + fill_halo_regions!(tracers) + + # Compute diffusivity fields if needed for vertically implicit + K = DiffusivityFields(grid, (:b, :c), NamedTuple(), closure) + + if time_disc isa VerticallyImplicitTimeDiscretization + # Create a mock model for compute_diffusivities! + mock_model = (architecture = arch, + grid = grid, + clock = clock, + tracers = tracers, + buoyancy = buoyancy) + + compute_diffusivities!(K, closure, mock_model) + end + + model_fields = datatuple(tracers) + + # Test that flux calculations work without error + # This will fail if clock argument is missing + @allowscalar begin + i, j, k = 2, 2, 4 + + # Test diffusive fluxes - these should not error + # The key is that these functions internally call explicit_R₃₃_∂z_c + # which now requires the clock argument + flux_x = diffusive_flux_x(i, j, k, grid, closure, K, Val(1), c, clock, model_fields, buoyancy) + flux_y = diffusive_flux_y(i, j, k, grid, closure, K, Val(1), c, clock, model_fields, buoyancy) + flux_z = diffusive_flux_z(i, j, k, grid, closure, K, Val(1), c, clock, model_fields, buoyancy) + + # Fluxes should be real numbers (not NaN or Inf) + @test isfinite(flux_x) + @test isfinite(flux_y) + @test isfinite(flux_z) + end + + return true +end + +""" +Test that time discretization affects flux computation correctly. +Explicit should compute R₃₃ contribution, implicit should precompute it. +""" +function test_triad_time_discretization_behavior(arch) + grid = RectilinearGrid(arch, size=(4, 4, 8), extent=(100, 100, 100)) + + # Test with both time discretizations + for time_disc in (ExplicitTimeDiscretization(), VerticallyImplicitTimeDiscretization()) + closure = TriadIsopycnalSkewSymmetricDiffusivity(time_disc, Float64, + κ_skew = 100.0, + κ_symmetric = 100.0) + + K = DiffusivityFields(grid, (:b, :c), NamedTuple(), closure) + + if time_disc isa VerticallyImplicitTimeDiscretization + # Should have ϵκR₃₃ field + @test hasfield(typeof(K), :ϵκR₃₃) + @test K.ϵκR₃₃ isa Field + else + # Should be nothing for explicit + @test K === nothing + end + end + + return true +end + +""" +Test that the closure works with time-varying diffusivities. +""" +function test_triad_with_time_varying_diffusivity(arch) + grid = RectilinearGrid(arch, size=(4, 4, 8), extent=(100, 100, 100)) + + # Time-varying diffusivity + κ_time_varying(x, y, z, t) = 100.0 * (1.0 + 0.1 * sin(2π * t / 86400)) + + closure = TriadIsopycnalSkewSymmetricDiffusivity(ExplicitTimeDiscretization(), Float64, + κ_skew = κ_time_varying, + κ_symmetric = κ_time_varying) + + model = HydrostaticFreeSurfaceModel(; grid, closure, + buoyancy = BuoyancyTracer(), + tracers = (:b, :c)) + + # Set up initial condition + bᵢ(x, y, z) = 1e-5 * z + set!(model, b=bᵢ) + + # Time-step at different times - the clock should be passed correctly + for n in 1:3 + time_step!(model, 1000.0) # 1000 second time steps + @test model.clock.time ≈ n * 1000.0 + end + + return true +end + +@testset "TriadIsopycnalSkewSymmetricDiffusivity" begin + @info "Testing TriadIsopycnalSkewSymmetricDiffusivity..." + + for arch in archs + @testset "Time stepping with TriadIsopycnalSkewSymmetricDiffusivity [$arch]" begin + @info " Testing time stepping with explicit time discretization on $arch..." + @test time_step_with_triad_isopycnal_diffusivity(arch, ExplicitTimeDiscretization()) + + @info " Testing time stepping with vertically implicit time discretization on $arch..." + @test time_step_with_triad_isopycnal_diffusivity(arch, VerticallyImplicitTimeDiscretization()) + end + + @testset "Flux calculations with clock argument [$arch]" begin + @info " Testing flux calculations receive clock (explicit) on $arch..." + @test test_triad_flux_calculations_with_clock(arch, ExplicitTimeDiscretization()) + + @info " Testing flux calculations receive clock (implicit) on $arch..." + @test test_triad_flux_calculations_with_clock(arch, VerticallyImplicitTimeDiscretization()) + end + + @testset "Time discretization behavior [$arch]" begin + @info " Testing time discretization affects diffusivity fields on $arch..." + @test test_triad_time_discretization_behavior(arch) + end + + @testset "Time-varying diffusivity [$arch]" begin + @info " Testing time-varying diffusivity with clock on $arch..." + @test test_triad_with_time_varying_diffusivity(arch) + end + end +end From ac8cd35aee2aad85cb7c3196f1c2e4e296e3f189 Mon Sep 17 00:00:00 2001 From: Xin Kai Lee Date: Fri, 5 Dec 2025 15:39:48 -0500 Subject: [PATCH 4/7] remove tests, keep timestep only --- test/test_triad_isopycnal_diffusivity.jl | 142 ----------------------- 1 file changed, 142 deletions(-) diff --git a/test/test_triad_isopycnal_diffusivity.jl b/test/test_triad_isopycnal_diffusivity.jl index b313a50bf9..525cc5095a 100644 --- a/test/test_triad_isopycnal_diffusivity.jl +++ b/test/test_triad_isopycnal_diffusivity.jl @@ -31,130 +31,6 @@ function time_step_with_triad_isopycnal_diffusivity(arch, time_disc) return true end -""" -Test that flux calculations work correctly and receive the clock argument. -This specifically tests for the bug where the clock argument was missing in -the explicit_R₃₃_∂z_c function call. -""" -function test_triad_flux_calculations_with_clock(arch, time_disc) - grid = RectilinearGrid(arch, size=(4, 4, 8), extent=(100, 100, 100)) - - closure = TriadIsopycnalSkewSymmetricDiffusivity(time_disc, Float64, - κ_skew = 100.0, - κ_symmetric = 100.0) - - # Create necessary fields - tracers = TracerFields((:b, :c), grid) - clock = Clock(time=0.0) - buoyancy = BuoyancyTracer() - - # Set up a stratified state with lateral gradients - b = tracers.b - c = tracers.c - - # Create a tilted isopycnal surface: b = α*x + β*z - for k in 1:grid.Nz, j in 1:grid.Ny, i in 1:grid.Nx - x, y, z = nodes((Center, Center, Center), grid, i, j, k) - b[i, j, k] = 1e-5 * x + 1e-4 * z - c[i, j, k] = 1.0 + 0.1 * sin(2π * x / 100) * sin(2π * z / 100) - end - - fill_halo_regions!(tracers) - - # Compute diffusivity fields if needed for vertically implicit - K = DiffusivityFields(grid, (:b, :c), NamedTuple(), closure) - - if time_disc isa VerticallyImplicitTimeDiscretization - # Create a mock model for compute_diffusivities! - mock_model = (architecture = arch, - grid = grid, - clock = clock, - tracers = tracers, - buoyancy = buoyancy) - - compute_diffusivities!(K, closure, mock_model) - end - - model_fields = datatuple(tracers) - - # Test that flux calculations work without error - # This will fail if clock argument is missing - @allowscalar begin - i, j, k = 2, 2, 4 - - # Test diffusive fluxes - these should not error - # The key is that these functions internally call explicit_R₃₃_∂z_c - # which now requires the clock argument - flux_x = diffusive_flux_x(i, j, k, grid, closure, K, Val(1), c, clock, model_fields, buoyancy) - flux_y = diffusive_flux_y(i, j, k, grid, closure, K, Val(1), c, clock, model_fields, buoyancy) - flux_z = diffusive_flux_z(i, j, k, grid, closure, K, Val(1), c, clock, model_fields, buoyancy) - - # Fluxes should be real numbers (not NaN or Inf) - @test isfinite(flux_x) - @test isfinite(flux_y) - @test isfinite(flux_z) - end - - return true -end - -""" -Test that time discretization affects flux computation correctly. -Explicit should compute R₃₃ contribution, implicit should precompute it. -""" -function test_triad_time_discretization_behavior(arch) - grid = RectilinearGrid(arch, size=(4, 4, 8), extent=(100, 100, 100)) - - # Test with both time discretizations - for time_disc in (ExplicitTimeDiscretization(), VerticallyImplicitTimeDiscretization()) - closure = TriadIsopycnalSkewSymmetricDiffusivity(time_disc, Float64, - κ_skew = 100.0, - κ_symmetric = 100.0) - - K = DiffusivityFields(grid, (:b, :c), NamedTuple(), closure) - - if time_disc isa VerticallyImplicitTimeDiscretization - # Should have ϵκR₃₃ field - @test hasfield(typeof(K), :ϵκR₃₃) - @test K.ϵκR₃₃ isa Field - else - # Should be nothing for explicit - @test K === nothing - end - end - - return true -end - -""" -Test that the closure works with time-varying diffusivities. -""" -function test_triad_with_time_varying_diffusivity(arch) - grid = RectilinearGrid(arch, size=(4, 4, 8), extent=(100, 100, 100)) - - # Time-varying diffusivity - κ_time_varying(x, y, z, t) = 100.0 * (1.0 + 0.1 * sin(2π * t / 86400)) - - closure = TriadIsopycnalSkewSymmetricDiffusivity(ExplicitTimeDiscretization(), Float64, - κ_skew = κ_time_varying, - κ_symmetric = κ_time_varying) - - model = HydrostaticFreeSurfaceModel(; grid, closure, - buoyancy = BuoyancyTracer(), - tracers = (:b, :c)) - - # Set up initial condition - bᵢ(x, y, z) = 1e-5 * z - set!(model, b=bᵢ) - - # Time-step at different times - the clock should be passed correctly - for n in 1:3 - time_step!(model, 1000.0) # 1000 second time steps - @test model.clock.time ≈ n * 1000.0 - end - - return true -end @testset "TriadIsopycnalSkewSymmetricDiffusivity" begin @info "Testing TriadIsopycnalSkewSymmetricDiffusivity..." @@ -167,23 +43,5 @@ end @info " Testing time stepping with vertically implicit time discretization on $arch..." @test time_step_with_triad_isopycnal_diffusivity(arch, VerticallyImplicitTimeDiscretization()) end - - @testset "Flux calculations with clock argument [$arch]" begin - @info " Testing flux calculations receive clock (explicit) on $arch..." - @test test_triad_flux_calculations_with_clock(arch, ExplicitTimeDiscretization()) - - @info " Testing flux calculations receive clock (implicit) on $arch..." - @test test_triad_flux_calculations_with_clock(arch, VerticallyImplicitTimeDiscretization()) - end - - @testset "Time discretization behavior [$arch]" begin - @info " Testing time discretization affects diffusivity fields on $arch..." - @test test_triad_time_discretization_behavior(arch) - end - - @testset "Time-varying diffusivity [$arch]" begin - @info " Testing time-varying diffusivity with clock on $arch..." - @test test_triad_with_time_varying_diffusivity(arch) - end end end From 943984178630bcea4ec8bec1200fe542bca74899 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sat, 6 Dec 2025 09:04:31 +1100 Subject: [PATCH 5/7] Apply suggestions from code review --- test/test_triad_isopycnal_diffusivity.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/test_triad_isopycnal_diffusivity.jl b/test/test_triad_isopycnal_diffusivity.jl index 525cc5095a..13e3cd963a 100644 --- a/test/test_triad_isopycnal_diffusivity.jl +++ b/test/test_triad_isopycnal_diffusivity.jl @@ -37,11 +37,10 @@ end for arch in archs @testset "Time stepping with TriadIsopycnalSkewSymmetricDiffusivity [$arch]" begin - @info " Testing time stepping with explicit time discretization on $arch..." - @test time_step_with_triad_isopycnal_diffusivity(arch, ExplicitTimeDiscretization()) - - @info " Testing time stepping with vertically implicit time discretization on $arch..." - @test time_step_with_triad_isopycnal_diffusivity(arch, VerticallyImplicitTimeDiscretization()) + for time_discretization in [ExplicitTimeDiscretization(), VerticallyImplicitTimeDiscretization()] + @info " Testing time stepping with $(typeof(time_discretization)) on $arch..." + @test time_step_with_triad_isopycnal_diffusivity(arch, time_discretization) + end end end end From d3ba0d7d324038ef8fbc156f6fc8ae4bc40dbe1d Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sat, 6 Dec 2025 09:05:26 +1100 Subject: [PATCH 6/7] Apply suggestions from code review --- test/test_triad_isopycnal_diffusivity.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_triad_isopycnal_diffusivity.jl b/test/test_triad_isopycnal_diffusivity.jl index 13e3cd963a..f2b634550a 100644 --- a/test/test_triad_isopycnal_diffusivity.jl +++ b/test/test_triad_isopycnal_diffusivity.jl @@ -38,7 +38,7 @@ end for arch in archs @testset "Time stepping with TriadIsopycnalSkewSymmetricDiffusivity [$arch]" begin for time_discretization in [ExplicitTimeDiscretization(), VerticallyImplicitTimeDiscretization()] - @info " Testing time stepping with $(typeof(time_discretization)) on $arch..." + @info " Time-stepping TriadIsopycnalSkewSymmetricDiffusivity with $(typeof(time_discretization)) on $arch..." @test time_step_with_triad_isopycnal_diffusivity(arch, time_discretization) end end From 624b0effa479c42347b8afc00303db2b3854e5af Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Sat, 6 Dec 2025 09:07:27 +1100 Subject: [PATCH 7/7] Refactor time_step_with_triad_isopycnal_diffusivity --- test/test_triad_isopycnal_diffusivity.jl | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/test/test_triad_isopycnal_diffusivity.jl b/test/test_triad_isopycnal_diffusivity.jl index f2b634550a..c2d2b97679 100644 --- a/test/test_triad_isopycnal_diffusivity.jl +++ b/test/test_triad_isopycnal_diffusivity.jl @@ -6,24 +6,23 @@ using Oceananigans.TurbulenceClosures: diffusive_flux_x, diffusive_flux_y, diffu compute_diffusivities! """ -Test that TriadIsopycnalSkewSymmetricDiffusivity can be constructed and time-stepped -with both explicit and vertically implicit time discretizations. +Test that TriadIsopycnalSkewSymmetricDiffusivity can be constructed and timestepped +with both any time discretization. """ -function time_step_with_triad_isopycnal_diffusivity(arch, time_disc) +function time_step_with_triad_isopycnal_diffusivity(arch, time_discretization) grid = RectilinearGrid(arch, size=(4, 4, 8), extent=(100, 100, 100)) - closure = TriadIsopycnalSkewSymmetricDiffusivity(time_disc, Float64, - κ_skew = 100.0, - κ_symmetric = 100.0) + closure = TriadIsopycnalSkewSymmetricDiffusivity(time_discretization, Float64, + κ_skew = 100.0, + κ_symmetric = 100.0) # TriadIsopycnalSkewSymmetricDiffusivity only works with HydrostaticFreeSurfaceModel model = HydrostaticFreeSurfaceModel(; grid, closure, buoyancy = BuoyancyTracer(), tracers = (:b, :c)) - # Set up a simple stratified initial condition - bᵢ(x, y, z) = 1e-5 * z - set!(model, b=bᵢ) + # A constant stratification initial condition + set!(model, b=(x, y, z) -> 1e-5 * z) # Attempt to time-step time_step!(model, 1)