Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
aeae520
creating new example for the ACC
Aug 14, 2024
705f078
Update acc_regional_simulation.jl
francispoulin Aug 15, 2024
bc31849
Update acc_regional_simulation.jl
francispoulin Aug 20, 2024
67c3eb7
Merge branch 'main' into fjp/acc_regional_model
simone-silvestri Dec 10, 2024
06ab5d4
Merge branch 'main' into fjp/acc_regional_model
simone-silvestri Dec 18, 2024
7741ea7
updated script
Dec 18, 2024
a398d0c
add different masking
simone-silvestri Dec 18, 2024
e377edf
updating script to get further
Dec 18, 2024
ef9d130
fix node problem
Dec 18, 2024
5e95104
fix phinodes
francispoulin Dec 18, 2024
9abbc32
add grid to varphinodes
francispoulin Dec 18, 2024
55f667b
fix varphinode for real
Dec 18, 2024
3f9dd7d
a working version on a gpu
Dec 19, 2024
47ec55e
change time step to 10 minutes
Dec 20, 2024
a6989e8
cleaning up callbacks
Dec 20, 2024
8cc2719
Update examples/acc_regional_simulation.jl
francispoulin Dec 22, 2024
04b24e9
Merge branch 'main' into fjp/acc_regional_model
simone-silvestri Jan 13, 2025
c341fdc
change to the restoring rate and the outputwriter schedule
simone-silvestri Jan 13, 2025
7862bf2
Merge remote-tracking branch 'origin/main' into fjp/acc_regional_model
simone-silvestri May 29, 2025
75d909f
update example
simone-silvestri May 29, 2025
0cb27c5
Merge branch 'main' into fjp/acc_regional_model
simone-silvestri May 29, 2025
4462fe0
run docs
simone-silvestri May 29, 2025
2101f85
run docs
simone-silvestri May 29, 2025
a53438e
Update examples/acc_regional_simulation.jl
simone-silvestri May 29, 2025
9f2a04d
add a dataset
simone-silvestri May 29, 2025
bb228d1
fix restoring
simone-silvestri May 29, 2025
291f381
jld2 writer
simone-silvestri May 29, 2025
7a30c07
remove the interior
simone-silvestri May 29, 2025
feb1e12
correctly compute restoring on GPU
simone-silvestri May 30, 2025
06f479f
pass it
simone-silvestri May 30, 2025
16957c2
Update acc_regional_simulation.jl
francispoulin May 30, 2025
a3ad47e
updating file names
francispoulin Jun 1, 2025
88fa6a6
try with passing the grid
simone-silvestri Jun 2, 2025
ad5bdb6
changing the name of the files to save
Jun 2, 2025
b0c23ea
modifying some names and using the visualization from near global sim…
Jun 3, 2025
43693b9
changing a few names and using the visualization from near global (fo…
francispoulin Jun 3, 2025
2275549
change coupled_simulation to simulation
francispoulin Jun 3, 2025
3f546de
remove two unnecessary lines
francispoulin Jun 3, 2025
2837862
fix alignments
francispoulin Jun 3, 2025
0738b8b
restore backend definition
francispoulin Jun 3, 2025
1fcd5ed
returning to model
francispoulin Jun 3, 2025
c343d9c
changing initial time step to 2*minutes
francispoulin Jun 3, 2025
5cd349c
Merge remote-tracking branch 'origin/main' into fjp/acc_regional_model
simone-silvestri Jun 3, 2025
727f16e
trying the simulation from T=S=0 and no atmospheric forcing
Jun 16, 2025
f6f8492
adding line so it can run
Jun 16, 2025
759c1ac
Update Project.toml
simone-silvestri Jul 17, 2025
01e9f05
Update near_global_ocean_simulation.jl
simone-silvestri Jul 17, 2025
e48a2b5
Update one_degree_simulation.jl
simone-silvestri Jul 17, 2025
0765874
changes
simone-silvestri Jul 17, 2025
3ecb067
force with salinity field
simone-silvestri Jul 17, 2025
98c8166
Merge branch 'ss/adapt-to-new-oceananigans' into fjp/acc_regional_model
simone-silvestri Jul 17, 2025
5cdbc05
Merge branch 'fjp/acc_regional_model' of github.com:CliMA/ClimaOcean.…
simone-silvestri Jul 17, 2025
dd95781
adding the Manifest
simone-silvestri Jul 17, 2025
019b331
add CUDA
simone-silvestri Jul 17, 2025
5453bfb
change the zfaces
simone-silvestri Jul 17, 2025
11bfa0e
add CUDA to the examples
simone-silvestri Jul 17, 2025
bd5eb40
using CUDA
simone-silvestri Jul 17, 2025
0362716
Merge branch 'fjp/acc_regional_model' of github.com:CliMA/ClimaOcean.…
simone-silvestri Jul 17, 2025
c5cf412
revert cuda
simone-silvestri Jul 17, 2025
d6339c6
specify which record function to use
francispoulin Jul 17, 2025
a2ed433
fixing names of the files to load
francispoulin Jul 17, 2025
ca71f87
Update examples/acc_regional_simulation.jl
navidcy Jul 17, 2025
e35fd74
Delete Manifest.toml
navidcy Jul 22, 2025
b310603
bump Oceananigans compat
navidcy Jul 22, 2025
abfcaa0
Merge branch 'main' into fjp/acc_regional_model
navidcy Jul 22, 2025
e2b0529
Merge branch 'main' into fjp/acc_regional_model
navidcy Jul 23, 2025
ed80673
Update make.jl
navidcy Jul 23, 2025
9152964
a working version with non constant TKE
Aug 3, 2025
f36e9f9
adding a regional acc example, with TKE
Aug 3, 2025
ed34861
removing testing folder
francispoulin Aug 3, 2025
8068ff4
Update examples/acc_regional_simulation.jl
francispoulin Aug 4, 2025
2ade2a1
Changing the name of the example
francispoulin Aug 4, 2025
45d434f
Merge branch 'main' of github.com:CliMA/ClimaOcean.jl into fjp/acc_re…
francispoulin Aug 4, 2025
7c7c979
Merge branch 'fjp/acc_regional_model' of github.com:CliMA/ClimaOcean.…
francispoulin Aug 4, 2025
33e0d6e
Update docs/make.jl
francispoulin Aug 5, 2025
73d599a
Update docs/make.jl
francispoulin Aug 5, 2025
861f847
Update examples/panantarctic_regional_simulation.jl
francispoulin Aug 5, 2025
f69d6cf
Update examples/panantarctic_regional_simulation.jl
francispoulin Aug 5, 2025
32360a0
Update panantarctic_regional_simulation.jl
francispoulin Aug 5, 2025
885456a
uncomment the running of the simulation
francispoulin Aug 7, 2025
35c52d8
Merge branch 'main' into fjp/acc_regional_model
simone-silvestri Aug 10, 2025
32f4df8
run less time
navidcy Aug 10, 2025
cbbd8c7
Apply suggestions from code review
navidcy Aug 10, 2025
721ae2a
try ECCO2
navidcy Aug 11, 2025
80ac982
Update examples/panantarctic_regional_simulation.jl
navidcy Aug 11, 2025
2cc41d4
Update panantarctic_regional_simulation.jl
navidcy Aug 11, 2025
0e2675f
Apply suggestions from code review
navidcy Aug 11, 2025
c258839
fix phrasing
navidcy Aug 11, 2025
ac38912
literate
navidcy Aug 11, 2025
717ad8d
bring back everyone in the show
navidcy Aug 11, 2025
f3d6252
there is sea ice
navidcy Aug 11, 2025
a4941a9
dreaded missing comma
navidcy Aug 11, 2025
47742f4
Merge branch 'main' into fjp/acc_regional_model
francispoulin Aug 12, 2025
0109356
Update make.jl
navidcy Aug 13, 2025
122e418
Update panantarctic_regional_simulation.jl
navidcy Aug 14, 2025
1241a5d
Update panantarctic_regional_simulation.jl
francispoulin Aug 14, 2025
aebd509
Rephrase for clarity
navidcy Aug 14, 2025
c945e63
Update make.jl
navidcy Aug 15, 2025
c079625
Update make.jl
navidcy Aug 23, 2025
ef77e75
updating resolution for Ny
francispoulin Aug 26, 2025
f7d8df5
Change interpolation passes from 7 to 5
navidcy Sep 4, 2025
af27468
Merge branch 'main' into fjp/acc_regional_model
navidcy Sep 4, 2025
c5ff257
Merge branch 'main' into fjp/acc_regional_model
simone-silvestri Sep 4, 2025
d5291d7
Update panantarctic_regional_simulation.jl
francispoulin Sep 4, 2025
8cd6585
Merge branch 'main' into fjp/acc_regional_model
navidcy Sep 5, 2025
0249abe
Merge branch 'main' into fjp/acc_regional_model
navidcy Sep 6, 2025
65bbc6e
Update make.jl
navidcy Sep 7, 2025
6169de0
Update make.jl
navidcy Sep 7, 2025
6537a21
Update make.jl
francispoulin Sep 10, 2025
48c69c0
Update make.jl
francispoulin Sep 10, 2025
805445f
Update make.jl
francispoulin Sep 11, 2025
4fbc9d9
Update runtests.jl
francispoulin Sep 12, 2025
4cf99b6
Update runtests.jl
francispoulin Sep 12, 2025
2ad1653
Update docs/make.jl
francispoulin Sep 15, 2025
3b716db
Update docs/make.jl
francispoulin Sep 15, 2025
3ff77e8
Update docs/make.jl
glwagner Sep 15, 2025
e430943
Update docs/make.jl
glwagner Sep 15, 2025
0bb4542
Update panantarctic_regional_simulation.jl
francispoulin Sep 16, 2025
3aa53ac
Update panantarctic_regional_simulation.jl
francispoulin Sep 16, 2025
5a69b1c
Merge branch 'main' into fjp/acc_regional_model
navidcy Sep 20, 2025
8e4c837
Merge branch 'main' into fjp/acc_regional_model
francispoulin Oct 28, 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
4 changes: 3 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ const EXAMPLES_DIR = joinpath(@__DIR__, "..", "examples")
const OUTPUT_DIR = joinpath(@__DIR__, "src/literated")

to_be_literated = [
"panantarctic_regional_simulation.jl",
"single_column_os_papa_simulation.jl",
"one_degree_simulation.jl",
"near_global_ocean_simulation.jl"
"near_global_ocean_simulation.jl",
]

for file in to_be_literated
Expand All @@ -47,6 +48,7 @@ pages = [
"Single-column ocean simulation" => "literated/single_column_os_papa_simulation.md",
"One-degree ocean--sea ice simulation" => "literated/one_degree_simulation.md",
"Near-global ocean simulation" => "literated/near_global_ocean_simulation.md",
"Panantarctic regional simulation" => "literated/panantarctic_regional_simulation.md",
],

"Vertical grids" => "vertical_grids.md",
Expand Down
11 changes: 6 additions & 5 deletions examples/near_global_ocean_simulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,13 @@ set!(ocean.model, T=Metadatum(:temperature, dataset=ECCO4Monthly()),
# ### Prescribed atmosphere and radiation
#
# Next we build a prescribed atmosphere state and radiation model,
# which will drive the ocean simulation. We use the default `Radiation` model,
# which will drive the ocean simulation.

# The radiation model specifies an ocean albedo emissivity to compute the net radiative
# fluxes. The default ocean albedo is based on Payne (1982) and depends on cloud cover
# (calculated from the ratio of maximum possible incident solar radiation to actual
# incident solar radiation) and latitude. The ocean emissivity is set to 0.97.
# We use the default `Radiation` model. The radiation model specifies an ocean albedo
# emissivity to compute the net radiative fluxes. The default ocean albedo is based
# on Payne (1982) and depends on cloud cover (calculated from the ratio of maximum possible
# incident solar radiation to actual incident solar radiation) and latitude.
# The ocean emissivity is set to 0.97.

radiation = Radiation(arch)

Expand Down
300 changes: 300 additions & 0 deletions examples/panantarctic_regional_simulation.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
# # Panantarctic regional ocean simulation
#
# This example sets up and runs a regional ocean simulation for a domain around Antarctica
# using the Oceananigans.jl and ClimaOcean.jl. The simulation covers latitudes from 80°S to 20°S,
# with a horizontal resolution of 1/4 degree and 60 vertical levels.
#
# The simulation's results are visualized with the CairoMakie.jl package.
#
# The example showcases how we can use DatasetRestoring functionality to restore to a given dataset
# and also how to add custom masks on forcings.
#
# ## Initial setup with package imports
#
# We begin by importing the necessary Julia packages for visualization (CairoMakie),
# ocean modeling (Oceananigans, ClimaOcean), handling dates and times (Dates),
# and CUDA for running on CUDA-enabled GPUs.
# These packages provide the foundational tools for setting up the simulation environment,
# including grid setup, physical processes modeling, and data visualization.

using ClimaOcean
using ClimaOcean.ECCO
using Oceananigans
using Oceananigans.Units
using CUDA
using CairoMakie
using Dates
using Printf

# ### Grid and Bathymetry
#
# We start by constructing a the grid around Antarctica.

arch = GPU()
Nx = 1440
Ny = 240
Nz = 40

depth = 6000meters
z = ExponentialCoordinate(Nz, -depth, 0)

underlying_grid = LatitudeLongitudeGrid(arch;
size = (Nx, Ny, Nz),
halo = (7, 7, 7),
z = z,
latitude = (-80, -20),
longitude = (0, 360))

# ### Bathymetry and immersed boundary
#
# We add the bottom height from ETOPO1 data on our grid via `regrid_bathymetry`:

bottom_height = regrid_bathymetry(underlying_grid;
minimum_depth = 10meters,
interpolation_passes = 5,
major_basins = 1)

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

# and visualise it:

fig, ax, hm = heatmap(grid.immersed_boundary.bottom_height,
colormap=:deep, colorrange=(-depth, 0))
Colorbar(fig[0, 1], hm, label="Bottom height (m)", vertical=false)
save("panantarctic_bathymetry.png", fig)
nothing #hide

# ![](panantarctic_bathymetry.png)

# ### Restoring force
#
# We need to add restoring forces (both for tracers and for velocities) at the
# northern part of the domain to mimic the effect of the part of the ocean north
# of 20°S that we are not including in our domain.
#
# First we create some mask that have the following form:
#
# ```julia
# φS φN -20
# -------------- | ------------------ | ------------ |
# no restoring 0 linear mask 1 mask = 1 1
# ```

const φN₁ = -23
const φN₂ = -25
const φS₁ = -78
const φS₂ = -75

@inline northern_mask(φ) = min(max((φ - φN₂) / (φN₁ - φN₂), zero(φ)), one(φ))
@inline southern_mask(φ, z) = ifelse(z > -20,
min(max((φ - φS₂) / (φS₁ - φS₂), zero(φ)), one(φ)),
zero(φ))

@inline function tracer_mask(λ, φ, z, t)
n = northern_mask(φ)
s = southern_mask(φ, z)
return max(s, n)
end

# Now we are ready to construct the forcing. We relax temperature, salinity to
# data from the ECCO4 dataset at a timescale of 5 days. For the velocities at the
# northern part of the domain, we apply a sponge layer (i.e., we relax them to zero).

start_date = DateTime(1993, 1, 1)
end_date = DateTime(1993, 4, 1)

dataset = ECCO4Monthly()
T_meta = Metadata(:temperature; start_date, end_date, dataset)
S_meta = Metadata(:salinity; start_date, end_date, dataset)

@inline function u_sponge(i, j, k, grid, clock, fields, p)
φ = Oceananigans.Grids.φnode(i, j, k, grid, Face(), Center(), Center())
return - p.rate * fields.u[i, j, k] * northern_mask(φ)
end

@inline function v_sponge(i, j, k, grid, clock, fields, p)
φ = Oceananigans.Grids.φnode(i, j, k, grid, Center(), Face(), Center())
return - p.rate * fields.v[i, j, k] * northern_mask(φ)
end

rate = 1/5days
forcing = (T = DatasetRestoring(T_meta, grid; rate, mask=tracer_mask),
S = DatasetRestoring(S_meta, grid; rate, mask=tracer_mask),
u = Forcing(u_sponge; discrete_form=true, parameters=(; rate)),
v = Forcing(v_sponge; discrete_form=true, parameters=(; rate)))

# ### Ocean model configuration
#
# We build our ocean model using `ocean_simulation`,

momentum_advection = WENOVectorInvariant()
tracer_advection = WENO(order=7)

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

# We initialize the ocean model with eddy-resolving ECCO2 temperature, salinity,
# and horizontal velocities.

dataset = ECCO2Monthly()
T_meta = Metadatum(:temperature; date=start_date, dataset)
S_meta = Metadatum(:salinity; date=start_date, dataset)
u_meta = Metadatum(:u_velocity; date=start_date, dataset)
v_meta = Metadatum(:v_velocity; date=start_date, dataset)

set!(ocean.model, T=T_meta, S=S_meta, u=u_meta, v=v_meta)

# ### Prescribed atmosphere and radiation
#
# Next we build a prescribed atmosphere state and radiation model,
# which will drive the ocean simulation.

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

# ## The coupled simulation

# We put all the pieces together (ocean, atmosphere, and radiation)
# into a coupled model and a coupled simulation.
# We start with a small-ish time step of 2 minutes.
# We run the simulation for 10 days with this small-ish time step.

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

# A callback function to monitor the simulation's progress is always useful.

wall_time = [time_ns()]

function progress(sim)
ocean = sim.model.ocean
u, v, w = ocean.model.velocities
T = ocean.model.tracers.T

Tmax, Tmin = maximum(T), minimum(T)
umax = maximum(abs, u), maximum(abs, v), maximum(abs, w)
step_time = 1e-9 * (time_ns() - wall_time[1])

@info @sprintf("Time: %s, Iteration %d, Δt %s, max(vel): (%.2e, %.2e, %.2e), max(T): %.2f, min(T): %.2f, wtime: %s \n",
prettytime(ocean.model.clock.time),
ocean.model.clock.iteration,
prettytime(ocean.Δt),
umax..., Tmax, Tmin, prettytime(step_time))

wall_time[1] = time_ns()
end

simulation.callbacks[:progress] = Callback(progress, TimeInterval(5days))

# ### Output
#
# We use output writers to save the simulation data at regular intervals.

ocean.output_writers[:surface] = JLD2Writer(ocean.model, merge(ocean.model.tracers, ocean.model.velocities);
schedule = TimeInterval(1days),
filename = "panantarctic_surface_fields",
indices = (:, :, grid.Nz),
overwrite_existing = true,
array_type = Array{Float32})

# ### Spinning up the simulation
#
# We spin up the simulation with a small time step to ensure that the interpolated initial
# conditions adapt to the model numerics and parameterization without causing instability.
# A 10-day integration with a time step of 1 minute should be sufficient to dissipate spurious
# initialization shocks.

run!(simulation)
nothing #hide

# ### Running the simulation
#
# Now that the simulation has spun up, we can run increase the timestep and run for longer;
# here we choose 60 days.

simulation.stop_time = 60days
simulation.Δt = 10minutes
run!(simulation)
nothing #hide

# ## Visualizing the results
#
# The simulation has finished, let's visualize the results.
# In this section we pull up the saved data and create visualizations using the CairoMakie.jl package.
# In particular, we generate an animation of the evolution of surface fields:
# surface speed (s), surface temperature (T), and turbulent kinetic energy (e).

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

times = u.times
Nt = length(times)

n = Observable(Nt)

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

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

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

un = Field{Face, Center, Nothing}(u.grid)
vn = Field{Center, Face, Nothing}(v.grid)

s = @at (Center, Center, Nothing) sqrt(un^2 + vn^2)
s = Field(s)

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

title = @lift string("Panantarctic regional ocean simulation after ",
prettytime(times[$n] - times[1]))

λ, φ, _ = nodes(T)

fig = Figure(size = (1000, 1500))

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⁻²)")

Label(fig[0, :], title)

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

# ![](snapshot.png)

# And now we make a movie:

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

# ![](panantarctic_regional_surface.mp4)