-
Notifications
You must be signed in to change notification settings - Fork 22
OMIP prototype #456
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
base: main
Are you sure you want to change the base?
OMIP prototype #456
Changes from all commits
ae5f0be
42be4e9
1dab6e2
9d11295
27ebee4
7f4af88
8d9401e
a7a3268
f8e7fe7
6deb3b8
fdef030
f4d63a1
a130e73
c90b7f9
08b377f
2eb5556
ba4bce0
68dfdb0
f212e88
1a68d4e
c318e54
79b5935
91e1169
b6fb198
e81bdfb
afbd1cc
8599314
bb24633
4f05dbb
fe6dc72
787ebc9
7c519a1
78a53cd
1e71d67
4f7fdb2
58662d2
22c8d08
79f37eb
a98669f
5405ef3
b2ff520
992b4d7
e65b0ea
e7a0039
40a9f24
58d5c11
4fc2394
385a44a
54e5838
925981d
62c2f46
fb35d78
65ca9ba
18504c5
f35345c
97c91fd
182cbfb
a23c423
f42a187
0a6dd9f
790b5e6
1649353
739bc46
6ef9d7c
58c38c7
4e53f82
29d15c8
418fa99
f8cd74b
4761081
93c6b6f
0293afd
cffb7e1
1febc0e
ce7cbd3
fbfe5ce
46940e7
473dbd7
3ccc9f7
a35bf04
68b3ff3
5f53219
9209bbf
62b4629
4d963ea
52c91d9
1ee41af
1d58772
0c020d0
bafe3c7
350b657
4a49b40
fea1854
4441567
7c4aa61
24f7d93
d231995
ca1980c
f448eeb
fed209b
aeedd2f
f954c69
ddee7f0
daeb12f
629d582
54165a0
35fe01d
5548a99
dfb8590
a049dc1
d1e6faf
7186256
a6d758d
0b8624e
f18a772
6679bbd
50a7226
7975dd4
77e440b
5e3c729
b05fb83
501b3fa
f258e29
5751899
af67adc
d008026
83f97e9
03e7f19
1e02dd9
1eedc44
202212c
efa566c
0c8d8b1
0f04d0f
e28b9a4
0e1d4ca
2eeed4c
b27ac12
4d09283
1507936
702fe64
9664584
8392922
d28b611
4b763ee
c306b0f
83331f8
4857647
668bc53
dcce9e2
d5288c1
1322148
2490da2
c411c71
f762205
759c1ac
01e9f05
e48a2b5
0765874
808e6c9
88bd4e8
7cacb1d
7cb8d6b
469883a
86d0bce
509d6b4
308c9e3
06d895c
6397010
ea59ebb
352a3ef
2beac0e
ea86989
89af369
9e2482b
9affa64
7717533
6e0be09
4488c2e
26fde07
a436bed
5746652
5127f05
1037980
71c82f5
bc33d07
ed0d210
5b5b747
28d3e4e
00a2933
d7ef440
b0d1fd3
860ff09
5637600
b3ab48b
d1c7450
a1ede1f
4015bf4
970ffeb
4b4f64e
e6ff0d4
ef45d0c
d96c32b
ea3ee12
9165bd2
add5526
35e2df6
92fda28
ec70ca0
469bcb1
736ac4c
6db860a
5e0997c
049dacd
cf22586
17a2250
d024542
7d6ce58
5e66a54
9063e3e
4fb3526
e7845a5
fca5484
09d22a3
3885668
8bbc3b8
988ec77
3419022
b1430e2
abced34
cf2e735
d0b3bf9
5f3452d
f9613d8
557ddc9
3861dba
d126260
22d6f31
743fa84
f3b1b97
c21aab6
01af82e
91fae63
2bf3999
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| using ClimaOcean | ||
| using ClimaOcean.JRA55 | ||
| using ClimaOcean.DataWrangling: download_dataset | ||
|
|
||
| atmosphere = JRA55PrescribedAtmosphere(; dir="forcing_data/", | ||
|
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. Trying to encourage people not to set this variable because it makes setups less portable (eg data will be re-downloaded everywhere) |
||
| dataset=JRA55MultipleYears(), | ||
| backend=JRA55NetCDFBackend(10), | ||
| include_rivers_and_icebergs=true) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| using ClimaOcean | ||
| using ClimaSeaIce | ||
| using Oceananigans | ||
| using Oceananigans.Grids | ||
| using Oceananigans.Units | ||
| using Oceananigans.OrthogonalSphericalShellGrids | ||
| using ClimaOcean.OceanSimulations | ||
| using ClimaOcean.ECCO | ||
| using ClimaOcean.JRA55 | ||
| using ClimaOcean.DataWrangling | ||
| using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium | ||
| using Printf | ||
| using Dates | ||
| using CUDA | ||
|
|
||
| import Oceananigans.OutputWriters: checkpointer_address | ||
|
|
||
| arch = GPU() | ||
|
|
||
| Nx = 360 # longitudinal direction | ||
| Ny = 180 # meridional direction | ||
| Nz = 60 | ||
|
|
||
| z_faces = ExponentialCoordinate(Nz, -6000, 0) | ||
| # z_faces = MutableVerticalDiscretization(z_faces) | ||
|
|
||
| const z_surf = z_faces(Nz) | ||
|
|
||
| grid = TripolarGrid(arch; | ||
| size = (Nx, Ny, Nz), | ||
| z = z_faces, | ||
| halo = (7, 7, 7)) | ||
|
|
||
| bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=75) | ||
| grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) | ||
|
|
||
| ##### | ||
| ##### A Propgnostic Ocean model | ||
| ##### | ||
|
|
||
| using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization | ||
| using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation | ||
|
|
||
| momentum_advection = WENOVectorInvariant(order=5) | ||
| tracer_advection = WENO(order=5) | ||
|
|
||
| free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt=45minutes) | ||
|
|
||
| eddy_closure = Oceananigans.TurbulenceClosures.IsopycnalSkewSymmetricDiffusivity(κ_skew=1e3, κ_symmetric=1e3) | ||
| catke_closure = ClimaOcean.OceanSimulations.default_ocean_closure() | ||
| closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=1e-4), eddy_closure) | ||
|
|
||
| dataset = EN4Monthly() | ||
| date = DateTime(1958, 1, 1) | ||
| @inline mask(x, y, z, t) = z ≥ z_surf - 1 | ||
| Smetadata = Metadata(:salinity; dataset) | ||
|
|
||
| FS = DatasetRestoring(Smetadata, grid; rate = 1/18days, mask, time_indices_in_memory = 10) | ||
|
|
||
| ocean = ocean_simulation(grid; Δt=1minutes, | ||
| momentum_advection, | ||
| tracer_advection, | ||
| timestepper = :SplitRungeKutta3, | ||
| free_surface, | ||
| forcing = (; S = FS), | ||
| closure) | ||
|
|
||
| dataset = EN4Monthly() | ||
| date = DateTime(1958, 1, 1) | ||
|
|
||
| set!(ocean.model, T=Metadatum(:temperature; dataset, date), | ||
| S=Metadatum(:salinity; dataset, date)) | ||
|
|
||
| @info ocean.model.clock | ||
|
|
||
| ##### | ||
| ##### A Prognostic Sea-ice model | ||
| ##### | ||
|
|
||
| # Default sea-ice dynamics and salinity coupling are included in the defaults | ||
| sea_ice = sea_ice_simulation(grid, ocean; advection=WENO(order=7)) | ||
|
|
||
| set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset=ECCO4Monthly()), | ||
| ℵ=Metadatum(:sea_ice_concentration; dataset=ECCO4Monthly())) | ||
|
|
||
| ##### | ||
| ##### A Prescribed Atmosphere model | ||
| ##### | ||
|
|
||
| dir = "./forcing_data" | ||
| dataset = MultiYearJRA55() | ||
| backend = JRA55NetCDFBackend(100) | ||
|
|
||
| atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) | ||
| radiation = Radiation() | ||
|
|
||
| ##### | ||
| ##### An ocean-sea ice coupled model | ||
| ##### | ||
|
|
||
| omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) | ||
| omip = Simulation(omip, Δt=20minutes, stop_time=60days) | ||
|
|
||
| # Figure out the outputs.... | ||
| checkpointer_address(::SeaIceModel) = "SeaIceModel" | ||
|
|
||
| ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, | ||
| schedule = IterationInterval(1000), | ||
| prefix = "ocean_checkpoint_onedegree", | ||
| overwrite_existing = true) | ||
|
|
||
| sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, | ||
| schedule = IterationInterval(1000), | ||
| prefix = "sea_ice_checkpoint_onedegree", | ||
| overwrite_existing = true) | ||
|
|
||
| wall_time = Ref(time_ns()) | ||
|
|
||
| using Statistics | ||
|
|
||
| function progress(sim) | ||
| sea_ice = sim.model.sea_ice | ||
| ocean = sim.model.ocean | ||
| hmax = maximum(sea_ice.model.ice_thickness) | ||
| ℵmax = maximum(sea_ice.model.ice_concentration) | ||
| Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) | ||
| Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) | ||
| umax = maximum(ocean.model.velocities.u) | ||
| vmax = maximum(ocean.model.velocities.v) | ||
| wmax = maximum(ocean.model.velocities.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(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) | ||
| msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) | ||
| msg5 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) | ||
| msg6 = @sprintf("wall time: %s \n", prettytime(step_time)) | ||
|
|
||
| @info msg1 * msg2 * msg4 * msg5 * msg6 | ||
|
|
||
| wall_time[] = time_ns() | ||
|
|
||
| return nothing | ||
| end | ||
|
|
||
| # And add it as a callback to the simulation. | ||
| add_callback!(omip, progress, IterationInterval(1)) | ||
|
|
||
| run!(omip) | ||
|
|
||
| omip.Δt = 30minutes | ||
| omip.stop_time = 58 * 365days | ||
|
|
||
| run!(omip) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| using ClimaOcean | ||
| using ClimaSeaIce | ||
| using Oceananigans | ||
| using Oceananigans.Grids | ||
| using Oceananigans.Units | ||
| using Oceananigans.OrthogonalSphericalShellGrids | ||
| using ClimaOcean.OceanSimulations | ||
| using ClimaOcean.ECCO | ||
| using ClimaOcean.JRA55 | ||
| using ClimaOcean.DataWrangling | ||
| using ClimaSeaIce.SeaIceThermodynamics: IceWaterThermalEquilibrium | ||
| using Printf | ||
| using Dates | ||
| using CUDA | ||
|
|
||
| import Oceananigans.OutputWriters: checkpointer_address | ||
|
|
||
| function synch!(clock1::Clock, clock2) | ||
| # Synchronize the clocks | ||
| clock1.time = clock2.time | ||
| clock1.iteration = clock2.iteration | ||
| clock1.last_Δt = clock2.last_Δt | ||
| end | ||
|
|
||
| synch!(model1, model2) = synch!(model1.clock, model2.clock) | ||
|
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. if you need this please put it in a separate PR and get that merged, because people want to use stuff |
||
|
|
||
| arch = GPU() | ||
|
|
||
| Nx = 2160 # longitudinal direction | ||
| Ny = 1080 # meridional direction | ||
| Nz = 60 | ||
|
|
||
| r_faces = ClimaOcean.ExponentialCoordinate(Nz, -6000) | ||
| z_faces = MutableVerticalDiscretization(r_faces) | ||
|
|
||
| grid = TripolarGrid(arch; | ||
| size = (Nx, Ny, Nz), | ||
| z = z_faces, | ||
| halo = (7, 7, 7)) | ||
|
|
||
| bottom_height = regrid_bathymetry(grid; minimum_depth=15, major_basins=1, interpolation_passes=15) | ||
| grid = ImmersedBoundaryGrid(grid, GridFittedBottom(bottom_height); active_cells_map=true) | ||
|
|
||
| ##### | ||
| ##### A Propgnostic Ocean model | ||
| ##### | ||
|
|
||
| using Oceananigans.TurbulenceClosures: ExplicitTimeDiscretization | ||
| using Oceananigans.TurbulenceClosures.TKEBasedVerticalDiffusivities: CATKEVerticalDiffusivity, CATKEMixingLength, CATKEEquation | ||
|
|
||
| momentum_advection = WENOVectorInvariant() | ||
| tracer_advection = WENO(order=7) | ||
|
|
||
| free_surface = SplitExplicitFreeSurface(grid; cfl=0.7, fixed_Δt=10minutes) | ||
|
|
||
| mixing_length = CATKEMixingLength(Cᵇ=0.01) | ||
| turbulent_kinetic_energy_equation = CATKEEquation(Cᵂϵ=1.0) | ||
|
|
||
| catke_closure = CATKEVerticalDiffusivity(; mixing_length, turbulent_kinetic_energy_equation) | ||
| closure = (catke_closure, VerticalScalarDiffusivity(κ=1e-5, ν=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. @simone-silvestri, why change CATKE defaults? 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. Also it's wrong to add an additional background diffusivity. CATKE already introduces a background diffusivity via the 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. Otherwise I guess it's ok to experiment with different parameter choices, if there are choices that work better we can make them default in Oceananigans. |
||
|
|
||
| ocean = ocean_simulation(grid; Δt=1minutes, | ||
| momentum_advection, | ||
| tracer_advection, | ||
| free_surface, | ||
| closure) | ||
|
|
||
| dataset = ECCO4Monthly() | ||
|
|
||
| set!(ocean.model, T=Metadatum(:temperature; dataset), | ||
| S=Metadatum(:salinity; dataset)) | ||
|
|
||
| ##### | ||
| ##### A Prognostic Sea-ice model | ||
| ##### | ||
|
|
||
| # Default sea-ice dynamics and salinity coupling are included in the defaults | ||
| sea_ice = sea_ice_simulation(grid; advection=WENO(order=7)) | ||
|
|
||
| set!(sea_ice.model, h=Metadatum(:sea_ice_thickness; dataset), | ||
| ℵ=Metadatum(:sea_ice_concentration; dataset)) | ||
|
|
||
| ##### | ||
| ##### A Prescribed Atmosphere model | ||
| ##### | ||
|
|
||
| dir = "./forcing_data" | ||
| dataset = MultiYearJRA55() | ||
| backend = JRA55NetCDFBackend(100) | ||
|
|
||
| atmosphere = JRA55PrescribedAtmosphere(arch; dir, dataset, backend, include_rivers_and_icebergs=true) | ||
| radiation = Radiation() | ||
|
|
||
| ##### | ||
| ##### An ocean-sea ice coupled model | ||
| ##### | ||
|
|
||
| omip = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation) | ||
| omip = Simulation(omip, Δt=20, stop_time=60days) | ||
|
|
||
| # Figure out the outputs.... | ||
|
|
||
| checkpointer_address(::SeaIceModel) = "SeaIceModel" | ||
|
|
||
| ocean.output_writers[:checkpointer] = Checkpointer(ocean.model, | ||
| schedule = IterationInterval(10000), | ||
| prefix = "ocean_checkpoint", | ||
| overwrite_existing = true) | ||
|
|
||
| sea_ice.output_writers[:checkpointer] = Checkpointer(sea_ice.model, | ||
| schedule = IterationInterval(10000), | ||
| prefix = "sea_ice_checkpoint", | ||
| overwrite_existing = true) | ||
|
|
||
| wall_time = Ref(time_ns()) | ||
|
|
||
| using Statistics | ||
|
|
||
| function progress(sim) | ||
| sea_ice = sim.model.sea_ice | ||
| ocean = sim.model.ocean | ||
| hmax = maximum(sea_ice.model.ice_thickness) | ||
| ℵmax = maximum(sea_ice.model.ice_concentration) | ||
| Tmax = maximum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) | ||
| Tmin = minimum(sim.model.interfaces.atmosphere_sea_ice_interface.temperature) | ||
| umax = maximum(ocean.model.velocities.u) | ||
| vmax = maximum(ocean.model.velocities.v) | ||
| wmax = maximum(ocean.model.velocities.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(h): %.2e m, max(ℵ): %.2e ", hmax, ℵmax) | ||
| msg4 = @sprintf("extrema(T): (%.2f, %.2f) ᵒC, ", Tmax, Tmin) | ||
| msg5 = @sprintf("maximum(u): (%.2f, %.2f, %.2f) m/s, ", umax, vmax, wmax) | ||
| msg6 = @sprintf("wall time: %s \n", prettytime(step_time)) | ||
|
|
||
| @info msg1 * msg2 * msg4 * msg5 * msg6 | ||
|
|
||
| wall_time[] = time_ns() | ||
|
|
||
| return nothing | ||
| end | ||
|
|
||
| # And add it as a callback to the simulation. | ||
| add_callback!(omip, progress, IterationInterval(50)) | ||
|
|
||
| run!(omip) | ||
|
|
||
| omip.Δt = 6minutes | ||
| omip.stop_time = 58 * 365days | ||
|
|
||
| run!(omip) | ||
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.
we don't need these right?