Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Energy balance and firn model (EBFM)

PyPI version License

This repository provides a Python implementation of an energy balance and firn model (EBFM).

Using YAC, this model can be coupled to other models.

Basic installation

Create virtual environment

You can use an arbitrary location to create your virtual environment. A common choice is .venv. In the following, we will use $VENV as a placeholder and the path to the virtual environment .venv should be set as follows:

export VENV=/path/to/your/environment/.venv

If you do not already have a virtual environment, you can create one using the following commands, which will additionally install the necessary dependencies specified in pyproject.toml:

python3 -m venv $VENV
source $VENV/bin/activate

Check if your virtual environment is activated. You should see the name within parentheses just before your command prompt, in this case it should say (.venv).

If you want to know more about virtual environments, please refer to the Python documentation.
If you intend to develop EBFM, please take a look at the developer notes further down in the README.

Install EBFM

You can then install EBFM directly into you virtual environment by running the following command:

pip3 install EBFM

This will install the basic version of EBFM without coupling.

Checking your installation

Please check your installation by running ebfm --help to print the help message and ebfm --version to print the installed version.

Installation with coupling features

Before installing EBFM with coupling features, you must install YAC with the Python bindings. Similar to the instructions above, we will use a virtual environment to install all required dependencies. During YAC’s configuration step, set the installation prefix to your virtual environment and enable Python bindings (--prefix=$VENV --enable-python-bindings). Make sure to do this after creating your virtual environment.

The procedure should look similar to below:

python3 -m venv $VENV
# configure and install YAC with --prefix=$VENV and --enable-python-bindings
source $VENV/bin/activate
pip3 install EBFM[cpl]

Adding [cpl] will make sure that additional dependencies needed for coupling, such as yac, are present in your virtual environment.

If you see any errors during the process, please make sure that your virtual environment is activated. If this is the case, you should see the name within parentheses just before your command prompt, in this case it should say (.venv).

If during the installation of EBFM it appears that yac is missing, please double-check with pip3 freeze that the package has been installed properly. For detailed instructions on how to install YAC properly and guidance for troubleshooting, see the YAC documentation on Python bindings.

Running EBFM

Test experiments

After installation, you are able to perform two basic uncoupled simulations, provided you cloned this repository. Every run produces an output file (/Output/model_output.nc), which contains daily output and can be viewed with tools like Ncview. The first test runs EBFM for all glaciers in Svalbard for 1-Jan-1979 (unless --start-time and --end-time are set differently) with a synthetic randomized weather forcing:

ebfm --matlab-mesh examples/dem_and_mask.mat

Another test applies EBFM to the Greenland Ice Sheet and forces it with Copernicus CARRA2 meteorological data for the month May 1990 on a 10-km resolution grid:

ebfm --netcdf-mesh examples/Greenland_CARRA2/grid.nc --fill-missing-elevation --forcing-dir examples/Greenland_CARRA2/forcing --start-time 1990-05-01T00:00:00 --end-time 1990-06-01T00:00:00

Two more tests can be done, simulating the Greenland Ice Sheet for a full year (1990) at spatial resolutions of 2.5 km or 10 km. The faster 10-km resolution test requires this package, whereas the computationally more expensive high-resolution 2.5-km resolution test requires this downloadable package. The zip-files need to be extracted so that the .nc files are in the /examples/ folder prior to running the model with the following commands:

ebfm --netcdf-mesh examples/Greenland_CARRA2/grid.nc --fill-missing-elevation --forcing-dir examples/Greenland_CARRA2/forcing --start-time 1990-01-01T00:00:00 --end-time 1991-01-01T00:00:00

for the 10-km resolution experiment, and as:

ebfm --netcdf-mesh examples/Greenland_CARRA2/grid_fine.nc --fill-missing-elevation --forcing-dir examples/Greenland_CARRA2/forcing_fine --start-time 1990-01-01T00:00:00 --end-time 1991-01-01T00:00:00

