Skip to content
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

One degree simulation in the examples and correct documentation #276

Open
wants to merge 82 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 80 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
3114f74
this works best?
simone-silvestri Nov 22, 2024
9101d57
One degree simulation take 4
simone-silvestri Nov 22, 2024
5833d19
add a biharmonic viscosity
simone-silvestri Nov 22, 2024
96a64a2
Merge branch 'main' into ss/one-degree-take3
navidcy Nov 23, 2024
0aa74dc
infer maximum delta t
simone-silvestri Nov 23, 2024
ea8708f
Merge branch 'ss/one-degree-take3' of github.com:CliMA/ClimaOcean.jl …
simone-silvestri Nov 23, 2024
3a77b67
Merge remote-tracking branch 'origin/main' into ss/one-degree-take3
simone-silvestri Nov 26, 2024
7c87f2b
changes
simone-silvestri Nov 26, 2024
bddeae3
add statistics
simone-silvestri Nov 26, 2024
f129a1d
infer -> compute
simone-silvestri Dec 2, 2024
c0e2038
compute -> infer
simone-silvestri Dec 2, 2024
8de801a
Merge branch 'ss/one-degree-take3' of github.com:CliMA/ClimaOcean.jl …
simone-silvestri Dec 2, 2024
1857737
Merge branch 'main' into ss/one-degree-take3
simone-silvestri Dec 3, 2024
75bd857
Merge branch 'main' into ss/one-degree-take3
simone-silvestri Dec 3, 2024
9d08000
default for distribtued grid
simone-silvestri Dec 4, 2024
2ffa919
Merge branch 'ss/one-degree-take3' of github.com:CliMA/ClimaOcean.jl …
simone-silvestri Dec 4, 2024
9ead323
all_reduce instead of allreduce
simone-silvestri Dec 4, 2024
9425908
update other packages
simone-silvestri Dec 10, 2024
1cde9b9
Merge branch 'main' into ss/one-degree-take3
simone-silvestri Dec 11, 2024
d887392
Merge branch 'main' into ss/one-degree-take3
simone-silvestri Dec 13, 2024
60a4eac
Merge branch 'main' into ss/one-degree-take3
navidcy Dec 15, 2024
fa2eea4
let's see if it works
simone-silvestri Dec 15, 2024
22126cb
try it out
simone-silvestri Dec 15, 2024
7ddd356
run simulation
simone-silvestri Dec 15, 2024
1803be5
remove all instances of diffusion
simone-silvestri Dec 15, 2024
afe79e4
try a zstar grid
simone-silvestri Dec 15, 2024
2f57e3c
need a manifest for this
simone-silvestri Dec 15, 2024
48d70c9
regrid the bathymetry
simone-silvestri Dec 15, 2024
2b88745
better
simone-silvestri Dec 15, 2024
c8c446a
make it work
simone-silvestri Dec 22, 2024
28f95d6
Update Project.toml
simone-silvestri Dec 22, 2024
44d16ce
Merge branch 'main' into ss/one-degree-take3
simone-silvestri Dec 22, 2024
c36c867
Merge branch 'main' into ss/one-degree-take3
simone-silvestri Dec 22, 2024
53b898a
fix docs
simone-silvestri Dec 22, 2024
5c6bf40
fix docs
simone-silvestri Dec 22, 2024
c081671
update project
simone-silvestri Dec 23, 2024
3035819
just remove it for now
simone-silvestri Dec 23, 2024
915320d
Merge remote-tracking branch 'origin/main' into ss/one-degree-take3
simone-silvestri Dec 23, 2024
3ec643c
Merge branch 'main' into ss/one-degree-take3
simone-silvestri Jan 19, 2025
63c8f97
try out correct settings
simone-silvestri Jan 19, 2025
bf0da6d
Update examples/one_degree_simulation.jl
simone-silvestri Jan 23, 2025
d3d7a58
should work now
simone-silvestri Feb 2, 2025
1f0f98d
Merge branch 'main' into ss/one-degree-take3
navidcy Feb 2, 2025
0bbb834
literate one-degree example
navidcy Feb 12, 2025
c161d72
use GPU
navidcy Feb 12, 2025
36cf425
nuke znode
navidcy Feb 12, 2025
c4e21d0
add CairoMakie 0.13 compat
navidcy Feb 12, 2025
90fc47a
explain that there is also e
navidcy Feb 12, 2025
fc0e6cf
add comment for OrthogonalSphericalShellGrids
navidcy Feb 12, 2025
00ca95e
add comment for coupled ocean--sea ice
navidcy Feb 12, 2025
cfe530c
nuke ExplicitTimeDiscretization and fix typo
navidcy Feb 12, 2025
6c275c0
this should work
simone-silvestri Feb 13, 2025
de65394
add another restoring file
simone-silvestri Feb 13, 2025
4a4f6b2
correct videos
simone-silvestri Feb 13, 2025
1d404e1
Merge remote-tracking branch 'origin/main' into ss/one-degree-take3
simone-silvestri Feb 15, 2025
5f90f0c
tamper with the time step
simone-silvestri Feb 15, 2025
0961bd9
bugfix
simone-silvestri Feb 15, 2025
90d5a44
Merge branch 'main' into ss/one-degree-take3
simone-silvestri Feb 16, 2025
2372660
remove for the moment
simone-silvestri Feb 16, 2025
e792172
fix examples
simone-silvestri Feb 17, 2025
23ff95a
bugfix
simone-silvestri Feb 17, 2025
76c4a05
small fix
simone-silvestri Feb 18, 2025
9dcbd3e
try it out
simone-silvestri Feb 18, 2025
d283450
small change
simone-silvestri Feb 19, 2025
953305f
single column sim
simone-silvestri Feb 19, 2025
148eb6a
bugfix
simone-silvestri Feb 20, 2025
428d366
fix yet another example
simone-silvestri Feb 20, 2025
7c5e161
Merge branch 'main' into ss/one-degree-take3
simone-silvestri Feb 21, 2025
9cc0a77
gpu example
simone-silvestri Feb 21, 2025
79a9630
Merge branch 'ss/one-degree-take3' of github.com:CliMA/ClimaOcean.jl …
simone-silvestri Feb 21, 2025
b6501dc
update the clima common
simone-silvestri Feb 21, 2025
ab91378
allow scalar
simone-silvestri Feb 21, 2025
dd9a898
Update examples/one_degree_simulation.jl
simone-silvestri Feb 21, 2025
7271558
Update examples/one_degree_simulation.jl
simone-silvestri Feb 21, 2025
5d3e30f
Update src/OceanSimulations.jl
simone-silvestri Feb 21, 2025
37738ec
Update src/OceanSimulations.jl
simone-silvestri Feb 21, 2025
2870ab1
implement suggestions
simone-silvestri Feb 21, 2025
b5f8d61
implement suggestions
simone-silvestri Feb 21, 2025
a568275
add generate surface fluxes
simone-silvestri Feb 21, 2025
42c6f76
fix timesteps
simone-silvestri Feb 21, 2025
e10d62f
uff
simone-silvestri Feb 21, 2025
f1a603a
works?
simone-silvestri Feb 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .buildkite/examples_build.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
agents:
queue: new-central
slurm_mem: 8G
modules: climacommon/2024_05_27
modules: climacommon/2024_10_10
slurm_time: 48:00:00

