• Prerequisites & Dependencies
• Get the code — git clone
Section 01: Containerized Builds
• Docker — Part 1 · activate + create container
• Docker — Part 2 · shell + compile
• Apptainer (HPC) — Part 1 · activate + create .sif
• Apptainer (HPC) — Part 2 · shell + compile
Section 02: Native Build
• 1. Set up system dependencies
• 2. Compile (basic / trimesh / MPI / CUDA)
• 3. Run the model
Section 03: Advanced & Troubleshooting
• Hybrid Build Combinations
• Scalability Guidelines
• Common Build Errors
• Build Summary
What FLUXOS links against at compile time. Installation commands come later — the container path handles them for you, the native path lists package names per OS.
| CMake | ≥ 3.18 |
| C++ compiler | C++17 (GCC 7+, Clang 5+) |
| Armadillo | linear algebra |
| nlohmann/json | JSON config parser (header-only) |
| HDF5 | binary I/O backend |
| OpenMP | shared-memory parallelism |
| OpenMPI / MPICH | distributed computing — enables USE_MPI=ON |
| CUDA Toolkit | ≥ 11.0 — enables USE_CUDA=ON |
| Gmsh | mesh generation (triangular domain preprocessing) |
git clone
Every method in the rest of this deck starts from the
repository root. Clone once, cd into it,
and keep that as your working directory for every command that follows.
# Clone the FLUXOS source git clone https://github.com/ue-hydro/FLUXOS_cpp.git # Enter the repo — all container recipes, Python scripts and sample # inputs are referenced relative to this directory. cd FLUXOS_cpp
containers/ — Dockerfile + Apptainer .def filessrc/fluxos/ — C++ sourcebin/ — DEMs, meshes, forcing, modset examplessupporting_scripts/ — Python config + post-processing templatesmain is the stable branch;
development collects feature-branch integrations.
Switch with git checkout development if you want the latest
work-in-progress.
Recommended starting point — zero host dependencies, works identically on macOS, Linux, Windows, and HPC clusters.
Two steps on the host: install Docker, then build the container image. The image ships every FLUXOS build-time dependency and the source tree. It does not compile FLUXOS yet — that's step 4, on the next slide.
# macOS / Windows: install & launch Docker Desktop (https://www.docker.com/products/docker-desktop) # Linux: install Docker Engine (https://docs.docker.com/engine/install/) # Sanity check (bash / zsh — macOS & Linux): docker --version && docker compose version # Sanity check (Windows PowerShell — `&&` is unsupported in PowerShell 5.1): # docker --version ; docker compose version
# From the repo root. Installs CMake, GCC, Armadillo, HDF5, nlohmann/json, OpenMP. docker compose -f containers/docker-compose.yml build # Add MPI support (optional) — brings OpenMPI into the image. # bash / zsh (macOS & Linux): USE_MPI=ON docker compose -f containers/docker-compose.yml build # Windows PowerShell equivalent (set the env var first, then build): # $env:USE_MPI="ON"; docker compose -f containers/docker-compose.yml build # Windows cmd.exe equivalent: # set USE_MPI=ON&& docker compose -f containers/docker-compose.yml build
&&; use
; to chain commands and $env:VAR="value" to set
environment variables. PowerShell 7+ accepts && but
not VAR=value cmd — always use $env: first.
With the container image ready, open a shell and compile FLUXOS.
The whole repo is bind-mounted at /work, so every file
the build writes lands on the host automatically.
# Drops you at a bash prompt inside the container. The host repo is # bind-mounted at /work, so sources, bin/, and any Results*/ folders # are the same files on the host and in the container. docker compose -f containers/docker-compose.yml run --rm fluxos
# You are now inside the container (default shell is bash). /work is # the bind-mounted repo root. Each command is on its own line so the # snippet survives multi-line paste in any host terminal — including # Windows PowerShell, which can mangle && chains. cd /work mkdir -p build cd build # -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/work/bin drops the binary onto the host's ./bin/ cmake -DMODE_release=ON \ -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/work/bin /work make -j$(nproc) # Run from /work so the relative paths inside the modset resolve against # Example for the bind-mounted inputs at /work/Working_example/ . Simulation outputs # land at whichever folder the modset's OUTPUT_FOLDER names. cd /work ./bin/fluxos Working_example/modset_river_30h.json
USE_MPI=ON env var
in step 2 installs OpenMPI inside the image; you must also pass
-DUSE_MPI=ON to cmake here in step 4 for FLUXOS to link
against it. The resulting binary is then ./bin/fluxos_mpi — launch
with mpirun -n N ./bin/fluxos_mpi Working_example/modset.json
(still from /work).
Apptainer (formerly Singularity) runs rootless on HPC clusters and mounts user home directories transparently. Two recipes are provided: fluxos_apptainer.def (CPU + OpenMP + MPI) and fluxos_apptainer_cuda.def (CUDA + MPI). Neither compiles FLUXOS during image build — that's step 4, next slide.
# Most HPC systems provide Apptainer as a module (or: module load singularity) module load apptainer # Sanity check apptainer --version # Local install (workstation): https://apptainer.org/docs/admin/main/installation.html
# CPU + OpenMP + MPI — run from the repo root apptainer build --fakeroot fluxos_cpu.sif \ containers/fluxos_apptainer.def # CUDA + MPI (GPU nodes) — the resulting run must use --nv to expose host GPUs apptainer build --fakeroot fluxos_cuda.sif \ containers/fluxos_apptainer_cuda.def
Apptainer .sif images are read-only, so compile into a bind-mounted host
directory. The container's source tree lives at /opt/fluxos;
point CMake at it and build into the writable mount.
# CPU shell with the current dir bind-mounted at /src (writable) apptainer shell --bind $PWD:/src fluxos_cpu.sif # CUDA shell — --nv exposes host GPUs + drivers apptainer shell --nv --bind $PWD:/src fluxos_cuda.sif
# You are now inside the container. Source tree is at /opt/fluxos (read-only). cd /src mkdir -p build cd build # -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/src/bin → binary appears on the host at ./bin/ cmake -DMODE_release=ON -DUSE_MPI=ON \ -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/src/bin /opt/fluxos make -j$(nproc) # Run from /src so the modset's relative paths resolve against Working_example/ cd /src ./bin/fluxos_mpi Working_example/modset_river_30h.json # Multi-process MPI: launch from the login node using `apptainer exec` # (exit the shell first) mpirun -n 16 apptainer exec --bind $PWD:/src fluxos_cpu.sif \ /src/bin/fluxos_mpi /src/Working_example/modset.json
⚠️ Commands below target Debian / Ubuntu with apt.
Other systems (macOS Homebrew, Fedora / RHEL dnf,
Arch pacman, Windows WSL) need equivalent package-manager tweaks
— the CMake options themselves are identical.
You should already be in the repo root from slide 4
(git clone & cd FLUXOS_cpp).
Install the toolchain and libraries FLUXOS links against. All commands
below target Debian / Ubuntu; adjust for your package manager.
# 1. Compiler + build tools (GCC 7+ or Clang 5+ for C++17) sudo apt install build-essential cmake git ca-certificates # 2. Required libraries — always needed sudo apt install libarmadillo-dev nlohmann-json3-dev libhdf5-dev libomp-dev # 3. Optional: MPI (for multi-node / multi-process runs) sudo apt install libopenmpi-dev openmpi-bin # 4. Optional: CUDA Toolkit ≥ 11.0 for GPU builds # Follow NVIDIA's instructions at https://developer.nvidia.com/cuda-downloads # Verify the driver is installed nvidia-smi
brew install cmake gcc armadillo nlohmann-json hdf5 libomp open-mpi
dnf install ... with equivalent package names.
All variants share the same CMake pattern — only the feature flags differ.
# Generic pattern (run from the repo root). Linux / macOS / WSL bash:
mkdir build
cd build
cmake -DMODE_release=ON <flags> ..
make -j$(nproc)
| Variant | CMake flags | Produces | Needs |
|---|---|---|---|
| Basic (regular mesh) | -DMODE_release=ON |
build/bin/fluxos |
toolchain only |
| Triangular mesh | -DUSE_TRIMESH=ON |
build/bin/fluxos with src/fluxos/trimesh/ |
same as basic |
| MPI (distributed) | -DUSE_MPI=ON |
build/bin/fluxos_mpi |
OpenMPI / MPICH |
| CUDA (GPU) | -DUSE_CUDA=ON |
build/bin/fluxos_cuda |
CUDA Toolkit ≥ 11.0, compute ≥ 6.0 |
| Hybrid trimesh + CUDA | -DUSE_TRIMESH=ON -DUSE_CUDA=ON |
CUDA-accelerated trimesh solver | both |
-DMODE_release=ON) enables -O3 -march=native -flto.
Debug mode (default) adds -g3 -Wall and produces a _debug suffix binary.
The modset JSON is the single argument. Paths inside the modset are resolved relative to the working directory from which you launch the binary.
# Coming from slide 12 you ended in build/; step back to the repo root # so the relative paths inside the modset resolve against the right place. cd .. # Basic / trimesh run (OpenMP threads auto-detected) ./build/bin/fluxos Working_example/modset.json # Control OpenMP threads explicitly OMP_NUM_THREADS=8 ./build/bin/fluxos Working_example/modset_trimesh.json # MPI: distributed across N processes mpirun -np 16 ./build/bin/fluxos_mpi Working_example/modset.json # Hybrid MPI + OpenMP (4 MPI procs × 4 threads each) export OMP_NUM_THREADS=4 mpirun -np 4 ./build/bin/fluxos_mpi Working_example/modset.json # GPU run ./build/bin/fluxos_cuda Working_example/modset_trimesh.json
Per-timestep snapshots land in OUTPUT.OUTPUT_FOLDER (from the modset).
Regular mesh → <sec>.txt, triangular → <sec>.vtu.
Run supporting_scripts/2_Read_Outputs/read_output_template.py
for an HTML statistics report; fluxos_viewer.py for KML / WebGL / MP4.
All CMake flags can be combined for maximum flexibility:
| Configuration | CMake Command | Use Case |
|---|---|---|
| OpenMP only | cmake -DMODE_release=ON .. |
Single workstation |
| MPI + OpenMP | cmake -DMODE_release=ON -DUSE_MPI=ON .. |
Multi-node HPC |
| Trimesh + CUDA | cmake -DMODE_release=ON -DUSE_CUDA=ON .. |
Single GPU workstation |
| Full hybrid | cmake -DMODE_release=ON -DUSE_MPI=ON -DUSE_CUDA=ON .. |
Multi-GPU HPC cluster |
| Domain Size | Recommended Configuration | Approx. Cores |
|---|---|---|
| < 1,000 × 1,000 | OpenMP only (single node) | 4–16 |
| 1,000 – 5,000² | MPI (4–16 processes) | 16–64 |
| 5,000 – 10,000² | MPI (16–64 processes) | 64–256 |
| > 10,000² | MPI (64+ processes) or CUDA | 256+ |
# Install Armadillo development package sudo apt install libarmadillo-dev # Or set path manually cmake -DARMADILLO_INCLUDE_DIR=/path/to/armadillo ..
# Ensure nvcc is in PATH (Linux / macOS / WSL bash): export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH # Windows PowerShell equivalent (CUDA on Windows native): # $env:PATH = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\bin;" + $env:PATH
# CMake should auto-detect, but if not:
cmake -DCMAKE_CXX_COMPILER=mpicxx ..
# nlohmann/json is header-only sudo apt install nlohmann-json3-dev # Or download single header: # https://github.com/nlohmann/json/releases
# Quick start: clone, build, run (native — Linux / macOS / WSL bash)
git clone https://github.com/ue-hydro/FLUXOS_cpp.git
cd FLUXOS_cpp
mkdir build
cd build
cmake -DMODE_release=ON ..
make -j$(nproc)
cd ..
./build/bin/fluxos Working_example/modset.json
# Quick start: containerized (no host dependencies) # Linux / macOS / WSL bash, OR Windows PowerShell — works as-is in both: git clone https://github.com/ue-hydro/FLUXOS_cpp.git cd FLUXOS_cpp docker compose -f containers/docker-compose.yml build docker compose -f containers/docker-compose.yml run --rm fluxos \ bash -c "cd /work && mkdir -p build && cd build && \ cmake -DMODE_release=ON \ -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/work/bin /work && \ make -j\$(nproc) && \ cd /work && ./bin/fluxos Working_example/modset.json"
Native build on Windows requires WSL2 (run the bash snippet inside Ubuntu/WSL).
The Docker snippet works on Windows PowerShell, cmd.exe, bash, and zsh
without changes — the multi-line && chain runs
inside the container's bash shell, not on the host.
CMake 3.18+, C++17, Armadillo, nlohmann/json
CUDA 11+, OpenMPI, Gmsh
USE_TRIMESH, USE_CUDA, USE_MPI
GitHub: github.com/ue-hydro/FLUXOS_cpp
Documentation: fluxos-cpp.readthedocs.io
Contact: diogo.costa@uevora.pt