GEOCEAN — Model Development
How the group's numerical models are built and maintained on the SCI-UC cluster. If you just want to run a model, see Software Modules instead — this page is for building a new version, fixing a build, or adding a new model.
Where everything lives
/nfs/software/geocean/
models/ # this git repo — per-model build recipes (see below)
modulefiles/ # generated by models/*/build.sh --install — NOT in git,
# shared runtime state, rebuilt from models/ on demand
spack/ # shared Spack instance — environments, package cache
conda/ # shared conda installation
<name>/ # LEGACY, pre-dates this convention — see "Cleaning up
# legacy directories" below. Confusingly same-named as
# models/<name>/ but NOT the same thing — do not use.
If you see a bare /nfs/software/geocean/xbeach/ (or swan/, delft3d/,
etc. — no models/ in the path), that's the old hand-built copy, not this
workspace. Always go through models/<name>/ and the published module
(module load <name>) instead. See "Cleaning up legacy directories" below.
models/ is its own git repository, separate from this cluster-docs
one. It holds the recipes (scripts, config, documentation, small test
inputs) — never the actual compiled binaries or large source checkouts,
which are gitignored and rebuilt locally by each maintainer.
cd /nfs/software/geocean/models
git status # see what's changed since the last commit
git log --oneline -10 # recent history
The canonical reference is
models/README.md — this
page is a shorter entry point into it, not a replacement. Read that file
(and the per-model README.md/VERSIONS.md under
models/<name>/) before touching a build; it documents every non-obvious
toolchain decision and quirk hit getting each model working, which this
page only summarizes.
The workspace convention
Every model directory under models/ has (roughly) this shape:
<model>/
README.md # what's built, how, and every quirk hit getting there
VERSIONS.md # every version ever built here, including legacy/superseded ones
build-config.yaml # revision/paths/target — edit this, not build.sh, for routine changes
build.sh # --configure / --build / --install (steps vary by model, see below)
spack/ # spack.yaml (if any) + write-modulefile.sh
sources/ # gitignored — private per-version source checkout
install/<version>/ # gitignored — the actual compiled binaries
test/ # a real benchmark case + expected/ output + verify.sh
bin/ # sbatch template(s)
Not every model needs every piece — see each model's own README.md for
what actually applies (some have no --configure step, some need
multiple Spack environments, riskscape needs none at all). The shape
above is the starting template, not a rigid requirement.
Spack environments — which one to activate
Almost every model has its own Spack environment under
models/*/spack/ (declared in spack.yaml, installed under
/nfs/software/geocean/spack/var/spack/environments/). Activate the
right one before touching a build:
source /nfs/software/geocean/spack/share/spack/setup-env.sh
spack env activate <env-name>
spack install # if the env has never been concretized/installed
| Model | Spack env(s) | What it provides |
|---|---|---|
| xbeach | xbeach-deps |
GCC 12, OpenMPI, HDF5, NetCDF-C/Fortran, Python |
| delft3d | delft3d-deps (Intel), delft3d-deps-gcc (GCC), petsc-intel, esmf-tool |
Split across 4 envs — Intel for anything with a compiled Fortran interface, GCC for C/C++-only deps; see delft3d/README.md for why this can't be one env |
| swan | swan-deps |
Intel oneAPI, NetCDF-Fortran, METIS |
| swash | (none) | Builds directly against the system ifx — no extra deps needed |
| schism | schism-deps |
GCC 12, OpenMPI, HDF5, NetCDF-C/Fortran, CMake, Python |
| sfincs | sfincs-deps |
GCC 12, NetCDF-C (+szip), autotools, binutils |
| snapwave | snapwave-deps |
GCC 12 (explicit), NetCDF-Fortran/-C, binutils |
| lisflood | lisflood-deps |
GCC 12, NetCDF-C, numactl, CMake, binutils |
| riskscape | (none) | Prebuilt Java app — uses the system's /usr/lib/jvm/java-17-openjdk directly |
spack find inside an activated env shows what's actually installed;
spack env list shows every environment that exists (there are a couple
of superseded ones too — delft3dfm202606, xbeach-env-6157 — left over
from earlier attempts, not part of the current build flow, see
VERSIONS.md/README.md in the relevant model for why).
Spack's unify: true means one compiler per language for the whole
environment, not per-package — this is the single most common source
of confusing concretization failures. If you need to mix toolchains
(Intel for Fortran, GCC for a C-only dependency), split into separate
envs rather than fighting the concretizer. See
models/README.md's "Toolchain notes" section for this and every other
non-obvious lesson learned building these (compressed-debug-section
linker issues, hdf5's szip variant, Fortran module-dependency races
under parallel make, GCC-version ABI mismatches, and more) — read it
before debugging a build failure that looks unfamiliar, there's a decent
chance it's already documented there.
Building a new revision of an existing model
cd /nfs/software/geocean/models/<model>
# edit build-config.yaml: revision, source_dir/download_url, install_prefix
./build.sh --configure # not every model has this step — check build.sh --help
./build.sh --build
./build.sh --install # writes modulefiles/<model>/<revision>.lua
Each step is independently rerunnable — don't rerun the whole pipeline just to retry a failed build step. After a successful install:
cd test/
./verify.sh # run the model against the reference case first
Installing a new version does not silently change the default
(module load <model> with no version) — bump
modulefiles/<model>/.version by hand once you've verified the new build
against test/.
Adding a brand-new model
- Check for an existing hand-built version somewhere in
/nfs/software/geocean/first — there usually is one (see "Cleaning up legacy directories" below for where these currently live; they'll move as that cleanup proceeds), and its build script/notes (even a stalecompila.shor half-finishedREADME) are often the fastest way to learn the model's real toolchain/dependency requirements before touching Spack. - Scaffold the layout above; copy an existing model's
build.sh/write-modulefile.shas a starting point — xbeach for "simple, GCC-only, no deps split", delft3d for "needs multiple Spack envs", riskscape for "no compilation at all." - Get a build working before worrying about polish.
- Find (or download from the model's own site) a real benchmark case,
not a synthetic one, and wire up
test/verify.sh. - Write
VERSIONS.mdand the "why" parts ofREADME.mdwhile the reasoning is still fresh.
Full detail (including the git-sparse-checkout trick for repos without
tags, what to do when a model has no public repo at all, and the exact
patterns used for verification) is in models/README.md.
Cleaning up legacy directories (in progress, as of 2026-08-26)
/nfs/software/geocean/ predates models/ and still has the old
hand-built model directories sitting at its root, same-named as (but
not the same as) models/<name>/: delft3d/, xbeach/, swan/,
swash/, schism/, sfincs/, snapwave/, lisflood/, riskscape/.
Alongside those, several self-evidently old/junk directories:
Delft3D_VIEJO/, spack_old/, swa/, viejo/, netcdf_fortran_borrar/,
nuevo/, plus hand-built dependency installs (mpich/, netcdf/,
zlib/, intel/) now redundant with each model's own Spack environment.
Together these account for roughly 45G, on top of ~20G more in intel/
and the dependency dirs.
models/ has been verified independent of all of it — no build or
runtime path in any of the 9 models here touches those legacy
directories; the only mentions are provenance notes in
VERSIONS.md/README.md files about where a pre-existing hand-built
binary came from. Full detail and the size breakdown are in
models/README.md's "Cleaning up /nfs/software/geocean/ beyond
models/" section — that's the canonical, up-to-date reference; this is
just a pointer.
Not yet resolved: NEW/ (9.2G) is a full OpenFOAM build, unrelated to
any of the 9 models and not covered by this cleanup — it needs someone to
decide whether OpenFOAM joins this convention as a 10th model or gets
dropped.
Until the legacy directories are actually archived/removed, always load
models through module load <name> (published from models/<name>/) and
never reference a bare /nfs/software/geocean/<name>/ path directly —
that's the old copy.
Git workflow
cd /nfs/software/geocean/models
git status # review what changed
git diff <model>/README.md # review individual files before staging
git add <model>/ # stage one model's worth of changes at a time
git commit -m "..."
- Never
git add -A/git add .blindly —sources/,install/, andbuild/are gitignored per-model, but double-checkgit statusbefore a broad add, especially after adding a new model (the.gitignoreneeds a matching entry for each new model's generated directories, or its build products will show up as untracked). - Review large or binary-looking additions before committing — some
test/case/inputs are legitimately large (real benchmark grids, reanalysis-derived rasters), that's expected, but confirm you're not accidentally staging something frominstall//build//sources/. modulefiles/is not part of this repo (it's shared runtime state, generated bybuild.sh --install) — don't try togit addanything under/nfs/software/geocean/modulefiles/.
Open items
- [ ] Decide on a review process (PR-equivalent, or just direct commits)
for changes to
models/. - [ ] Document how to roll back a bad default-version bump
(
modulefiles/<model>/.version). - [ ] Grep the cluster for hardcoded references to the legacy
/nfs/software/geocean/<name>/paths before archiving them (other users' scripts/crontabs may still point there). - [ ] Decide OpenFOAM's (
NEW/) fate — 10th model, or drop. - [ ] Archive the confirmed-unused legacy directories listed above once step 1 is done.