Introduction to atomman: spglib load and dump
Lucas M. Hale, lucas.hale@nist.gov, Materials Science and Engineering Division, NIST.
1. Introduction
The spglib Python package provides space group analysis methods for analyzing atomic systems. Atomman provides direct conversions between atomman.System objects and the system representations used by spglib to allow users to easily take advantage of the methods in spglib.
Note: The methods in spglib only care about select properties of the atomic configuration and ignore everything else. For this reason, the spglib conversions are only of use for running spglib analysis on Systems and not for storing the atomic data.
Library Imports
[1]:
# Standard Python libraries
import datetime
# http://www.numpy.org/
import numpy as np
import atomman as am
import atomman.unitconvert as uc
# Show atomman version
print('atomman version =', am.__version__)
# Show date of Notebook execution
print('Notebook executed on', datetime.date.today())
atomman version = 1.4.11
Notebook executed on 2024-04-29
Generate test system information (CsCl)
[2]:
# Generate box
alat = uc.set_in_units(3.2, 'angstrom')
box = am.Box(a=alat, b=alat, c=alat)
# Generate atoms with atype, pos, charge, and stress properties
atype = [1, 2]
pos = [[0,0,0], [0.5, 0.5, 0.5]]
charge = uc.set_in_units([1, -1], 'e')
stress = uc.set_in_units(np.zeros((2, 3, 3)), 'MPa')
atoms = am.Atoms(pos=pos, atype=atype, charge=charge, stress=stress)
# Build system from box and atoms, and scale atoms
system = am.System(atoms=atoms, box=box, scale=True, symbols=['Cs', 'Cl'])
# Print system information
print(system)
system.atoms_df()
avect = [ 3.200, 0.000, 0.000]
bvect = [ 0.000, 3.200, 0.000]
cvect = [ 0.000, 0.000, 3.200]
origin = [ 0.000, 0.000, 0.000]
natoms = 2
natypes = 2
symbols = ('Cs', 'Cl')
pbc = [ True True True]
per-atom properties = ['atype', 'pos', 'charge', 'stress']
id atype pos[0] pos[1] pos[2]
0 1 0.000 0.000 0.000
1 2 1.600 1.600 1.600
[2]:
atype | pos[0] | pos[1] | pos[2] | charge | stress[0][0] | stress[0][1] | stress[0][2] | stress[1][0] | stress[1][1] | stress[1][2] | stress[2][0] | stress[2][1] | stress[2][2] | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
1 | 2 | 1.6 | 1.6 | 1.6 | -1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2. System.dump(‘spglib_cell’)
spglib reads in only the basic atomic structure information needed to perform its analysis. This “cell” information is a tuple consisting of
“lattice” : 3x3 array of cell box vectors
“positions” : Nx3 array of scaled atomic positions
“numbers” : N list of unique atom types
The System.dump(‘spglib_cell’) style returns the cell data associated with the System and nothing more.
[3]:
cell = system.dump('spglib_cell')
print('lattice:')
print(cell[0])
print('scaled_positions:')
print(cell[1])
print('numbers:')
print(cell[2])
lattice:
[[3.2 0. 0. ]
[0. 3.2 0. ]
[0. 0. 3.2]]
scaled_positions:
[[0. 0. 0. ]
[0.5 0.5 0.5]]
numbers:
[1 2]
3. atomman.load(‘spglib_cell’)
Once an spglib analysis is complete, any generated “cell” information can then be converted into an atomman.System simply by loading it.
Parameters
cell (tuple) A tuple containing 3x3 lattice vectors, 3XN box relative positions, and N numeric atomic types.
symbols (list) The elemental symbols to pair with the unique atom types/numbers.
Returns
system (atomman.System) A atomman representation of a system.
[4]:
system = am.load('spglib_cell', cell, symbols=system.symbols)
print(system)
system.atoms_df()
avect = [ 3.200, 0.000, 0.000]
bvect = [ 0.000, 3.200, 0.000]
cvect = [ 0.000, 0.000, 3.200]
origin = [ 0.000, 0.000, 0.000]
natoms = 2
natypes = 2
symbols = ('Cs', 'Cl')
pbc = [ True True True]
per-atom properties = ['atype', 'pos']
id atype pos[0] pos[1] pos[2]
0 1 0.000 0.000 0.000
1 2 1.600 1.600 1.600
[4]:
atype | pos[0] | pos[1] | pos[2] | |
---|---|---|---|---|
0 | 1 | 0.0 | 0.0 | 0.0 |
1 | 2 | 1.6 | 1.6 | 1.6 |