for the 2.5-km resolution experiment.

Please note that runs become significantly faster (~3 times) when running with performance optimization (see also Performance and Profiling Runs below), e.g.:

ebfm --netcdf-mesh examples/Greenland_CARRA2/grid_fine.nc --fill-missing-elevation --forcing-dir examples/Greenland_CARRA2/forcing_fine --numba-threads 2 --start-time 1990-01-01T00:00:00 --end-time 1991-01-01T00:00:00

Mesh data

The arguments --matlab-mesh, --elmer-mesh, and --netcdf-mesh allow to provide different kinds of mesh data. The arguments --netcdf-dem-mesh and --netcdf-dem-mesh-unstructured allow to add a Digital Elevation Model (DEM) for --elmer-mesh since it comes without elevation information. EBFM supports the following formats:

For Elmer-based inputs, the argument --elmer-mesh-crs-epsg is needed to define the coordinate reference system (CRS) of the input x/y coordinates. EBFM uses this CRS to convert coordinates to lon/lat (EPSG:4326) internally.

Important: For some larger files we are using Git LFS. Please make sure to install Git LFS.

  • MATLAB Mesh: An example is given in examples/dem_and_mask.mat. This mesh file provides x-y coordinates and elevation data. Please use the argument --matlab-mesh /path/to/your/mesh.mat.

    Usage example:

    ebfm --matlab-mesh examples/dem_and_mask.mat
    
  • NetCDF Mesh: A NetCDF file with latitude, longitude, elevation (orog or orography) and mask on a 2D grid. Please use the argument --netcdf-mesh /path/to/your/mesh.nc.

    Cells with missing elevation are never active. They still enter the slope of neighbouring active cells, so EBFM stops if an active cell borders a missing elevation. The option --fill-missing-elevation sets missing elevations to 0 m instead.

    Usage example:

    ebfm --netcdf-mesh examples/Greenland_CARRA2/grid.nc --fill-missing-elevation
    
  • Elmer Mesh: An Elmer mesh file with x-y coordinates of mesh points and elevation data stored in the z-component. Please use the argument --elmer-mesh /path/to/your/elmer/mesh.

    Usage example:

    ebfm --elmer-mesh examples/greenland_mesh_v0_with_DEM/MESH --elmer-mesh-crs-epsg 3413
    

    Note: You can also use --elmer-mesh examples/greenland_mesh_v0/MESH here, but this will lead to a very unphysical setup with zero elevation in the whole domain. To generate examples/greenland_mesh_v0_with_DEM/MESH please refer to the section Amend elevation data to 2D Elmer mesh below.

  • Elmer Mesh with Elevation data from NetCDF: The Elmer mesh file provides x-y coordinate. An additioal NetCDF file is given to provide elevation data for these x-y coordinates. Please use the arguments --elmer-mesh /path/to/your/elmer/mesh and --netcdf-dem-mesh /path/to/your/elevation.nc

    Usage example:

    ebfm --elmer-mesh examples/greenland_mesh_v0/MESH --netcdf-dem-mesh examples/BedMachineGreenland-v5_lo.nc --elmer-mesh-crs-epsg 3413
    
  • Elmer Mesh with Elevation data from Elmer/Ice XIOS output: The Elmer mesh file provides x-y coordinates. A NetCDF file written by Elmer/Ice through XIOS provides the surface elevation zs and the ice thickness h at the mesh nodes. Cells with more than 1 m of ice are treated as glacier. Please use the arguments --elmer-mesh /path/to/your/elmer/mesh and --netcdf-dem-mesh-unstructured /path/to/your/xios_output.nc. See examples/README.md for the required contents of the file.

    Usage example:

    ebfm --elmer-mesh examples/greenland_mesh_v0/MESH --netcdf-dem-mesh-unstructured examples/greenland_mesh_v0/xios_dem.nc --elmer-mesh-crs-epsg 3413
    

Note that an Elmer mesh must be provided in a directory following the structure:

path/to/your/elmer/MESH/
├── mesh.boundary
├── mesh.elements
├── mesh.header
└── mesh.nodes

The option --is-partitioned-elmer-mesh will tell EBFM that the provided Elmer mesh is a partitioned mesh. A partitioned mesh file follows the structure:

path/to/your/elmer/mesh
    └── MESH
        ├── mesh.boundary
        ├── mesh.elements
        ├── mesh.header
        ├── mesh.nodes
        └── partitioning.128
            ├── part.1.boundary
            ├── part.1.elements
            ├── part.1.header
            ├── part.1.nodes
            ...
            ├── part.128.boundary
            ├── part.128.elements
            ├── part.128.header
            └── part.128.nodes

Usage example for partitioned mesh:

ebfm --elmer-mesh examples/greenland_mesh_v0/MESH/partitioning.128/ --netcdf-dem-mesh examples/BedMachineGreenland-v5_lo.nc --is-partitioned-elmer-mesh --use-part 42 --allow-partition-mismatch

Without --use-part, MPI rank r computes partition r + 1. Rank 0 writes the output of all ranks to a single file, with the cells ordered by their Elmer element id.

A run needs one MPI rank per partition. To compute only some partitions, e.g. a single one with --use-part as above, pass --allow-partition-mismatch.

Note: The partitioned mesh is not included in this repository.

Getting the example data

A reduced-resolution NetCDF file (examples/BedMachineGreenland-v5_lo.nc) is included directly in this repository and can be used as a drop-in for quick testing. See examples/README.md for details on how it was derived from the original dataset.

For the full-resolution dataset and the example Elmer mesh (MESH), refer to the TerraDT testcase repository. Note that access to that repository may need to be requested and requires access to the Levante supercomputer at DKRZ.

Once available, you can either copy or symlink the required files into the examples/ directory of this repository, or point EBFM to their locations using the CLI arguments shown above.

Using reader.py to amend elevation data to examples/greenland_mesh_v0

The helper script reader.py can be used to combine an existing Elmer mesh with a DEM NetCDF file by replacing the z‑coordinates in mesh.nodes ahead of time. This can be useful if you want to preprocess a mesh once and reuse it for multiple EBFM runs.

Assuming the example data has been copied into the examples/ directory as described above, you can run the following command from the repository root:

python3 src/ebfm/reader.py examples/greenland_mesh_v0/MESH examples/BedMachineGreenland-v5.nc --outpath examples/greenland_mesh_v0_with_DEM/MESH --elmer-mesh-crs-epsg 3413

This will write the updated mesh to a new directory. The path examples/greenland_mesh_v0_with_DEM should not already exist. The original examples/greenland_mesh_v0/MESH directory is copied and left unchanged.

Alternatively, you can modify the mesh directly in place, which overwrites mesh.nodes:

python3 src/ebfm/reader.py examples/greenland_mesh_v0/MESH examples/BedMachineGreenland-v5_lo.nc --in-place --elmer-mesh-crs-epsg 3413

The resulting mesh can then be used directly with EBFM similar to the example with the MATLAB file from above:

ebfm --elmer-mesh examples/greenland_mesh_v0_with_DEM/MESH --elmer-mesh-crs-epsg 3413

Working with restart files

You may use restart files with EBFM. To create a restart file at the end of a run, please provide a --restart-dir:

ebfm --matlab-mesh examples/dem_and_mask.mat --restart-dir examples/restart

You can now use the --restart-init option to tell EBFM to use the restart file examples/restart/restart_1979-01-02T00:00:00.nc that you just created as a starting point:

ebfm --matlab-mesh examples/dem_and_mask.mat --restart-dir examples/restart --restart-init --start-time 1979-01-02T00:00:00 --end-time 1979-01-03T00:00:00

Note that it is necessary to provide a --start-time consistent with the given restart file.

Running on several MPI ranks

