-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Antarctic slope current example #8
base: main
Are you sure you want to change the base?
Changes from 8 commits
02b697c
3f7b23a
375b630
2e28ce6
952b796
17da147
2c2cfea
f7ae29f
8e27b2a
528c194
9656960
ba3f10a
1518f01
9eeebf2
fed4167
9fb7d9f
432b51f
5ae2bb0
c7ee0f7
9035fcd
8a216e8
90bb0f4
9a26cb1
788e573
9836e44
bb40c83
c70a2ff
820941e
1650072
0b43b1e
3e25a6a
380708d
12a133e
cf94e3e
31d1748
aaf894c
5cec281
72c7b05
35181a6
cc71c6f
8fe96d1
9d590d8
fc13b51
a15fc56
e59a723
2b1196e
1c5790f
10c77ff
4d6be26
64aa547
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,154 @@ | ||||||||||
|
||||||||||
#using CairoMakie | ||||||||||
using Oceananigans | ||||||||||
using Oceananigans.Units: minute, minutes, hour | ||||||||||
using SeawaterPolynomials.TEOS10 | ||||||||||
|
||||||||||
# This file sets up a model that resembles the Antarctic Slope Current (ASC) model in the | ||||||||||
# 2022 paper by Ian Eisenman | ||||||||||
|
||||||||||
arch = GPU() | ||||||||||
|
||||||||||
g_Earth = 9.80665 | ||||||||||
|
||||||||||
Lx = 400000 | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
Ly = 450000 | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
Lz = 4000 | ||||||||||
|
||||||||||
Nx = 400 | ||||||||||
Ny = 450 | ||||||||||
Nz = 70 # TODO: modify spacing if needed, 10 m at surface, 100m at seafloor | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we start with a smaller resolution? It'd be nice to test this on our laptops first |
||||||||||
|
||||||||||
sponge_width = 20000 | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
#= | ||||||||||
# | ||||||||||
# Setting up the grid and bathymetry: | ||||||||||
# | ||||||||||
# Using a linear slope that approximates the min and max spacings in the paper: | ||||||||||
init_adjustment = (0.5*(100-10)/(Nz-1)) + (10 - (100-10)/(Nz-1)) | ||||||||||
linear_slope(k) = (0.5*(100-10)/(Nz-1))*(k)^2 + (10 - (100-10)/(Nz-1))*(k) - init_adjustment | ||||||||||
|
||||||||||
spacing_adjustment = Lz / linear_slope(Nz+1) | ||||||||||
linear_slope_z_faces(k) = -spacing_adjustment * linear_slope(k) | ||||||||||
# Can reverse this to get grid from -4000 to 0 later | ||||||||||
=# | ||||||||||
refinement = 20.0 # controls spacing near surface (higher means finer spaced), 12.0 | ||||||||||
stretching = 3 # controls rate of stretching at bottom, 3 | ||||||||||
|
||||||||||
# Normalized height ranging from 0 to 1 | ||||||||||
h(k) = (k - 1) / Nz | ||||||||||
|
||||||||||
# Linear near-surface generator | ||||||||||
ζ₀(k) = 1 + (h(k) - 1) / refinement | ||||||||||
|
||||||||||
# Bottom-intensified stretching function | ||||||||||
Σ(k) = (1 - exp(-stretching * h(k))) / (1 - exp(-stretching)) | ||||||||||
|
||||||||||
# Generating function | ||||||||||
z_faces(k) = Lz * (ζ₀(k) * Σ(k) - 1) | ||||||||||
|
||||||||||
underlying_grid = RectilinearGrid(arch, | ||||||||||
size = (Nx, Ny, Nz), | ||||||||||
topology = (Periodic, Bounded, Bounded), | ||||||||||
x = (-Lx/2, Lx/2), | ||||||||||
y = (0, Ly), | ||||||||||
z = z_faces) | ||||||||||
|
||||||||||
println(underlying_grid) | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
# We want the underwater slope to provide a depth of 500 m at y = 0 and the full 4 km by y =200. It follows | ||||||||||
# a hyperbolic tangent curve with its center at y ~= 150 at a depth of ~ -4000 + (4000 - 500)/2 = -2250 m | ||||||||||
underwater_slope(x, y) = -1750tanh(0.00004*(y - 150000)) - 2250 | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
# TODO: add 50km troughs to the slope, dependent on x and y. Use appendix C to add detail here | ||||||||||
|
||||||||||
grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(underwater_slope)) | ||||||||||
|
||||||||||
println(grid) | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
# TODO: add underwater slope at y = 0 with troughs | ||||||||||
|
||||||||||
# | ||||||||||
# Creating the Hydrostatic model: | ||||||||||
# | ||||||||||
|
||||||||||
# Forcings: | ||||||||||
u_forcing(x, y, z, t) = exp(z) * cos(x) * sin(t) # Not actual forcing, just example | ||||||||||
|
||||||||||
# TODO: need to use forcings to enact the sponge layers. Their support is within 20000 m | ||||||||||
# of the N/S boundaries, they impose a cross-slope buoyancy gradient, and the relaxation | ||||||||||
# tiem scales decrease linearly with distance from the interior termination of the sponge layers | ||||||||||
|
||||||||||
# We'll use Relaxation() to impose a sponge layer forcing on velocity, temperature, and salinity | ||||||||||
damping_rate = 1 / 43200 # Relaxation time scale in seconds, need to make this decrease linearly toward outermost boundary | ||||||||||
south_mask = GaussianMask{:y}(center=0, width=sponge_width) | ||||||||||
north_mask = GaussianMask{:y}(center=Ly, width=sponge_width) | ||||||||||
south_sponge_layer = Relaxation(; rate=damping_rate, mask=south_mask) | ||||||||||
north_sponge_layer = Relaxation(; rate=damping_rate, mask=north_mask) | ||||||||||
sponge_layers = (south_sponge_layer, north_sponge_layer) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's try running without the sponge layer to start |
||||||||||
# TODO: compose north_mask and south_mask together into one sponge layer, OR compose north/south sponge layers | ||||||||||
|
||||||||||
|
||||||||||
# Boundary Conditions: | ||||||||||
no_slip_bc = ValueBoundaryCondition(0.0) | ||||||||||
free_slip_bc = FluxBoundaryCondition(nothing) | ||||||||||
|
||||||||||
free_slip_surface_bcs = FieldBoundaryConditions(no_slip_bc, top=FluxBoundaryCondition(nothing)) | ||||||||||
no_slip_field_bcs = FieldBoundaryConditions(no_slip_bc) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we want to impose no slip conditions here (even if it was used in the original Si and Stewart). We just need the momentum fluxes for |
||||||||||
|
||||||||||
# Buoyancy Equations of State - we want high order polynomials, so we'll use TEOS-10 | ||||||||||
eos = TEOS10EquationOfState() | ||||||||||
|
||||||||||
# Coriolis Effect, using basic f-plane with precribed reference Coriolis parameter | ||||||||||
coriolis = FPlane(f=-1.3e14) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps insert the reference latitude here? Eg something like coriolis = FPlane(latitude=-60) |
||||||||||
|
||||||||||
# Diffusivities as part of closure | ||||||||||
# TODO: make sure this works for biharmonic diffusivities as the horizontal, | ||||||||||
horizontal_closure = HorizontalScalarDiffusivity(ν=0.1, κ=0.1) | ||||||||||
vertical_closure = VerticalScalarDiffusivity(ν=3e-4, κ=1e-5) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need biharmonic or a background diffusivity if we use WENO + CATKE, so we can eliminate these |
||||||||||
|
||||||||||
# Assuming no particles or biogeochemistry | ||||||||||
model = HydrostaticFreeSurfaceModel(; grid, | ||||||||||
clock = Clock{eltype(grid)}(0, 0, 1), | ||||||||||
momentum_advection = CenteredSecondOrder(), | ||||||||||
tracer_advection = CenteredSecondOrder(), | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
buoyancy = SeawaterBuoyancy(equation_of_state=eos), | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
coriolis = coriolis, | ||||||||||
free_surface = ImplicitFreeSurface(gravitational_acceleration=g_Earth), | ||||||||||
forcing = (u=sponge_layers, v=sponge_layers, w=sponge_layers, T=sponge_layers, S=sponge_layers), # NamedTuple() | ||||||||||
closure = (horizontal_closure, vertical_closure), | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can rely entirely on WENO for horizontal dissipation. The only closure we need is for vertical mixing.
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
boundary_conditions = (u=free_slip_surface_bcs, v=free_slip_surface_bcs, w=no_slip_field_bcs), # NamedTuple(), | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note we can't set boundary conditions on |
||||||||||
tracers = (:T, :S), | ||||||||||
velocities = nothing, | ||||||||||
pressure = nothing, | ||||||||||
diffusivity_fields = nothing, | ||||||||||
#auxiliary_fields = nothing, # NamedTuple(), | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove the unused kwargs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
) | ||||||||||
|
||||||||||
println(model) | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
println("u boundary conditions:") | ||||||||||
println(model.velocities.u.boundary_conditions) | ||||||||||
println("v boundary conditions:") | ||||||||||
println(model.velocities.v.boundary_conditions) | ||||||||||
println("w boundary conditions:") | ||||||||||
println(model.velocities.w.boundary_conditions) | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
# | ||||||||||
# Now create a simulation and run the model | ||||||||||
# | ||||||||||
simulation = Simulation(model; Δt=100.0, stop_time=600minutes) | ||||||||||
|
||||||||||
# Create a NamedTuple | ||||||||||
|
||||||||||
filename = "asc_model_run" | ||||||||||
|
||||||||||
simulation.output_writers[:slices] = | ||||||||||
JLD2OutputWriter(model, merge(model.velocities, model.tracers), | ||||||||||
filename = filename * ".jld2", | ||||||||||
indices = (:, grid.Ny/2, :), | ||||||||||
schedule = TimeInterval(1minute), | ||||||||||
overwrite_existing = true) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The most interesting output will be a slice at the surface, eg using indices = (:, :, grid.Nz) so make sure to always output that |
||||||||||
|
||||||||||
run!(simulation) | ||||||||||
|
||||||||||
println(simulation) | ||||||||||
jlk9 marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be simpler to keep the defaults rather than change this. I made a comment though if we want to manually set this