Introduction to atomman: Load and dump

Lucas M. Hale, lucas.hale@nist.gov, Materials Science and Engineering Division, NIST.

Disclaimers

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.10
Notebook executed on 2023-07-28

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