# \[ANN\] Enumlib.jl: a package for derivative structure enumeration

**URL:** <https://discourse.julialang.org/t/ann-enumlib-jl-a-package-for-derivative-structure-enumeration/139475>\
**Category:** Package Announcements\
**Tags:** package, hpc, materials-science, chemistry, dft\
**Created:** [September 15, 2026, 2:29am UTC](https://discourse.julialang.org/t/ann-enumlib-jl-a-package-for-derivative-structure-enumeration/139475 "2026-09-15T02:29:31Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gus\_Hart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gus_hart/32/6987_2.png) [@Gus\_Hart](https://discourse.julialang.org/u/Gus_Hart)\
**Post date:** [September 15, 2026, 2:29am UTC](https://discourse.julialang.org/t/ann-enumlib-jl-a-package-for-derivative-structure-enumeration/139475/1 "2026-09-15T02:29:31Z")

</div>

Most users of my original [enumlib](https://github.com/msg-byu/enumlib) will go on calling it (this new code) from inside Python, obliviously—so this probably appeals only to a handful of computational materials scientists here. But it is the culmination of a couple of years of careful work, and I would rather it be findable than not.

Enumlib.jl generates the symmetry-distinct supercells and atomic decorations of a parent lattice—the building blocks for cluster-expansion fits and configuration sampling in alloy theory. It is a from-scratch Julia reimplementation of the Fortran [enumlib](https://github.com/msg-byu/enumlib) (which I also wrote, years ago), and it is now registered: `Pkg.add("Enumlib")`.

The public API is a few composable functions rather than a file-driven program:

```julia
using Enumlib
parent = ParentLattice([0.5 0.5 0.0; 0.5 0.0 0.5; 0.0 0.5 0.5])
sites = Sites([Site([0.0, 0.0, 0.0], [0, 1])])

count_inequivalent(parent, sites; supercells = VolumeRange(1:6)) # how many, without enumerating
e = enumerate_structures(parent, sites; supercells = VolumeRange(1:4))

```

`count_inequivalent` is the part I would point a Julia audience at: it answers “how big is this going to be” by Pólya/Burnside counting, without generating anything. `estimate_cost` turns that into a memory prediction and refuses an enumeration that could never finish—a gotcha the original code had no defence against, and one I have walked into myself.

Algorithms: HNF/SNF enumeration and Pólya counting (Hart & Forcade 2008), multilattices (2009), fixed concentration via multinomial hashing (2012), and the recursive-stabilizer tree (Morgan, Hart & Forcade 2017). Multilattices, site-restricted sublattices and per-sublattice concentrations are all supported.

Two things that did not exist in the Fortran and may be the reason to care: per-site `allowed_labels` with per-sublattice concentrations, so zinc-blende, Heusler and perovskite problems are stated directly rather than encoded around; and a POSCAR round trip—`write_enumeration_archive` out, `read_results` / `attach_results` back—for assembling cluster-expansion training sets without hand-rolling the bookkeeping.

For interoperability there are also standalone `enum.x` / `polya.x` / `makestr.x` executables built with PackageCompiler, so Python workflows (pymatgen’s `EnumlibAdaptor`) can use it without a Julia installation.

Docs: [https://glwhart.github.io/Enumlib.jl](https://glwhart.github.io/Enumlib.jl)  
Source: [GitHub - glwhart/Enumlib.jl: Julia successor to the Fortran enumlib: derivative-structure / superlattice enumeration with colorings and symmetry reduction. · GitHub](https://github.com/glwhart/Enumlib.jl)
