This project is all about how we create the most basic ocean_only domain to shake things out and get spinning as fast as possible. This is one way of testing everything before we get into our research questions.
Download this project by either:
Running the CrocoDash CLI command:
crocodash template --output ocean_only_case.ipynb --machine glade --notebook crocodash.projects.ocean_only, then filling in the paths it leaves as placeholdersCopying the file from your CrocoDash checkout:
gallery/crocodash/projects/ocean_only.ipynb
Grid Generation¶
The first thing we are going to do is think about how to get a domain. Scaling data is available online, but a 100x100 point domain is relatively quick. If we provide ~40 cores for the ocean, it’ll run within a few minutes.
We’ll pick a 100x100 point horizontal grid and a standard vertical grid.
from CrocoDash.grid import Grid
from CrocoDash.vgrid import VGrid
grid = Grid(
resolution = 0.05, # in degrees
xstart = 278.0, # min longitude in [0, 360]
lenx = 5.0, # longitude extent in degrees
ystart = 7.0, # min latitude in [-90, 90]
leny = 5.0, # latitude extent in degrees
name = "basic_grid",
)
vgrid = VGrid.hyperbolic(
nk = 75, # number of vertical levels
depth = 2000,
ratio=20.0 # target ratio of top to bottom layer thicknesses
)Now that we have our horizontal and vertical grids, we need to setup our bathymetry. Normally, we’d use the Topo.set_from_dataset function to go from a bathymetry dataset to grid bathymetry. However, as a first step we’ll skip the dataset entirely and use an idealized bathymetry. Topo provides helpers mirroring MOM6’s built-in TOPO_CONFIG options, such as spoon, the analytic basin shape used in MOM6’s idealized double gyre case.
from CrocoDash.topo import Topo
topo = Topo(
grid = grid,
min_depth = 9.5, # in meters
)
topo.set_spoon(max_depth = 2000, dedge = 200)
topo.depth.plot()Great! So I’m going to create my case now, and this step will hardly ever change!
from pathlib import Path
from CrocoDash.case import Case
# CESM case (experiment) name
casename = "basic_ocean"
# CESM source root (Update this path accordingly!!!)
cesmroot ="<CESM>"
# Place where all your input files go
inputdir = Path("<inputdir>") / casename
# CESM case directory
caseroot = Path("<casedir>") / casename
case = Case(
cesmroot = cesmroot,
caseroot = caseroot,
inputdir = inputdir,
ocn_grid = grid,
ocn_vgrid = vgrid,
ocn_topo = topo,
project = "<PROJECT>", # Update this with your project code
job_queue = "<JOB_QUEUE>", # PBS queue the run is submitted to
job_wallclock_time = "<WALLCLOCK_1H>", # hh:mm:ss walltime requested for the run
override = True,
machine = "derecho",
compset = "CR_JRA"
)Now, the last step is to generate forcings, which is done as a two step configure and process. Since it can take a long time to get raw data from outside sources, we’re going to use a fake data generator that comes with CrocoDash.
I also think we can run for 60 days. That doesn’t sound too bad.
case.configure_forcings(
date_range = ["2019-01-01 00:00:00", "2019-03-03 00:00:00"],
product_name="reference_ocean",
function_name="get_reference_ocean_data"
)
case.process_forcings()
Cool! Once this is done, we have to ./case.build and ./case.submit in our case directory. Before that though, here’s some things I’d xmlchange to make the domain run faster.
I’d set the
NTASKS = 10, which sets every component to 10 cores, and makes the data atmosphere regridding very fast. (All components share these 10 cores)I’d set the
NTASKS_OCN = 40because of the scaling data we saw: https://crocodile -cesm .github .io /SeaSloth /mom6 _scaling .html I’d set the
ROOTPE = 0, which ensures that all components share the same cores. If I set ROOTPE_OCN=10, it would skip the first 10 cores and run on the next 40 cores.I’d set the
JOB_WALLCLOCK_TIME = 00:30:00 --subgroup case.run, which ensures the queue picks up our job realllly fast.
And there we go! A fake running ocean model! Isn’t that awesome!