Skip to content

Commit fcf881b

Browse files
authored
Merge pull request #124 from CliMA/glw/latest-oceananigans
Updates to Oceananigans 0.68
2 parents 374e758 + 52bab1d commit fcf881b

15 files changed

+711
-1360
lines changed

Manifest.toml

Lines changed: 388 additions & 235 deletions
Large diffs are not rendered by default.

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
2525
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2626

2727
[compat]
28-
Oceananigans = "^0.58"
28+
Oceananigans = "^0.68.2"
29+
Oceanostics = "^0.6.3"
2930
julia = "^1.6"
3031

3132
[extras]

examples/free_convection.jl

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,14 @@
33
# This script runs a simulation of convection driven by cooling at the
44
# surface of an idealized, stratified, rotating ocean surface boundary layer.
55

6-
using LESbrary, Printf, Statistics
6+
using LESbrary, Printf, Statistics, Oceananigans, Oceananigans.Units
77

88
# Domain
99

10-
using Oceananigans.Grids
11-
12-
grid = RegularRectilinearGrid(size=(32, 32, 32), x=(0, 128), y=(0, 128), z=(-64, 0))
10+
grid = RectilinearGrid(CPU(), size=(32, 32, 32), x=(0, 128), y=(0, 128), z=(-64, 0))
1311

1412
# Buoyancy and boundary conditions
1513

16-
using Oceananigans.BuoyancyModels, Oceananigans.BoundaryConditions
17-
1814
Qᵇ = 1e-7
1915
= 1e-5
2016