EBFM splits the grid over the MPI ranks of a run (requires pip install 'ebfm[mpi]'):

mpirun -np 4 ebfm --matlab-mesh examples/dem_and_mask.mat --no-shading
  • MATLAB and NetCDF grids and Elmer meshes are split into contiguous blocks of columns, the first block on rank 0. A partitioned Elmer mesh gives one partition to each rank (see above).
  • With a non-partitioned Elmer mesh, every rank reads the whole mesh, and EBFM warns about it. For large meshes, use a partitioned mesh (requires --netcdf-dem-mesh).
  • Rank 0 writes the output file and --dump-reference for all ranks. They are identical to those of a run on a single rank.
  • Not supported on several ranks, and rejected with an error: shading, --forcing-dir and --restart-dir/--restart-init.
  • --no-check-grid-distribution skips the start-up check that every column is held by exactly one rank.

Performance and Profiling Runs

Multi-threaded Numba kernels (--with-numba), GPU offloading (--with-gpu), timing, output comparison and reproducibility options are described in docs/Performance.md.

Coupled simulation

The EBFM code allows coupling to other simulation codes. The following arguments allow to configure the coupling:

ebfm ...
  --couple-to-elmer-ice
  --couple-to-icon-atmo
  --couple-to-icon-land
  --coupler-config /path/to/coupling/config.yaml

With --couple-to-icon-land, EBFM sends the ice-covered fraction of its grid cells (icefract, albedo, t_sub, ghf_cond, runoff, smb, snowmass) to the ICON land model (ICON-Land/JSBACH) and receives the surface energy balance results of its glacier tile (t_srf, melt, evapotrans, averaged over the EBFM time step), which then drive the firn model instead of EBFM's own energy balance (kept as diagnostic ebm_*). ICON-Land is coupled as a separate YAC component (icon-land) independent of the ICON atmosphere coupling. Note that the abbreviation --couple-to-icon is ambiguous and no longer accepted.

Note that the coupling uses the Python bindings of YAC. Additionally, EBFM must be run in a MPMD (multiple process multiple data) run. Follow the install instructions from above and run the example command for a coupled simulation with Elmer/Ice and ICON:

mpirun -np 1 ebfm \
  --elmer-mesh $MESHES/greenland_mesh_v0/MESH/partitioning.128/ \
  --netcdf-dem-mesh $DATA/BedMachineGreenland-v5.nc \
  --is-partitioned-elmer-mesh --use-part 1 --allow-partition-mismatch \
  --coupler-config $CPL_CONFIG --couple-to-elmer-ice --couple-to-icon-atmo \
  : \
  -np 1 $ELMER_ROOT/src/elmer_dummy_f.x $MESHES/greenland_mesh_v0/MESH/partitioning.128 1 $CPL_CONFIG \
  : \
  -np 1 $ICON_ROOT/src/icon_dummy.x $MESHES/icon_grid_0054_R02B08_G.nc $DATA/mbe3064_atm_elmer_monmean_1979.nc $DATA/varlist_elmerfile

Be aware that the command above requires setting a few environment variables. Assuming your project is structured following this repository, the following settings should help getting started:

export EBFM_DUMMY_REPO=/path/to/TerraDT/ebfm_dummy
export EBFM_REPO=/path/to/this/repo

export CPL_CONFIG=$EBFM_DUMMY_REPO/config/coupling.yaml
export MESHES=$EBFM_DUMMY_REPO/mesh
export DATA=$EBFM_DUMMY_REPO/data

export EBFM_ROOT=$EBFM_REPO
export ELMER_ROOT=$EBFM_DUMMY_REPO/dummies/ELMER
export ICON_ROOT=$EBFM_DUMMY_REPO/dummies/ICON

Depending on the binaries that you want to use $ELMER_ROOT and/or $ICON_ROOT may be set to point to the non-dummy versions of the codes.

Running tests

You can use toxto run the test suite in an isolated environment. Select the tox environment matching your Python version, e.g., py313 for Python 3.13:

