Open
Description
I noticed that passive tracers are not conserved in my global simulation (with a tripolar grid and the z-star coordinate) when a prescribed atmosphere is added (i.e., with JRA55
and ClimaOcean
). I’ve been able to isolate the issue to an Oceananigans-only MWE, adapted from the tripolar grid tracer conservation test in our suite. The only change is the addition of wind forcing.
Below is the simplified test setup used to reproduce the issue:
function run_tripolar_test_simulation(arch; with_wind = false)
z_stretched = MutableVerticalDiscretization(collect(-20:0))
grid = TripolarGrid(arch; size = (20, 20, 20), z = z_stretched)
function mtn₁(λ, φ)
λ₁ = 70
φ₁ = 55
dφ = 5
return exp(-((λ - λ₁)^2 + (φ - φ₁)^2) / 2dφ^2)
end
function mtn₂(λ, φ)
λ₁ = 70
λ₂ = λ₁ + 180
φ₂ = 55
dφ = 5
return exp(-((λ - λ₂)^2 + (φ - φ₂)^2) / 2dφ^2)
end
zb = - 20
h = - zb + 10
gaussian_islands(λ, φ) = zb + h * (mtn₁(λ, φ) + mtn₂(λ, φ))
grid = ImmersedBoundaryGrid(grid, GridFittedBottom(gaussian_islands))
free_surface = SplitExplicitFreeSurface(grid; substeps=10)
kwargs = (;
grid,
free_surface,
tracers = (:b, :c),
buoyancy = BuoyancyTracer(),
vertical_coordinate = ZStar()
)
if with_wind
u₁₀, cᴰ, ρₒ, ρₐ = 10.0, 2.5e-3, 1026.0, 1.225
τx = -ρₐ / ρₒ * cᴰ * u₁₀ * abs(u₁₀)
u_bcs = FieldBoundaryConditions(top = FluxBoundaryCondition(τx))
model = HydrostaticFreeSurfaceModel(; kwargs..., boundary_conditions = (u = u_bcs,))
else
model = HydrostaticFreeSurfaceModel(; kwargs...)
end
bᵢ(x, y, z) = y < 0 ? 0.06 : 0.01
# Instead of initializing with random velocities, infer them from a random initial streamfunction
# to ensure the velocity field is divergence-free at initialization.
ψ = Field{Center, Center, Center}(grid)
set!(ψ, rand(size(ψ)...))
uᵢ = ∂y(ψ)
vᵢ = -∂x(ψ)
set!(model, c = (x, y, z) -> rand(), u = uᵢ, v = vᵢ, b = bᵢ)
simulation = Simulation(model, Δt=2minutes, stop_time=1day)
c = simulation.model.tracers.c
tracer_integral = Integral(c, dims=(1, 2, 3))
if with_wind
prefix = "test_with_wind"
else
prefix = "test_no_wind"
end
integral_ow = JLD2Writer(
simulation.model,
(; tracer_integral),
filename = "$(prefix)_integrals",
schedule = IterationInterval(1),
overwrite_existing = true,
)
simulation.output_writers[:integral] = integral_ow
run!(simulation)
return nothing
end
run_tripolar_test_simulation(GPU(); with_wind = false)
run_tripolar_test_simulation(GPU(); with_wind = true)
Visualizing the results shows that the passive tracer c
is
- conserved for the simulation without wind, which matches the behavior tested in our CI.
- not conserved for the simulation with wind, despite all other settings being identical.
Metadata
Metadata
Assignees
Labels
No labels