@@ -27,50 +23,48 @@ g = buoyancy.gravitational_acceleration
2723
Qᵀ = Qᵇ /* g)
2824
dTdz =/* g)
2925

30-
T_bcs = TracerBoundaryConditions(grid, top = BoundaryCondition(Flux, Qᵀ),
31-
bottom = BoundaryCondition(Gradient, dTdz))
26+
T_bcs = FieldBoundaryConditions(top = FluxBoundaryCondition(Qᵀ),
27+
bottom = GradientBoundaryCondition(dTdz))
3228

3329
# LES Model
3430

3531
# Wall-aware AMD model constant which is 'enhanced' near the upper boundary.
3632
# Necessary to obtain a smooth temperature distribution.
3733
using LESbrary.NearSurfaceTurbulenceModels: SurfaceEnhancedModelConstant
3834

39-
Cᴬᴹᴰ = SurfaceEnhancedModelConstant(grid.Δz, C₀ = 1/12, enhancement = 7, decay_scale = 4 * grid.Δz)
35+
Δz = grid.Δzᵃᵃᶜ
36+
Cᴬᴹᴰ = SurfaceEnhancedModelConstant(Δz, C₀ = 1/12, enhancement = 7, decay_scale = 4Δz)
4037

41-
# Instantiate Oceananigans.IncompressibleModel
38+
# Instantiate Oceananigans.NonhydrostaticModel
4239

4340
using Oceananigans
4441
using Oceananigans.Advection: WENO5
4542

46-
model = IncompressibleModel(architecture = CPU(),
47-
timestepper = :RungeKutta3,
48-
advection = WENO5(),
49-
grid = grid,
50-
tracers = :T,
51-
buoyancy = buoyancy,
52-
coriolis = FPlane(f=1e-4),
53-
closure = AnisotropicMinimumDissipation(C=Cᴬᴹᴰ),
54-
boundary_conditions = (T=T_bcs,))
43+
model = NonhydrostaticModel(; grid, buoyancy,
44+
timestepper = :RungeKutta3,
45+
advection = WENO5(),
46+
tracers = :T,
47+
coriolis = FPlane(f=1e-4),
48+
closure = AnisotropicMinimumDissipation(C=Cᴬᴹᴰ),
49+
boundary_conditions = (; T=T_bcs))
5550

5651
# # Initial condition
5752

5853
Ξ(z) = rand() * exp(z / 8)
59-
6054
Tᵢ(x, y, z) = dTdz * z + 1e-6 * Ξ(z) * dTdz * grid.Lz
61-
6255
set!(model, T=Tᵢ)
6356

6457
# # Prepare the simulation
6558

66-
using Oceananigans.Utils: hour, minute
6759
using LESbrary.Utils: SimulationProgressMessenger
6860

6961
# Adaptive time-stepping
70-
wizard = TimeStepWizard(cfl=1.5, Δt=2.0, max_change=1.1, max_Δt=30.0)
7162

72-
simulation = Simulation(model, Δt=wizard, stop_time=8hour, iteration_interval=100,
73-
progress=SimulationProgressMessenger(wizard))
63+
simulation = Simulation(model, Δt=2.0, stop_time=8hour)
64+
65+
wizard = TimeStepWizard(cfl=1.5, max_change=1.1, max_Δt=30.0)
66+
simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(100))
67+
simulation.callbacks[:progress] = Callback(SimulationProgressMessenger(wizard), IterationInterval(100))
7468

7569
# Prepare Output
7670

@@ -86,20 +80,19 @@ mkpath(data_directory)
8680
cp(@__FILE__, joinpath(data_directory, basename(@__FILE__)), force=true)
8781

8882
simulation.output_writers[:fields] = JLD2OutputWriter(model, merge(model.velocities, model.tracers);
89-
schedule = TimeInterval(4hour),
90-
prefix = prefix * "_fields",
91-
dir = data_directory,
92-
max_filesize = 2GiB,
93-
force = true)
83+
schedule = TimeInterval(4hour),
84+
prefix = prefix * "_fields",
85+
dir = data_directory,
86+
max_filesize = 2GiB,
87+
force = true)
9488

9589
simulation.output_writers[:slices] = JLD2OutputWriter(model, merge(model.velocities, model.tracers),
96-
schedule = AveragedTimeInterval(1hour, window=15minute),
97-
prefix = prefix * "_slices",
98-
field_slicer = FieldSlicer(j=floor(Int, grid.Ny/2)),
99-
dir = data_directory,
100-
max_filesize = 2GiB,
101-
force = true)
102-
90+
schedule = AveragedTimeInterval(1hour, window=15minute),
91+
prefix = prefix * "_slices",
92+
field_slicer = FieldSlicer(j=floor(Int, grid.Ny/2)),
93+
dir = data_directory,
94+
max_filesize = 2GiB,
95+
force = true)
10396

10497
# Horizontally-averaged turbulence statistics
10598
turbulence_statistics = LESbrary.TurbulenceStatistics.first_through_second_order(model)
@@ -108,9 +101,9 @@ tke_budget_statistics = LESbrary.TurbulenceStatistics.turbulent_kinetic_energy_b
108101
simulation.output_writers[:statistics] =
109102
JLD2OutputWriter(model, merge(turbulence_statistics, tke_budget_statistics),
110103
schedule = AveragedTimeInterval(1hour, window=15minute),
111-
prefix = prefix * "_statistics",
112-
dir = data_directory,
113-
force = true)
104+
prefix = prefix * "_statistics",
105+
dir = data_directory,
106+
force = true)
114107

115108
# # Run
116109

@@ -151,7 +144,7 @@ advective_flux = - file["timeseries/tke_advective_flux/$iter"][1, 1, :]
151144

152145
transport = zeros(grid.Nz)
153146
transport = (pressure_flux[2:end] .+ advective_flux[2:end]
154-
.- pressure_flux[1:end-1] .- advective_flux[1:end-1]) / grid.Δz
147+
.- pressure_flux[1:end-1] .- advective_flux[1:end-1]) / Δz
155148

156149
## For mixing length calculation
157150
wT = file["timeseries/wT/$iter"][1, 1, 2:end-1]
@@ -161,7 +154,7 @@ close(file)
161154
## Post-process the data to determine the mixing length
162155

163156
## Mixing length, computed at cell interfaces and omitting boundaries
164-
Tz = @. (T[2:end] - T[1:end-1]) / grid.Δz
157+
Tz = @. (T[2:end] - T[1:end-1]) / Δz
165158
bz = @. α * g * Tz
166159
eᶠ = @. (e[1:end-1] + e[2:end]) / 2
167160

@@ -204,3 +197,4 @@ mixing_length = plot([ℓ_measured ℓ_estimated], zF[2:end-1], size = plot_size
204197
label = ["measured" "estimated"])
205198

206199
plot(temperature, variances, budget, mixing_length, layout=(1, 4))
200+

examples/langmuir_turbulence.jl

Lines changed: 42 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,13 @@ using Plots
1919
using ArgParse
2020

2121
using Oceananigans
22-
using Oceananigans.Advection
23-
using Oceananigans.Grids
24-
using Oceananigans.Fields
25-
using Oceananigans.BuoyancyModels
26-
using Oceananigans.BoundaryConditions
27-
using Oceananigans.Diagnostics
28-
using Oceananigans.OutputWriters
29-
using Oceananigans.Utils
30-
31-
using LESbrary
32-
22+
using Oceananigans.Units
3323
using Oceananigans.BuoyancyModels: g_Earth
34-
using Oceananigans.Fields: PressureField
35-
using Oceananigans.BuoyancyModels: BuoyancyTracer
36-
using Oceananigans.SurfaceWaves: UniformStokesDrift
3724

38-
using LESbrary.TurbulenceStatistics: TurbulentKineticEnergy, ShearProduction, ViscousDissipation
25+
using LESbrary
26+
using LESbrary.TurbulenceStatistics: TurbulentKineticEnergy, ViscousDissipation
3927
using LESbrary.TurbulenceStatistics: first_through_second_order, turbulent_kinetic_energy_budget
28+
using Oceanostics.TKEBudgetTerms: ZShearProduction
4029

4130
"Returns a dictionary of command line arguments."
4231
function parse_command_line_arguments()
@@ -121,16 +110,16 @@ uˢ(z) = Uˢ * exp(2wavenumber * z)
121110
##### Grid
122111
#####
123112

124-
grid = RegularRectilinearGrid(size=(Nh, Nh, Nz), extent=(Lh, Lh, Lz))
113+
grid = RectilinearGrid(CPU(), size=(Nh, Nh, Nz), extent=(Lh, Lh, Lz))
125114

126115
#####
127116
##### Boundary conditions
128117
#####
129118

130-
u_bcs = UVelocityBoundaryConditions(grid, top = BoundaryCondition(Flux, Qᵘ))
119+
u_bcs = FieldBoundaryConditions(top = FluxBoundaryCondition(Qᵘ))
131120

132-
b_bcs = TracerBoundaryConditions(grid, top = BoundaryCondition(Flux, Qᵇ),
133-
bottom = BoundaryCondition(Gradient, N²))
121+
b_bcs = FieldBoundaryConditions(top = FluxBoundaryCondition(Qᵇ),
122+
bottom = GradientBoundaryCondition(N²))
134123

135124
#####
136125
##### Sponge layer
@@ -150,19 +139,15 @@ b_sponge = Relaxation(rate = 1/hour,
150139

151140
advection = eval(args["advection-scheme"])()
152141

153-
model = IncompressibleModel(
154-
architecture = GPU(),
155-
timestepper = :RungeKutta3,
156-
advection = advection,
157-
grid = grid,
158-
tracers = :b,
159-
buoyancy = BuoyancyTracer(),
160-
coriolis = FPlane(f=f),
161-
closure = AnisotropicMinimumDissipation(),
162-
surface_waves = UniformStokesDrift(∂z_uˢ=∂z_uˢ),
163-
boundary_conditions = (u=u_bcs, b=b_bcs),
164-
forcing = (u=u_sponge, v=v_sponge, w=w_sponge, b=b_sponge),
165-
)
142+
model = NonhydrostaticModel(; advection, grid,
143+
timestepper = :RungeKutta3,
144+
tracers = :b,
145+
buoyancy = BuoyancyTracer(),
146+
coriolis = FPlane(f=f),
147+
closure = AnisotropicMinimumDissipation(),
148+
stokes_drift = UniformStokesDrift(∂z_uˢ=∂z_uˢ),
149+
boundary_conditions = (u=u_bcs, b=b_bcs),
150+
forcing = (u=u_sponge, v=v_sponge, w=w_sponge, b=b_sponge))
166151

167152
#####
168153
##### Initial conditions: Stokes drift + stratification + noise
@@ -182,23 +167,26 @@ set!(model, u=uᵢ, w=wᵢ, b=bᵢ)
182167
##### Simulation setup
183168
#####
184169

185-
wizard = TimeStepWizard(cfl=1.0, Δt=1.0, max_change=1.1, max_Δt=30.0)
170+
simulation = Simulation(model; Δt=1.0, stop_time)
186171

187-
umax = FieldMaximum(abs, model.velocities.u)
188-
vmax = FieldMaximum(abs, model.velocities.v)
189-
wmax = FieldMaximum(abs, model.velocities.w)
172+
wizard = TimeStepWizard(cfl=1.0, max_change=1.1, max_Δt=30.0)
173+
simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(10))
190174

191175
wall_clock = [time_ns()]
192176

193177
function print_progress(simulation)
194178
model = simulation.model
195179

180+
umax = maximum(abs, model.velocities.u)
181+
vmax = maximum(abs, model.velocities.v)
182+
wmax = maximum(abs, model.velocities.w)
183+
196184
## Print a progress message
197185
msg = @sprintf("i: %04d, t: %s, Δt: %s, umax = (%.1e, %.1e, %.1e) ms⁻¹, wall time: %s\n",
198-
model.clock.iteration,
199-
prettytime(model.clock.time),
200-
prettytime(wizard.Δt),
201-
umax(), vmax(), wmax(),
186+
iteration(simulation),
187+
prettytime(simulation),
188+
prettytime(simulation.Δt),
189+
umax, vmax, wmax,
202190
prettytime(1e-9 * (time_ns() - wall_clock[1]))
203191
)
204192

@@ -209,10 +197,7 @@ function print_progress(simulation)
209197
return nothing
210198
end
211199

212-
simulation = Simulation(model, iteration_interval = 10,
213-
Δt = wizard,
214-
stop_time = stop_time,
215-
progress = print_progress)
200+
simulation.callbacks[:progress] = Callback(print_progress, IterationInterval(10))
216201

217202
#####
218203
##### Output setup
@@ -224,9 +209,9 @@ data_directory = joinpath(@__DIR__, "..", "data", prefix) # save data in /data/p
224209
# "Primitive" statistics
225210

226211
b = BuoyancyField(model)
227-
p = PressureField(model)
228-
w_scratch = ZFaceField(model.architecture, model.grid)
229-
c_scratch = CenterField(model.architecture, model.grid)
212+
p = model.pressures.pHY′ + model.pressures.pNHS
213+
w_scratch = ZFaceField(model.grid)
214+
c_scratch = CenterField(model.grid)
230215

231216
primitive_statistics = first_through_second_order(model, b=b, p=p, w_scratch=w_scratch, c_scratch=c_scratch)
232217

@@ -236,23 +221,26 @@ V = primitive_statistics[:v]
236221
# Turbulent kinetic energy budget terms
237222

238223
e = TurbulentKineticEnergy(model, U=U, V=V)
239-
shear_production = ShearProduction(model, data=c_scratch.data, U=U, V=V)
240-
dissipation = ViscousDissipation(model, data=c_scratch.data)
224+
shear_production = ZShearProduction(model, U=U, V=V)
225+
dissipation = ViscousDissipation(model)
241226

242227
tke_budget_statistics = turbulent_kinetic_energy_budget(model, b=b, p=p, U=U, V=V, e=e,
243228
shear_production=shear_production, dissipation=dissipation)
244229

245230
statistics_to_output = merge(primitive_statistics, tke_budget_statistics)
246231

247232
fields_to_output = merge(model.velocities, model.tracers,
248-
(νₑ=model.diffusivities.νₑ, e=e, sp=shear_production, ϵ=dissipation))
233+
(νₑ = model.diffusivity_fields.νₑ,
234+
e = Field(e),
235+
sp = Field(shear_production),
236+
ϵ = Field(dissipation)))
249237

250238
# Output configured for pickup
251239

252240
pickup = args["pickup"]
253241
force = pickup ? false : true
254242

255-
k_xy_slice = searchsortedfirst(grid.zF[:], -slice_depth)
243+
k_xy_slice = searchsortedfirst(znodes(Face, grid), -slice_depth)
256244

257245
simulation.output_writers[:checkpointer] =
258246
Checkpointer(model, schedule = TimeInterval(26hour), prefix = prefix * "_checkpointer", dir = data_directory)
@@ -418,8 +406,9 @@ pressure_flux = statistics_file["timeseries/tke_pressure_flux/$last_iteration"][
418406

419407
close(statistics_file)
420408

421-
pressure_flux_divergence = @. (pressure_flux[2:end] - pressure_flux[1:end-1]) ./ grid.Δz
422-
advective_flux_divergence = @. (advective_flux[2:end] - advective_flux[1:end-1]) ./ grid.Δz
409+
Δz = grid.Δzᵃᵃᶜ
410+
pressure_flux_divergence = @. (pressure_flux[2:end] - pressure_flux[1:end-1]) ./ Δz
411+
advective_flux_divergence = @. (advective_flux[2:end] - advective_flux[1:end-1]) ./ Δz
423412

424413
tendency = @. - pressure_flux_divergence - advective_flux_divergence + shear_production + buoyancy_flux - dissipation
425414

0 commit comments

Comments
 (0)