[ANN] Brillouin.jl: k-space utilities for crystalline eigenproblems

I wrote a small’ish package Brillouin.jl that is aimed at making the frequent task of determining and understanding paths and domains in k-space simpler and more streamlined.

Specifically, it provides tools to easily:

  • Construct Wigner-Seitz cells (i.e. Brillouin zones if in k-space) from a lattice basis [wignerseitz].
  • Obtain “minimal” paths in k-space, consistent with symmetry constraints (as defined by a space group number and lattice basis) [irrfbz_path]. Specifically, it returns the same paths as those in the popular Python SeeK-path package, but implemented in Julia (and works in both 2D and 3D).
  • Interpolate generated k-space paths, either by approximately equidistant distribution of points [interpolate] or by splicing [splice].
  • Visualize generated Wigner-Seitz cells and k-space paths via PlotlyJS (and, to a lesser, more incomplete degree, Makie). Examples included in the documentation.
  • Plot well-labelled dispersion diagrams through interpolated k-paths.

The hope is that this might be useful for those who frequently need to generate dispersion diagrams (e.g., in solid state physics or photonic crystal research) and have tired of manually determining a “good” path in k-space.

If there’s interest, future developments might include interfacing with spglib to automatically determine the space group and (conventional) lattice bases.

12 Likes

Very cool! In DFTK we currently use pymatgen via PyCall to get BZ paths. It would be nice to replace with a pure-julia solution! @mfh opened an issue for this at https://github.com/JuliaMolSim/DFTK.jl/issues/483

1 Like

@mfh opened an issue for this

Yes, I would have tried that straight away, but unfortunately I do lack the time at the moment. I’ll get back to you @tchr in case of issues.

Also related to the announcement of SymmetryReduceBZ by @jerjorg I wonder if integrating symmetry reduction was on your roadmap? In DFTK we would love to see a pure-Julian way of handling BZ meshes available …

1 Like

Ah, that’s exciting - if this could find application in DFTK.jl, that’d be very cool indeed!

Right now, I’m not planning on adding BZ integration/mesh features, mostly because I’m somewhat ignorant of the techniques (the need to integrate over BZs efficiently isn’t as pronounced in my field, photonics, as it is in electronics) - but it’s very cool that SymmetryReduceBZ.jl does this…!
If I find time, I might add tools to get the irreducible BZ shape - just because it’s a fun geometric task - but I imagine that would mainly be useful for visualizations (at least so long that it isn’t accompanied by meshes).

If you’re interested in Julia-implementations of space group theoretic tools (operations, notation, lattices/bases, irreps, Wyckoff positions, band representations, etc.) then I also have a significantly larger project, Crystalline.jl, which provides access to such tools. I’ll probably announce that at some point as well when I’ve filled in some of the gaps in the documentation. Unfortunately, for DFTK.jl at least, it doesn’t give spinful irreps as of yet.

1 Like

Hi, thanks for this a nice package! I have two questions about the Wigner-Seitz utility.

  1. Is there a function to find a periodic image of some point r inside thr WS cell (without brute force search)? (I mean for given r, finding r+R inside the WS cell.)

  2. Would it be possible/easy to the transform the Cell object to a different coordinate system? I see the latticize and cartesianize functions, but I need a general transformation to arbitrary coordinates. Can this be done by just transforming all the vertices?

Ah, not yet, no. We could probably add one in time; feel free to create an issue for it so I don’t forget.

Yep, definitely, you could operate directly on the vertices. Suppose your new coordinate system has a basis specified in Cartesian coordinates in the variable basis_new (a vector of vectors) and your Cell is called cell, then you could do:

# `cell` is initially in the original lattice basis (`basis(cell)`); convert to cartesian before we convert to `basis_new`
verts_cart = cartesianize(cell.verts, cell.basis)
# transform vertices to new basis
verts_new = latticize(verts_cart, basis_new)
# construct new `Cell` with updated vertices and basis
cell_new = Cell(verts_new , cell.faces, basis_new, cell.setting)

Thanks! I opened an issue. https://github.com/thchr/Brillouin.jl/issues/9

1 Like