Skip to content

Commit fb2c670

Browse files
hdrakeHenri Drakeglwagner
authored
Enforce total buoyancy flux BC in tilted geometry example (#3581)
* Enforce total buoyancy flux BC in tilted geometry example This example includes no explicit modification to the BCs on buoyancy, meaning that it defaults to a no-flux BC (or `FluxBoundaryCondition()`) on buoyancy. Following equation (6) of Wenegrat and Thomas (2020), we instead enforce a no-normal diffusive flux boundary condition on the *total* buoyancy, i.e. the perturbation plus the constantly-stratified `BackgroundField`. Because Oceananigans.jl does not allow diffusion to act on `BackgroundField`s, the background part of the no-flux BC is missing. However, we here can enforce it by specifying a perturbation flux BC that matches the implied background flux. Other minor changes: - Added equally-spaced buoyancy surfaces to movie panels - Guess timestep by minimum of advective and diffusive timescales, instead of just the advective timescale * Update examples/tilted_bottom_boundary_layer.jl Co-authored-by: Gregory L. Wagner <[email protected]> * Imeplement Greg's suggestions * Add equations to explain the choice of bottom BC on buoyancy * More intentional phrasing to explain perturbation BC Co-authored-by: Gregory L. Wagner <[email protected]> * More transparent assignment of bottom BC Co-authored-by: Gregory L. Wagner <[email protected]> * Rename background field to match mathematical notation Co-authored-by: Gregory L. Wagner <[email protected]> * Rename background field to match mathematical notation, follow-up Co-authored-by: Gregory L. Wagner <[email protected]> --------- Co-authored-by: Henri Drake <[email protected]> Co-authored-by: Gregory L. Wagner <[email protected]> Co-authored-by: Gregory L. Wagner <[email protected]>
1 parent 79895af commit fb2c670

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

examples/tilted_bottom_boundary_layer.jl

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,22 @@ coriolis = ConstantCartesianCoriolis(f = 1e-4, rotation_axis = ĝ)
9595
# _perturbations_ away from the constant density stratification by imposing
9696
# a constant stratification as a `BackgroundField`,
9797

98-
B_field = BackgroundField(constant_stratification, parameters=(; ĝ, N² = 1e-5))
98+
= 1e-5 # s⁻² # background vertical buoyancy gradient
99+
B∞_field = BackgroundField(constant_stratification, parameters=(; ĝ, N² = N²))
99100

100-
# where ``N^2 = 10^{-5} \rm{s}^{-2}`` is the background buoyancy gradient.
101+
# We choose to impose a bottom boundary condition of zero *total* diffusive buoyancy
102+
# flux across the seafloor,
103+
# ```math
104+
# ∂_z B = ∂_z b + N^{2} \cos{\theta} = 0.
105+
# ```
106+
# This shows that to impose a no-flux boundary condition on the total buoyancy field ``B``, we must apply a boundary condition to the perturbation buoyancy ``b``,
107+
# ```math
108+
# ∂_z b = - N^{2} \cos{\theta}.
109+
#```
110+
111+
∂z_b_bottom = -* cosd(θ)
112+
negative_background_diffusive_flux = GradientBoundaryCondition(∂z_b_bottom)
113+
b_bcs = FieldBoundaryConditions(bottom = negative_background_diffusive_flux)
101114

102115
# ## Bottom drag
103116
#
@@ -128,14 +141,16 @@ v_bcs = FieldBoundaryConditions(bottom = drag_bc_v)
128141
# and a constant viscosity and diffusivity. Here we use a smallish value
129142
# of ``10^{-4} \, \rm{m}^2\, \rm{s}^{-1}``.
130143

131-
closure = ScalarDiffusivity=1e-4, κ=1e-4)
144+
ν = 1e-4
145+
κ = 1e-4
146+
closure = ScalarDiffusivity=ν, κ=κ)
132147

133148
model = NonhydrostaticModel(; grid, buoyancy, coriolis, closure,
134149
timestepper = :RungeKutta3,
135150
advection = UpwindBiasedFifthOrder(),
136151
tracers = :b,
137-
boundary_conditions = (u=u_bcs, v=v_bcs),
138-
background_fields = (; b=B_field))
152+
boundary_conditions = (u=u_bcs, v=v_bcs, b=b_bcs),
153+
background_fields = (; b=B∞_field))
139154

140155
# Let's introduce a bit of random noise at the bottom of the domain to speed up the onset of
141156
# turbulence:
@@ -146,9 +161,11 @@ set!(model, u=noise, w=noise)
146161
# ## Create and run a simulation
147162
#
148163
# We are now ready to create the simulation. We begin by setting the initial time step
149-
# conservatively, based on the smallest grid size of our domain.
164+
# conservatively, based on the smallest grid size of our domain and either an advective
165+
# or diffusive time scaling, depending on which is shorter.
150166

151-
simulation = Simulation(model, Δt = 0.5 * minimum_zspacing(grid) / V∞, stop_time = 1day)
167+
Δt₀ = 0.5 * minimum([minimum_zspacing(grid) / V∞, minimum_zspacing(grid)^2/κ])
168+
simulation = Simulation(model, Δt = Δt₀, stop_time = 1day)
152169

153170
# We use a `TimeStepWizard` to adapt our time-step,
154171

@@ -199,6 +216,7 @@ run!(simulation)
199216

200217
using NCDatasets, CairoMakie
201218

219+
xb, yb, zb = nodes(B)
202220
xω, yω, zω = nodes(ωy)
203221
xv, yv, zv = nodes(V)
204222

@@ -220,14 +238,17 @@ ax_v = Axis(fig[3, 1]; title = "Along-slope velocity (v)", axis_kwargs...)
220238
n = Observable(1)
221239

222240
ωy = @lift ds["ωy"][:, 1, :, $n]
241+
B = @lift ds["B"][:, 1, :, $n]
223242
hm_ω = heatmap!(ax_ω, xω, zω, ωy, colorrange = (-0.015, +0.015), colormap = :balance)
224243
Colorbar(fig[2, 2], hm_ω; label = "s⁻¹")
244+
ct_b = contour!(ax_ω, xb, zb, B, levels=-1e-3:0.5e-4:1e-3, color=:black)
225245

226246
V = @lift ds["V"][:, 1, :, $n]
227247
V_max = @lift maximum(abs, ds["V"][:, 1, :, $n])
228248

229249
hm_v = heatmap!(ax_v, xv, zv, V, colorrange = (-V∞, +V∞), colormap = :balance)
230250
Colorbar(fig[3, 2], hm_v; label = "m s⁻¹")
251+
ct_b = contour!(ax_v, xb, zb, B, levels=-1e-3:0.5e-4:1e-3, color=:black)
231252

232253
times = collect(ds["time"])
233254
title = @lift "t = " * string(prettytime(times[$n]))

0 commit comments

Comments
 (0)