Engines · dft-bands
Band structure of a crystal, from a POSCAR, a CIF or a pw.x input
Give it a crystal in a format you already have. It finds the primitive cell, writes the same kind of input file the DFT program runs from, and computes the self-consistent LDA band structure in your browser. Silicon takes about eight seconds.
What it takes and gives
The engine is engines/dft-bands.viv, 125 lines of Viv that run
dft/pwdft_it. Its header says what it takes and gives:
#! engine dft-bands
#! title Band structure of a crystal, from a POSCAR, a CIF or a pw.x input
#! program dft/pwdft_it
#! input crystal: poscar | cif | qe-pw | xyz+cell
#! input settings: ecut, kmesh, smearing, bands (defaults from dft/ref/materials.py)
#! output bands, total-energy
#! limit tab: fcc lattices, up to 8 atoms, an estimated 90 s of compiled wasm; larger runs natively with dft/run.sh
#! validated si: dft/si_it_check.viv
#! validated gaas: dft/gaas_it_check.viv - input
- crystal: poscar | cif | qe-pw | xyz+cell
- input
- settings: ecut, kmesh, smearing, bands (defaults from dft/ref/materials.py)
- output
- bands, total-energy
- limit
- tab: fcc lattices, up to 8 atoms, an estimated 90 s of compiled wasm; larger runs natively with dft/run.sh
- validated
- si:
dft/si_it_check.viv - validated
- gaas:
dft/gaas_it_check.viv
What happens to your file
- An input reader parses it (
www/src/lib/engines/formats/): a POSCAR’s scale and species line, a CIF’s cell parameters and symmetry operations, a pw.x input’sibrav,celldmand cards, an extended XYZ’sLattice. Each gives the same thing, a cell and atoms in it. - The crystal is reduced to the engine’s cell. Every translation that maps the structure
onto itself is found, which is how an 8-atom cubic cell or a supercell reveals the 2-atom primitive one.
The lattice must be face-centered cubic, because the engine’s k-mesh and band path are. It is rotated
into
dft/’s orientation and the atoms are centered the waydft/ref/materials.pyplaces them. - The input file is written as
dft/ref/make_deck.pywrites one: pseudopotentials from CP2K’s table, picked asdft/pseudo/make_pseudo.pypicks them, and the cutoff, k-mesh, smearing and band countmaterials.pymeasured. Silicon from any of the four formats givesdft/si.vivcharacter for character. - It runs. Compiled, the engine is one WebAssembly module for every input: it was built from
the program with silicon’s input in place, plus a loader that replaces every input variable, by name, with
the one the page hands it on standard input. Interpreted,
viv.wasmreads the program with your input pasted in.
The cost estimate is a model with one constant fitted to the compiled engine on dft/’s five
tab-sized materials: time grows with the bands, the FFT grid and the k-points. It lands within
20% of the time measured on those five, and predicts copper at
172 s where the compiled module took 258 s, so treat it as a rough guide.
A crystal estimated above 90 s is not offered here.
How it is checked
Every example input is compared with dft/’s own, and when it is identical the run is compared with the
numpy reference stored in that material’s check file: the total energy to 10−7 hartree and every band at
every one of the 61 path points to 10−5 eV, the tolerances dft/’s tests use. The engine
computes the difference itself and prints it. These are the last recorded runs:
| input | reference input | energy error, Ha | worst band error, eV | seconds |
|---|---|---|---|---|
| si.poscar, compiled | dft/si.viv | 1.6e-12 | 5.8e-7 | 8.6 |
| si.cif, compiled | dft/si.viv | 1.6e-12 | 5.8e-7 | 8.8 |
| si.pw.in, compiled | dft/si.viv | 1.6e-12 | 5.8e-7 | 8.6 |
| si.xyz, compiled | dft/si.viv | 1.6e-12 | 5.8e-7 | 8.3 |
| gaas.poscar, compiled | dft/gaas.viv | 9.3e-13 | 2.9e-6 | 12.1 |
| gaas.cif, compiled | dft/gaas.viv | 9.3e-13 | 2.9e-6 | 11.7 |
| gaas.pw.in, compiled | dft/gaas.viv | 9.3e-13 | 2.9e-6 | 11.9 |
| si.poscar, interpreted | dft/si.viv | 1.6e-12 | 5.8e-7 | 21.5 |
| gaas.cif, interpreted | dft/gaas.viv | 9.3e-13 | 2.9e-6 | 36.1 |
Seconds are timings under Node.js on the machine that ran the tests; a browser tab is usually a little slower. The input readers have their own tests: every example, all six materials of materials.py written as shifted POSCARs, silicon written four other ways, and inputs that must be refused, each with its reason.
The GTH pseudopotential parameters are CP2K's GTH_POTENTIALS table as PySCF ships it (Goedecker, Teter and Hutter 1996; Hartwigsen, Goedecker and Hutter 1998); only the numbers are used, no CP2K or PySCF code.
What it does not do
- Lattices other than fcc. Diamond, zincblende, rock salt and fcc metals only; anything else is refused with the lattice it found.
- Spin. A magnetic input (a pw.x
nspin = 2, a magnetic CIF, an XYZ with moments) is refused, not run without its spin. - Pseudopotentials you name. The engine uses GTH pseudopotentials from CP2K’s table; a pw.x input’s UPF files are listed as not used.
- Elements without a measured cutoff run only when you give a cutoff, and the result says it is unvalidated.
- Total energies between structures. The ion–ion term is left out, as in
dft/.