Rust wrapper for FEFF10, a real-space multiple-scattering code for ab initio calculations of X-ray absorption spectra (EXAFS, XANES), electronic structure, and related properties.
The 18 Fortran modules of FEFF10 are compiled into a single static library (libfeff10.a) and linked directly into the Rust binary via FFI — no external executables or runtime dependencies required.
- Single self-contained binary (~26-29 MB depending on compiler)
- All 18 FEFF10 stages linked statically (MKL, Fortran runtime included)
- Supports 3 Fortran compilers: gfortran, ifx (Intel), flang-new (LLVM)
- Prebuilt binaries — no Fortran compiler needed with
--features prebuilt - C library distribution (
libfeff10.a+feff10.h) for use from other languages - Built-in benchmarking and output comparison tools
- Progress bar and per-stage timing
No Fortran compiler required. The prebuilt libfeff10.a is automatically downloaded from GitHub releases:
cargo build --release --features prebuiltOr provide your own prebuilt library:
FEFF10_LIB_DIR=./lib cargo build --release --features prebuiltRequires a Fortran compiler and a BLAS/LAPACK implementation (MKL preferred).
# Default (gfortran + auto-detected MKL or system BLAS, -march=native)
cargo build --release
# Intel Fortran (ifx) — needs oneAPI installed
FEFF_FC=/opt/intel/oneapi/compiler/latest/bin/ifx cargo build --release
# LLVM Flang
FEFF_FC=flang-new cargo build --release
# Portable binary for distribution (-march=x86-64-v3, AVX2+FMA, ~2013+ CPUs)
FEFF_PORTABLE=1 cargo build --releaseOn Linux, the build system automatically detects MKL (from oneAPI) and falls back to OpenBLAS or system LAPACK. On macOS, the default is the built-in naive solver for stability; set FEFF_BLAS='-framework Accelerate' to opt in to Accelerate. All dependencies are linked statically — the resulting binary has no special runtime requirements.
| Variable | Description |
|---|---|
FEFF_FC |
Fortran compiler path (default: auto-detect) |
FEFF_FFLAGS |
Override all Fortran flags |
FEFF_PORTABLE |
Use -march=x86-64-v3 for distributable binaries |
FEFF_MARCH |
Explicit -march= value (e.g. x86-64-v2) |
FEFF_NO_NATIVE |
Disable -march entirely |
FEFF_LTO |
Enable link-time optimization |
FEFF10_LIB_DIR |
Path to prebuilt libfeff10.a (with --features prebuilt) |
FEFF10_LIB_SHA256 |
Expected SHA256 of prebuilt libfeff10.a (optional override) |
# Run a FEFF calculation
feff10-rs run path/to/feff.inp
# Run with explicit working directory
feff10-rs run path/to/feff.inp -w /tmp/work
# Run only specific stages
feff10-rs run path/to/feff.inp -s rdinp,pot,xsph
# Validate a feff.inp file
feff10-rs validate path/to/feff.inp
# Compare two xmu.dat files
feff10-rs compare file1.dat file2.dat
# Benchmark (3 iterations, JSON output)
feff10-rs bench path/to/feff.inp -n 3 -o results.json -l my-labelvalidate uses strict parsing and reports line-numbered errors for malformed
CONTROL, PRINT, POTENTIALS, and ATOMS records.
Each release includes libfeff10.a (static library) and feff10.h (C header) for Linux, macOS, and Windows. These can be used to call FEFF10 from C, C++, Python (via ctypes/cffi), or any language with C FFI support.
#include "feff10.h"
// Write feff.inp, chdir to working directory, then:
feff_rdinp();
feff_pot();
feff_xsph();
feff_fms();
feff_path();
feff_genfmt();
feff_ff2x();Linker flags (platform-dependent):
- Linux (ifx+MKL):
-lfeff10 -lpthread -lm -ldl(MKL and Intel runtime are merged into the.a) - macOS (gfortran):
-lfeff10 -lgfortran -framework Accelerate - Windows (gfortran):
-lfeff10 -lgfortran -lpthread -lm
Benchmarked on AMD Ryzen 9 7940HS (Zen4, 16 threads), Arch Linux, all using static MKL (sequential). Each test averaged over 3 iterations.
| Compiler | EXAFS Cu | XANES Cu | Binary Size |
|---|---|---|---|
| ifx 2025.3 | 0.72 s | 7.37 s | 29 MB |
| gfortran 15.2 | 0.79 s | 9.69 s | 26 MB |
| flang-new 21.1 | 1.22 s | 15.98 s | 28 MB |
| Stage | gfortran | ifx | flang-new |
|---|---|---|---|
| pot | 5.903 | 4.416 | 9.354 |
| fms | 2.041 | 1.494 | 3.640 |
| screen | 1.210 | 0.929 | 2.218 |
| mkgtr | 0.247 | 0.191 | 0.347 |
| xsph | 0.172 | 0.224 | 0.302 |
| atomic | 0.072 | 0.070 | 0.064 |
| Total | 9.69 | 7.37 | 15.98 |
All three compilers produce identical XANES Cu xmu.dat output (0.000% deviation across all pairwise comparisons).
- ifx is the fastest overall — 24% faster than gfortran, 54% faster than flang-new on XANES Cu. The advantage comes from
potandfmsstages which are dominated by dense linear algebra (MKL matrix operations). - gfortran produces the smallest binary and is the most portable. Good default choice.
- flang-new (LLVM Flang) works but is significantly slower, likely due to less mature optimization passes for Fortran-specific patterns.
- ifx requires the
-no-vecflag as a workaround for an ICE in the VPlan vectorizer onff2chijas.f90(ifx 2025.3). - All compilers use
-fPIC(required for Rust's PIE executables) and static MKL (sequential, no OpenMP — FEFF10 code is serial).
feff10-rs/
├── feff10/ # FEFF10 Fortran source (git submodule)
├── crates/
│ ├── feff10-sys/ # Build system + FFI bindings
│ │ ├── build.rs # Fortran compilation, driver patching, static linking
│ │ ├── include/feff10.h # C header for library usage
│ │ └── src/lib.rs # extern "C" declarations for 18 FEFF stages
│ ├── feff10/ # Safe Rust wrapper
│ │ ├── src/pipeline.rs # Pipeline orchestration (fork per stage)
│ │ ├── src/stage.rs # Stage enum + FFI dispatch
│ │ ├── src/input.rs # feff.inp parser
│ │ └── src/output.rs # xmu.dat reader + comparison
│ └── feff10-rs/ # CLI binary
└── Cargo.toml
-
Build time (
build.rs): The Fortranprogramentry points are patched tosubroutine ... bind(C)in a copy of the source. All objects are compiled and archived intolibfeff10.a, merged with MKL and the Fortran runtime. With--features prebuilt, this step is skipped and a prebuilt library is used instead. -
Runtime: Each FEFF stage runs in a
fork()-ed child process to isolate Fortran module state (global allocatable arrays, I/O units). This matches the original FEFF behavior where each stage was a separate executable.
The Rust wrapper code (feff10-rs) is dual-licensed under MIT or Apache-2.0, at your option.
The FEFF10 Fortran source code (in the feff10/ submodule) is copyright (c) 2020 FEFF Project, University of Washington and SLAC National Accelerator Laboratory, and is distributed under its own license. This software is based on or developed using FEFF10.0.
All licenses permit redistribution and use in source and binary forms, with or without modification, subject to their respective conditions. See LICENSE-MIT, LICENSE-APACHE, and feff10/LICENSE for full terms.