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

  1. 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 stale compila.sh or half-finished README) are often the fastest way to learn the model's real toolchain/dependency requirements before touching Spack.
  2. Scaffold the layout above; copy an existing model's build.sh/ write-modulefile.sh as a starting point — xbeach for "simple, GCC-only, no deps split", delft3d for "needs multiple Spack envs", riskscape for "no compilation at all."
  3. Get a build working before worrying about polish.
  4. Find (or download from the model's own site) a real benchmark case, not a synthetic one, and wire up test/verify.sh.
  5. Write VERSIONS.md and the "why" parts of README.md while 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 . blindlysources/, install/, and build/ are gitignored per-model, but double-check git status before a broad add, especially after adding a new model (the .gitignore needs 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 from install//build//sources/.
  • modulefiles/ is not part of this repo (it's shared runtime state, generated by build.sh --install) — don't try to git add anything 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.