env:
Expand Down
2 changes: 1 addition & 1 deletion .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
agents:
queue: new-central
slurm_mem: 8G
modules: climacommon/2024_10_08
modules: climacommon/2024_10_10

timeout_in_minutes: 1440

Expand Down
4 changes: 2 additions & 2 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ OrthogonalSphericalShellGrids = "c2be9673-fb75-4747-82dc-aa2bb9f4aed0"
SeawaterPolynomials = "d496a93d-167e-4197-9f49-d3af4ff8fe40"

[compat]
CairoMakie = "0.10.12, 0.11, 0.12"
CairoMakie = "0.10.12, 0.11, 0.12, 0.13"
DataDeps = "0.7"
Documenter = "1"
Oceananigans = "0.95.7 - 0.99"
OrthogonalSphericalShellGrids = "0.2.1"
SeawaterPolynomials = "0.3.4"
SeawaterPolynomials = "0.3.5"
2 changes: 2 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ to_be_literated = [
"generate_bathymetry.jl",
"generate_surface_fluxes.jl",
"single_column_os_papa_simulation.jl",
"one_degree_simulation.jl",
# "mediterranean_simulation_with_ecco_restoring.jl",
"near_global_ocean_simulation.jl"
]
Expand Down Expand Up @@ -46,6 +47,7 @@ pages = [
"Surface fluxes" => "literated/generate_surface_fluxes.md",
"Single-column simulation" => "literated/single_column_os_papa_simulation.md",
# "Mediterranean simulation with ECCO restoring" => "literated/mediterranean_simulation_with_ecco_restoring.md",
"One-degree Ocean simulation" => "literated/one_degree_simulation.md",
"Near-global Ocean simulation" => "literated/near_global_ocean_simulation.md",
],

