Published May 8, 2026 | Version 0.1.0
Software Open

Numerical implementation of "Leak localisation with a measure source convection–diffusion model"

  • 1. MODEMAT
  • 2. ROR icon University of Helsinki

Description

These are the codes for the numerical demonstrations of the manuscript “Leak localisation with a measure source convection–diffusion model” (arXiv:2605.12095) by Thi Tam Dang and Tuomo Valkonen. It should be relatively easy to to use this package and the algorithms it provides for other PDE-based point source localisation problems.

Building

Sorry, although the core of program is written in Rust with a modern dependency management and build process, we also have legacy C++ and Python dependencies, i.e., the Fenicsx PDE library. Therefore, the build process is difficult.

(We admit it, we made a mistake by going with the crowd and using Fenicsx. In the end it would have been less effort to write low-level PDE code in Rust.)

Phase 1: Python and Fenics

Option 1.A that avoids Conda hell, but is more work (macOS and Linux)

Phase 1.A.1: C++ dependencies of Fenics

First install C++ dependencies using Homebrew. Even on Linux, use Homebrew, or install from official sources; distribution packages are usually obsolete and buggy, often non-standard, and will cause problems (see above).

brew install openmpi boost pugixml fmt spdlog hdf5-mpi cmake kahip slepc petsc gsl

(Fenics recommends ParMETIS instead of Kahip, but only the latter is available from Homebrew at the time of writing this.)

There’s no guarantee that this will install compatible versions of these packages. Homebrew, while better than most Linux distributions, is also obsolete in its philosophy: it does not allow easily installing specific versions of packages. Versions known to work are:

package version
boost 1.90.0
cmake 4.2.1
fmt 12.1.0
hdf5-mpi 1.14.6
kahip 3.22
petsc 3.24.3
pugixml 1.15
slepc 3.24.2
spdlog 1.17.0
gsl 2.8

You can get the list of installed versions with:

brew list --versions openmpi boost pugixml fmt spdlog hdf5-mpi cmake kahip slepc petsc gsl
Phase 1.A.2: Python dependencies of Fenics

In this source directory, create and activate a virtual environment for Python, and install Python packages:

python3 -m venv .venv
source .venv/bin/activate
PETSC_DIR=/opt/homebrew/ SLEPC_DIR=/opt/homebrew/ pip install -r requirements.lock

To not have to activate the virtual environment manually every time, and to not mess up your global settings, it is recommended to install direnv and put the following in .envrc in this directory:

source .venv/bin/activate
export PYTHONPATH=$(echo .venv/lib/python*/site-packages)
export PYO3_PYTHON="$(which python)"

(The last two lines are required later.) This template is also available in misc/_envrc. For changes .envrc to take effect, you should use

direnv allow
Phase 1.A.3: Fenicx-basix

Install basix from https://github.com/FEniCS/basix/releases/tag/v0.10.0.post0 according to instructions. First do the C++ bit:

tar xzf basix-0.10.0.post0.tar.gz
cd basix-0.10.0.post0/cpp
mkdir build
cd build
cmake ..
make
make install

Then the Python bit. This has to be done with the venv created above, active.

cd ../../python
pip install .
Phase 1.A.4: Fenicx-dolfinx

Install dolfinx from https://github.com/FEniCS/dolfinx/releases/tag/v0.10.0.post5 according to instructions. First do the C++ bit:

tar xzf dolfinx-0.10.0.post5.tar.gz
cd dolfinx-0.10.0.post5/cpp
mkdir build
cd build
cmake ..
make
make install

Skip the source /usr/local/lib/dolfinx/dolfinx.conf recommended at the end of the compilation. It will likely break things.

Then the Python bit. This has to be done with the virtual environment created above, active.

cd ../../python
python -m scikit_build_core.build requires | python -c "import sys, json; print(' '.join(json.load(sys.stdin)))" | xargs pip install
pip install --check-build-dependencies --no-build-isolation .

If you didn’t already do these steps with direnv above, you should:

export PYTHONPATH=$(echo .venv/lib/python*/site-packages)
export PYO3_PYTHON="$(which python)"

Option 1.B: Conda

You can try to install Fenicsx in Conda according to instructions on the Fenics website. Additionally you need to install scipy:

conda create -n fenicsx-env
conda activate fenicsx-env
conda install -c conda-forge fenics-dolfinx=0.10.0 scipy=1.17.1 mpich

This is, however, unlikely to not work, as Conda, despite its sandboxing separation attempts, conflicts with system packages, or Conda packages have weird ideas. You’re likely to run into runtime problems with the FFCX form compiler (bad bad bad idea, running a C compiler runtime) failing due to something, somewhere, in the extremely fragile Conda setup, trying to load system libraries wrongly, etc.

Option 1.C: Debian/Ubuntu

You may be able to use the system package manager, but beware of obsolete and modified versions. As of 2026–03–23, the packages available in Debian/Ubuntu cause massive memory leaks and eventual system crash.

Phase 2: Rust

You will only need to install the “nightly” Rust compiler and the GNU Scientific Library manually. At the time of writing this README, alg_tools also needs to be downloaded separately.

  1. Install the Rust infrastructure (including Cargo) with rustup.

  2. Install a “nightly” release of the Rust compiler. With rustup, installed in the previous step, this can be done with

    rustup toolchain install nightly
    

Linux / further patching

Due to both Fenics and typical Linux system being completely broken, you may need to do further patching to get things to compile:

  1. I had to set (in my direnv .envrc)

      export PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:/usr/local/lib/pkgconfig/:/usr/lib/aarch64-linux-gnu/pkgconfig/
      export LD_LIBRARY_PATH=/home/linuxbrew/.linuxbrew/lib
    
  2. Some libraries, in particular libfmt and libspdlog installed in Homebrew, may conflict with system versions, that must be removed. Lack of proper sandboxing in legacy Linux distributions, effectively prohibits multiple versions of the same library.

  3. I had to add Libs in /usr/local/lib/pkgconfig/dolfinx.pc the bit -L/home/linuxbrew/.linuxbrew/lib/ -lopenblas. Nothing in the fenics stack seems to explicitly require it. Basix, that depends on openblas, is entirely missing a pkg-config file.

  4. Also export export OMP_NUM_THREADS=1 (in .envrc). We don’t do MPI. We cannot do MPI in Fenics' lame “it’s all just parallel solution of PDEs, with no other computation, ever” aka “single-program multiple-data, with no controller at all” way. If you don’t do this, you may have multiple threads wasting CPU just being there. We try to control the thread count in our code, but OpenMPI on Linux doesn’t seem to respect it.

Building and running the experiments

To compile the program, run

cargo build --release

When doing this for the first time, several dependencies will be downloaded. Now you can run the experiments in the article with

cargo run --release  -- \
-o results -a radon_sliding_fb -a radon_fb --max-iter 20000
experiments/laser_and_mirrors_aux.py experiments/laser_and_mirrors_aux2.py

The -o results option tells pointsource_pde to write results in the results directory. The other options indicate the algorithms and experiments to run, as well as the maximum number of iterations. The double-dash separates the options for the Cargo build system and pointsource_pde.

Visualising the results

The results may be plotted with

python3 ./plot.py results/laser_and_mirrors_aux/radon_sliding_fb

Vary the path to laser_and_mirrors_aux2 and radon_fb for the alternative experiment and basic algorithm.

The script misc/copy_results.sh may be generate the images and copy the results in the manuscript to ../gasleak.

Documentation

Use the --help option to get an extensive listing of command line options to customise algorithm parameters and the experiments performed.

Internals

If you are interested in the program internals, the integrated source code documentation may be built and opened with

cargo doc              # build dependency docs
misc/cargo-d --open    # build and open KaTeX-aware docs for this crate

The cargo-d script ensures that KaTeX mathematics is rendered in the generated documentation through an ugly workaround. Unfortunately, rustdoc is stuck in 80’s 7-bit gringo ASCII world, and does not support modern markdown features, such as mathematics.

Files

pointsource_pde-0.1.0.zip

Files (364.8 kB)

Name Size Download all
md5:e7bde8ce9974883e2839de8cf7bfd35f
364.8 kB Preview Download

Additional details

Funding

Jane and Aatos Erkko Foundation

Software

Programming language
Rust , Python , C++