Electrum.jl provides data types and methods that can be used to build tools for solid-state chemistry, aiming to assist those new to both solid-state chemistry and programming.
Background
I started graduate school in a solid state chemistry research group, and one thing is clear: only a small number of us enter the field with experience in software development. A significant portion of commonly used code is writting in C or FORTRAN, but these languages are difficult to approach for those who have minimal experience with code. On top of this, the maintenance of academic code (especially with low level languages!) can be very difficult, especially when nobody has experience with version control and environment management. I’ve seen my share of code whose purpose has been lost to time due to a lack of documentation, comments, descriptive variable names, or organization.
I started learning Julia to solve the two-language problem in my field, and built Electrum initially to perform simple tasks like constructing supercells or reading data from the file formats we commonly use. However, I came to realize that what I was doing could be used to accomplish far more, and could be used as a framework for learning solid-state chemistry and building new theoretical tools that are more accessible to those just entering the field.
Features
Electrum provides data types to handle commonly encountered objects in solid state chemistry: for instance, lattice basis vectors are described by the RealBasis
and ReciprocalBasis
types, lists of atomic positions in a crystal by PeriodicAtomList
, data grids with DataGrid
(and its subtype aliases RealDataGrid
and ReciprocalDataGrid
), wavefunctions in a planewave basis with PlanewaveWavefunction
, just to name a few.
Geometry
The RealBasis
and ReciprocalBasis
types describe the basis vectors of a crystal lattice, and are subtypes of StaticMatrix
, so most common mathematical operations are supported out of the box.
Atomic positions can be described using NamedAtom
, which allows for instances of the same atom in a structure to be tagged with different names, FractionalAtomPosition
and CartesianAtomPosition
(which add either fractional or Cartesian coordinates to the atom), and PeriodicAtomList
(which adds a set of basis vectors to a Vector{FractionalAtomPosition}
).
The Crystal
data type is essentially a lazy reference to a transformed cell, and can be collected to a PeriodicAtomList
.
Of particular interest, Electrum provides the supercell()
function to construct supercells using arbitrary transformation matrices (as well as scalars and vectors corresponding to diagonal matrices) - of particular use to those who need to build orthogonal cells from non-orthogonal primitive or conventional cells.
Data grids
Broadcasting is supported for DataGrid
, so it’s easy to apply functions elementwise to one or more DataGrid
instances, provided the basis vectors and associated shifts are equal. Scalar multiplication and division are supported, as well as addition, subtraction, and a few other common numerical operations that do not require broadcast syntax. Fourier transforms are provided with FFTW.jl: both fft(::DataGrid)
and ifft(::DataGrid)
are provided, and respect the grid axes and basis vectors.
The PlanewaveWavefunction
type stores the coefficients associated with wavefunctions, as well as energy and occupancy data, and supports multiple spins and k-points.
File format support
Electrum.jl can read many different file formats, including abinit binary outputs for electron densities, potentials, and wavefunctions, VASP POSCAR, WAVECAR, DOSCAR, etc., and XCrysDen XSF files.
Roadmap
I’ll be focusing on integrating Electrum with bindings to plotting packages like Makie.jl so that new users can not only see pretty-printed text representations of Electrum data structures in the REPL, but interactive plots for visualizing data as well. I’ve managed to get a few bindings working for atomic positions, and there’s plenty more in the pipeline.
I also seek to integrate Electrum with the AtomsBase ecosystem, especially since Electrum has tools for reading and writing some file formats not currently availabe in other packages.
And there will be some new theory tools built on Electrum in the future! Stay tuned.
Contributing
If you’d like to contribute and don’t know where to start - I would love to add integrations for file formats used by a broader variety of computational chemistry software, in particular anything supporting a planewave basis. At this point, even support for ABINIT and VASP files is not complete, so if you use these packages, feel free to add functionality to process more of their output data.
I would also like to see more interactive tools built on top of Electrum, especially simple pedagogical examples that could live in a Pluto or Jupyter notebook. Some of the contributors have leveraged Pluto for for this purpose, and we’d like to start collecting examples if you want to share them.