Expand Down
4 changes: 2 additions & 2 deletions examples/ecco_mixed_layer_depth.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ using SeawaterPolynomials: TEOS10EquationOfState
using Oceananigans.BuoyancyFormulations: buoyancy

arch = CPU()
Nx = 360 ÷ 1
Ny = 160 ÷ 1
Nx = 360
Ny = 160

z = ClimaOcean.DataWrangling.ECCO.ECCO_z
z = z[20:end]
Expand Down
6 changes: 4 additions & 2 deletions examples/generate_surface_fluxes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ set!(ocean.model; T=T_metadata, S=S_metadata)
coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation=Radiation())

# Now that the surface fluxes are computed, we can extract and visualize them.
# The turbulent fluxes are stored in `coupled_model.fluxes.turbulent`.
# The turbulent fluxes are stored in `coupled_model.interfaces.atmosphere_ocean_interface.fluxes`.

fluxes = coupled_model.fluxes.turbulent.fields
fluxes = coupled_model.interfaces.atmosphere_ocean_interface.fluxes
λ, φ, z = nodes(fluxes.sensible_heat)

fig = Figure(size = (800, 800), fontsize = 15)
Expand All @@ -89,4 +89,6 @@ ax = Axis(fig[3, 1], title = "Water vapor flux (kg m⁻² s⁻¹)", xlabel = "Lo
heatmap!(ax, λ, φ, interior(fluxes.water_vapor, :, :, 1); colormap = :bwr)

save("fluxes.png", fig)
nothing #hide

# ![](fluxes.png)
264 changes: 264 additions & 0 deletions examples/one_degree_simulation.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
# # One-degree global ocean simulation
#
# This example configures a global ocean--sea ice simulation at 1ᵒ horizontal resolution with
# realistic bathymetry and some closures.
#
# For this example, we need Oceananigans, ClimaOcean, OrthogonalSphericalShellGrids, and
# CairoMakie to visualize the simulation. Also we need CFTime and Dates for date handling.

using ClimaOcean
using ClimaOcean.ECCO
using Oceananigans
using Oceananigans.Units
using OrthogonalSphericalShellGrids
using CFTime
using Dates
using Printf

arch = GPU()

# ### Grid and Bathymetry

Nx = 360
Ny = 180
Nz = 100

r_faces = exponential_z_faces(; Nz, depth=5000, h=34)
z_faces = Oceananigans.MutableVerticalDiscretization(r_faces)

underlying_grid = TripolarGrid(arch;
size = (Nx, Ny, Nz),
z = z_faces,
halo = (5, 5, 4),
first_pole_longitude = 70,
north_poles_latitude = 55)

bottom_height = regrid_bathymetry(underlying_grid;
minimum_depth = 10,
interpolation_passes = 75,
major_basins = 2)

# For this bathymetry at this horizontal resolution we need to manually open the Gibraltar strait.

tampered_bottom_height = deepcopy(bottom_height)
CUDA.@allowscalar view(tampered_bottom_height, 102:103, 124, 1) .= -400

grid = ImmersedBoundaryGrid(underlying_grid, GridFittedBottom(tampered_bottom_height);
active_cells_map=true)

# ### Restoring
#
# We include temperature and salinity surface restoring to ECCO data.

restoring_rate = 1 / 10days
z_below_surface = r_faces[end-1]

mask = LinearlyTaperedPolarMask(southern=(-80, -70), northern=(70, 90), z=(z_below_surface, 0))

dates = DateTimeProlepticGregorian(1993, 1, 1) : Month(1) : DateTimeProlepticGregorian(1994, 1, 1)
temperature = ECCOMetadata(:temperature; dates, version=ECCO4Monthly(), dir="./")
salinity = ECCOMetadata(:salinity; dates, version=ECCO4Monthly(), dir="./")

FT = ECCORestoring(temperature, grid; mask, rate=restoring_rate)
FS = ECCORestoring(salinity, grid; mask, rate=restoring_rate)
forcing = (T=FT, S=FS)

# ### Closures
#
# We include a Gent-McWilliam isopycnal diffusivity as a parameterization for the mesoscale
# eddy fluxes. For vertical mixing at the upper-ocean boundary layer we include the CATKE
# parameterization. We also include some explicit horizontal diffusivity.

using Oceananigans.TurbulenceClosures: IsopycnalSkewSymmetricDiffusivity,
DiffusiveFormulation

eddy_closure = IsopycnalSkewSymmetricDiffusivity(κ_skew=1e3, κ_symmetric=1e3,
skew_flux_formulation=DiffusiveFormulation())
vertical_mixing = ClimaOcean.OceanSimulations.default_ocean_closure()

closure = (eddy_closure, vertical_mixing)

# ### Ocean simulation
#
# Now we bring everything together to construct the ocean simulation.
# We use a split-explicit timestepping with 30 substeps for the barotropic
# mode.

free_surface = SplitExplicitFreeSurface(grid; substeps=30)

momentum_advection = WENOVectorInvariant(vorticity_order=3)
tracer_advection = Centered()

ocean = ocean_simulation(grid;
momentum_advection,
tracer_advection,
closure,
forcing,
free_surface)

# ### Initial condition

# We initialize the ocean from the ECCO state estimate.

set!(ocean.model, T=ECCOMetadata(:temperature; dates=first(dates)),
S=ECCOMetadata(:salinity; dates=first(dates)))

# ### Atmospheric forcing

# We force the simulation with an JRA55-do atmospheric reanalysis.

radiation = Radiation(arch)
atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(20))