tox -e py313

This runs all tests in the tests/ directory.

To run the examples via tox, use:

tox -e examples

Remove build/test artifacts after your run with:

tox -e clean

Note: Replace py313 with the environment for your installed Python version (e.g., py310, py311, py312). To test across multiple Python versions, you need to have those versions installed on your system.
Check your current Python version with:

python3 --version

Alternatively, if you prefer to run your tests directly in your current environment:

pytest -v tests/

Troubleshooting

Numba and GPU runtime problems are covered in docs/Performance.md.

libnetcdf.so not found at runtime

Problem: ./icon_dummy.x: error while loading shared libraries: libnetcdf.so.15: cannot open shared object file: No such file or directory Solution: Try rebuilding icon_dummy.x `

libyaxt_c.so not found at runtime

Problem: ./icon_dummy.x: error while loading shared libraries: libyaxt_c.so.1: cannot open shared object file: No such file or directory

Solution: `export LD_LIBRARY_PATH='$YAXT_INSTALL_DIR/lib/'

#include <proj.h> not found when building the Elmer dummy

Problem:

...
elmer_grid.c:11:10: fatal error: proj.h: No such file or directory
   11 | #include <proj.h>
      |          ^~~~
compilation terminated.
make: *** [Makefile:48: elmer_grid.o] Error 1

Solution: sudo apt-get install libproj-dev

Developer notes

Optional dependencies [dev]

Please install the package with the optional dependencies [dev] if you are developing (this will automatically install pre-commit).

To concatenate multiple optional dependencies, please run

pip3 install EBFM[dev,cpl]

pre-commit

This project uses pre-commit hooks for some tasks described in detail below. To setup pre-commit please do the following:

pipx install pre-commit
pre-commit install

Alternative: If you are already working in an virtual environment, you can also use pip3 install pre-commit instead of pipx. Refer to the documentation of pipx for further information.

As soon as pre-commit is set up, you will not be able to commit if any of the checks fails. With the help of the logging output it should usually be possible to fix the problem.

Note: You can bypass this check with --no-verify. Please note that the CI will also run pre-commit and fail if there are problems in any of the checks. Therefore, it is recommended to use the pre-commit hooks locally before pushing code to this repository and only bypass them if there is a good reason.

This project uses REUSE to track information regarding copyright and licensing. Therefore, all files in this repository are required to provide the corresponding information. Please refer to the documentation of REUSE for details.

You can use pre-commit to automatically check if all files in the repository provide the necessary information:

pre-commit run reuse --all-files

Code formatting

Automated checks for PEP8 compiance are implemented following 1 with some modifications. You can use pre-commit hooks to automatically format your code with black:

pre-commit run black --all-files

With flake8 you can check whether your code follows all relevant formatting rules:

pre-commit run flake8 --all-files

Please note that black might not be able to automatically fix all problems and therefore flake8 might fail even if you have run black before. In this case, you will have to manually fix the remaining problems.

Further hints

  • Please consider installing EBFM via pip3 --editable . if you are developing the package.

  1. https://ljvmiranda921.github.io/notebook/2018/06/21/precommits-using-black-and-flake8/ ↩

Metadata

Release files for EBFM 0.9.0.dev1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for EBFM 0.9.0.dev1
File Size Uploaded Provenance
ebfm-0.9.0.dev1.tar.gz 587.5 kB With provenance Details

Release files / ebfm-0.9.0.dev1.tar.gz

Download URL ebfm-0.9.0.dev1.tar.gz
Size 587.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5eb376f877b3e11febf32f82da6fed3942a78e587e0582de58a463447500211d
BLAKE2b-256 checksum
How to use checksums
1297f1529ee5086681b115bba62dcab6c8bfc255063a7bd266d3527e7b8f20e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for EBFM 0.9.0.dev1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 1 file in this release has been uploaded with provenance metadata.

Attestation for ebfm-0.9.0.dev1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page