# ### Coupled simulation

# Now we are ready to build the coupled ocean--sea ice model and bring everything
# together into a `simulation`.

# We use a relatively short time step initially and only run for a few days to
# avoid numerical instabilities from the initial "shock" of the adjustment of the
# flow fields.

coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation)
simulation = Simulation(coupled_model; Δt=1minutes, stop_time=10days)

# ### A progress messenger
#
# We write a function that prints out a helpful progress message while the simulation runs.

wall_time = Ref(time_ns())

function progress(sim)
ocean = sim.model.ocean
u, v, w = ocean.model.velocities
T = ocean.model.tracers.T
Tmax = maximum(interior(T))
Tmin = minimum(interior(T))
umax = (maximum(abs, interior(u)),
maximum(abs, interior(v)),
maximum(abs, interior(w)))

step_time = 1e-9 * (time_ns() - wall_time[])

msg1 = @sprintf("time: %s, iteration: %d, Δt: %s, ", prettytime(sim), iteration(sim), prettytime(sim.Δt))
msg2 = @sprintf("max|u|: (%.2e, %.2e, %.2e) m s⁻¹, ", umax...)
msg3 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin)
msg4 = @sprintf("wall time: %s \n", prettytime(step_time))

@info msg1 * msg2 * msg3 * msg4

wall_time[] = time_ns()

return nothing
end

# And add it as a callback to the simulation.

add_callback!(simulation, progress, IterationInterval(10))

# ### Output
#
# We are almost there! We need to save some output. Below we choose to save _only surface_
# fields using the `indices` keyword argument. We save all velocity and tracer components.
# Note, that besides temperature and salinity, the CATKE vertical mixing parameterization
# also uses a prognostic turbulent kinetic energy, `e`, to diagnose the vertical mixing length.

outputs = merge(ocean.model.tracers, ocean.model.velocities)
ocean.output_writers[:surface] = JLD2OutputWriter(ocean.model, outputs;
schedule = TimeInterval(5days),
filename = "global_surface_fields",
indices = (:, :, grid.Nz),
overwrite_existing = true)

# ### Ready to run

# We are ready to press the big red button and run the simulation.

# After we run for a short time (here we set up the simulation with `stop_time = 10days`),
# we increase the timestep and run for longer.

run!(simulation)

simulation.Δt = 20minutes
simulation.stop_time = 360days

run!(simulation)

# ### A pretty movie
#
# We load the saved output and make a pretty movie of the simulation. First we plot a snapshot:

using CairoMakie

u = FieldTimeSeries("global_surface_fields.jld2", "u"; backend = OnDisk())
v = FieldTimeSeries("global_surface_fields.jld2", "v"; backend = OnDisk())
T = FieldTimeSeries("global_surface_fields.jld2", "T"; backend = OnDisk())
e = FieldTimeSeries("global_surface_fields.jld2", "e"; backend = OnDisk())

times = u.times
Nt = length(times)

n = Observable(Nt)

# We create a land mask and use it to fill land points with `NaN`s.

land = interior(T.grid.immersed_boundary.bottom_height) .≥ 0

Tn = @lift begin
Tn = interior(T[$n])
Tn[land] .= NaN
view(Tn, :, :, 1)
end
Comment on lines +204 to +208
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't the plotting extension do this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not for a tripolar grid

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


en = @lift begin
en = interior(e[$n])
en[land] .= NaN
view(en, :, :, 1)
end

# We compute the surface speed.

un = Field{Face, Center, Nothing}(u.grid)
vn = Field{Center, Face, Nothing}(v.grid)
s = Field(sqrt(un^2 + vn^2))

sn = @lift begin
parent(un) .= parent(u[$n])
parent(vn) .= parent(v[$n])
compute!(s)
sn = interior(s)
sn[land] .= NaN
view(sn, :, :, 1)
end

# Finally, we plot a snapshot of the surface speed, temperature, and the turbulent
# eddy kinetic energy from the CATKE vertical mixing parameterization.

fig = Figure(size = (800, 1200))

axs = Axis(fig[1, 1], xlabel="Longitude (deg)", ylabel="Latitude (deg)")
axT = Axis(fig[2, 1], xlabel="Longitude (deg)", ylabel="Latitude (deg)")
axe = Axis(fig[3, 1], xlabel="Longitude (deg)", ylabel="Latitude (deg)")

hm = heatmap!(axs, sn, colorrange = (0, 0.5), colormap = :deep, nan_color=:lightgray)
Colorbar(fig[1, 2], hm, label = "Surface speed (m s⁻¹)")

hm = heatmap!(axT, Tn, colorrange = (-1, 30), colormap = :magma, nan_color=:lightgray)
Colorbar(fig[2, 2], hm, label = "Surface Temperature (ᵒC)")

hm = heatmap!(axe, en, colorrange = (0, 1e-3), colormap = :solar, nan_color=:lightgray)
Colorbar(fig[3, 2], hm, label = "Turbulent Kinetic Energy (m² s⁻²)")

save("global_snapshot.png", fig)
nothing #hide

# ![](global_snapshot.png)

# And now a movie:

record(fig, "one_degree_global_ocean_surface.mp4", 1:Nt, framerate = 8) do nn
n[] = nn
end
nothing #hide

# ![](one_degree_global_ocean_surface.mp4)
30 changes: 15 additions & 15 deletions examples/single_column_os_papa_simulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ current_figure()
# the skin temperature from a balance between internal and external heat fluxes.

radiation = Radiation()
similarity_theory = SimilarityTheoryTurbulentFluxes(grid; surface_temperature_type=SkinTemperature())
coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation)
# TODO: improve interface to allow passing fluxes types easily
coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation)
simulation = Simulation(coupled_model, Δt=ocean.Δt, stop_time=30days)

wall_clock = Ref(time_ns())
Expand All @@ -122,9 +122,9 @@ function progress(sim)
S = sim.model.ocean.model.tracers.S
e = sim.model.ocean.model.tracers.e

τx = first(sim.model.fluxes.total.ocean.momentum.u)
τy = first(sim.model.fluxes.total.ocean.momentum.v)
Q = first(sim.model.fluxes.total.ocean.heat)
τx = first(sim.model.interfaces.net_fluxes.ocean_surface.u)
τy = first(sim.model.interfaces.net_fluxes.ocean_surface.v)
Q = first(sim.model.interfaces.net_fluxes.ocean_surface.Q)

u★ = sqrt(sqrt(τx^2 + τy^2))

Expand All @@ -142,15 +142,15 @@ end
simulation.callbacks[:progress] = Callback(progress, IterationInterval(100))

# Build flux outputs
τx = coupled_model.fluxes.total.ocean.momentum.u
τy = coupled_model.fluxes.total.ocean.momentum.v
JT = coupled_model.fluxes.total.ocean.tracers.T
Js = coupled_model.fluxes.total.ocean.tracers.S
E = coupled_model.fluxes.turbulent.fields.water_vapor
Qc = coupled_model.fluxes.turbulent.fields.sensible_heat
Qv = coupled_model.fluxes.turbulent.fields.latent_heat
ρₒ = coupled_model.fluxes.ocean_reference_density
cₚ = coupled_model.fluxes.ocean_heat_capacity
τx = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.x_momentum
τy = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.y_momentum
JT = coupled_model.interfaces.net_fluxes.ocean_surface.T
Js = coupled_model.interfaces.net_fluxes.ocean_surface.S
E = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.water_vapor
Qc = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.sensible_heat
Qv = coupled_model.interfaces.atmosphere_ocean_interface.fluxes.latent_heat
ρₒ = coupled_model.interfaces.ocean_properties.reference_density
cₚ = coupled_model.interfaces.ocean_properties.heat_capacity

Q = ρₒ * cₚ * JT
ρτx = ρₒ * τx
Expand Down Expand Up @@ -249,7 +249,7 @@ tn = @lift times[$n]

colors = Makie.wong_colors()

ρₒ = coupled_model.fluxes.ocean_reference_density
ρₒ = coupled_model.interfaces.ocean_properties.reference_density
τx = interior(ρτx, 1, 1, 1, :) ./ ρₒ
τy = interior(ρτy, 1, 1, 1, :) ./ ρₒ
u★ = @. (τx^2 + τy^2)^(1/4)
Expand Down
Loading