Introduction to atomman: System class

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

Disclaimers

1. Introduction

The System class represents an atomic system configuration by combining an Atoms object with a Box object. Additional System methods and attributes deal with boundary conditions and the interaction between the underlying Atoms and Box objects.

NOTE: The underlying structure of Atoms changed with version 1.2 to be more efficient and easier to work with. Changes have been made to the System class to reflect this.

Library Imports

[1]:
# Standard Python libraries
import sys
from copy import deepcopy
import datetime

# http://www.numpy.org/
import numpy as np

# https://github.com/usnistgov/atomman
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

2. Basics

2.1. Initialization Options

Parameters

  • atoms (atomman.Atoms, optional) The underlying Atoms object to build system around.

  • box (atomman.Box, optional) The underlying box object to build system around.

  • pbc (tuple or list of bool, optional) Indicates which of the dimensions related to the three box vectors are periodic. Default value is (True, True, True).

  • scale (bool, optional) If True, atoms.pos will be scaled relative to the box. Default value is False.

  • symbols (tuple, optional) A list of the element symbols for each atom atype. If len(symbols) is less than natypes, then missing values will be set to None. Default sets list with all None values.

  • masses (tuple, optional) A list of the masses for each atom atype. If len(symbols) is less than natypes, then missing values will be set to None. Default sets list with all None values.

  • model (str or DataModelDict, optional) File path or content of a JSON/XML data model containing all system information. Cannot be given with atoms, box or scale.

  • safecopy (bool, optional) Flag indicating if values are to be copied before setting. For values given as objects, direct setting (False, default) may result in the System pointing to the original object. Using safecopy=True deep copies the objects before setting to avoid this. Note that safecopy=True may be considerably slower for large numbers of atoms and/or properties.

Note: Since the number of atoms associated with an Atoms object is constant and a System’s Atoms cannot be reassigned, the number of atoms in a System cannot be changed after initialization.

Initialization without parameters uses the default Atoms() and Box() initializers.

[2]:
system = am.System()

print(system)
avect =  [ 1.000,  0.000,  0.000]
bvect =  [ 0.000,  1.000,  0.000]
cvect =  [ 0.000,  0.000,  1.000]
origin = [ 0.000,  0.000,  0.000]
natoms = 1
natypes = 1
symbols = (None,)
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

This combination of atoms and box lets you define systems for any unit cell.

[3]:
# Define a system for dc Si unit cell
pos = np.array([[0.00, 0.00, 0.00],
                [0.50, 0.50, 0.00],
                [0.50, 0.00, 0.50],
                [0.00, 0.50, 0.50],
                [0.25, 0.25, 0.25],
                [0.25, 0.75, 0.75],
                [0.75, 0.25, 0.75],
                [0.75, 0.75, 0.25]])
atoms = am.Atoms(pos=pos)

a = uc.set_in_units(5.431, 'Å')
box = am.Box(a=a, b=a, c=a)

# Scale = True will unscale atoms.pos to absolute Cartesian coordinates
system = am.System(atoms=atoms, box=box, scale=True, symbols='Si')
print(system)
avect =  [ 5.431,  0.000,  0.000]
bvect =  [ 0.000,  5.431,  0.000]
cvect =  [ 0.000,  0.000,  5.431]
origin = [ 0.000,  0.000,  0.000]
natoms = 8
natypes = 1
symbols = ('Si',)
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       1   2.716   2.716   0.000
      2       1   2.716   0.000   2.716
      3       1   0.000   2.716   2.716
      4       1   1.358   1.358   1.358
      5       1   1.358   4.073   4.073
      6       1   4.073   1.358   4.073
      7       1   4.073   4.073   1.358

3. Built-in Attributes

Each System instance has these built-in attributes:

  • atoms (atomman.Atoms) the underlying Atoms object.

  • natoms (int) is the number of atoms (same as system.atoms.natoms).

  • atypes (numpy.ndarray of int) lists all unique atype values (same as system.atoms.atypes).

  • natypes (int) is the number of unique atype values (same as system.atoms.natypes).

  • box (atomman.Box) the underlying Box object.

  • pbc (numpy.ndarray of bool) three Boolean values indicating which box directions are periodic.

  • symbols (tuple) the element symbols associated with each atype.

  • masses (tuple) the masses set for each atype, if needed. Added version 1.3.0

  • composition (str) composition description of elements and numbers. Added version 1.2.7

[4]:
print('system.natoms ->', system.natoms)
print('system.atypes ->', system.atypes)
print('system.natypes ->', system.natypes)
print('system.symbols ->', system.symbols)
print('system.masses ->', system.masses)
print('system.composition ->', system.composition)
print('system.pbc ->', system.pbc)
system.natoms -> 8
system.atypes -> (1,)
system.natypes -> 1
system.symbols -> ('Si',)
system.masses -> (None,)
system.composition -> Si
system.pbc -> [ True  True  True]

The pbc values can be set during initialization and changed at any time afterwards.

[5]:
print('setting: system.pbc = [False, True, True]')
system.pbc = [False, True, True]
print('system.pbc ->', system.pbc)
print()

print('setting: system.pbc[0] = True')
system.pbc[0] = True
print('system.pbc ->', system.pbc)
setting: system.pbc = [False, True, True]
system.pbc -> [False  True  True]

setting: system.pbc[0] = True
system.pbc -> [ True  True  True]

The underlying Atoms and Box objects can be directly retrieved. Note that

[6]:
print("system.atoms ->")
print(system.atoms)
print()

print("system.box ->")
print(system.box)
system.atoms ->
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   0.000   0.000   0.000
      1       1   2.716   2.716   0.000
      2       1   2.716   0.000   2.716
      3       1   0.000   2.716   2.716
      4       1   1.358   1.358   1.358
      5       1   1.358   4.073   4.073
      6       1   4.073   1.358   4.073
      7       1   4.073   4.073   1.358

system.box ->
avect =  [ 5.431,  0.000,  0.000]
bvect =  [ 0.000,  5.431,  0.000]
cvect =  [ 0.000,  0.000,  5.431]
origin = [ 0.000,  0.000,  0.000]

Symbols can be updated at any time by supplying a list/tuple. For atype values not associated with a symbol, use None for the symbol. Note that symbols is stored as a tuple and therefore must all be set at once.

Update 1.3.0 How atypes, natypes, composition and symbols are handled has been changed to allow for mismatches between assigned atype values and symbols lists. Backwards compatibility will be affected if previous System.atoms had atype values of 0 or non-sequential atype values.

  • Values for System.atoms.atype are limited to being ≥ 1.

  • System.atoms.natypes is max(System.atoms.atype)

  • System.natypes is the greater of System.atoms.natypes or len(System.symbols).

  • If System.symbols or System.atoms.atype values are changed such that System.atoms.natypes > len(System.symbols), then System.symbols is expanded with None values.

  • The composition string will be generated if all used atype values are assigned symbols. Otherwise, System.composition will return None.

[7]:
# More symbols can be assigned to the system than there are atype values
print("setting: system.symbols = ['Si', 'Ge']")
system.symbols = ['Ge', 'Si']
print('system.symbols ->', system.symbols)

# This change is reflected by system.atypes and system.natypes
print('system.natypes ->', system.natypes)
print('system.atypes ->', system.atypes)

# BUT, not by System.atoms.atypes and natypes! They are still based on atype values alone!
print('\nCAUTION!')
print('system.atoms.natypes ->', system.atoms.natypes)
print('system.atoms.atypes ->', system.atoms.atypes)
setting: system.symbols = ['Si', 'Ge']
system.symbols -> ('Ge', 'Si')
system.natypes -> 2
system.atypes -> (1, 2)

CAUTION!
system.atoms.natypes -> 1
system.atoms.atypes -> (1,)
[8]:
# Symbols can be reset to remove the extra
print("setting: system.symbols = 'Ge'")
system.symbols = 'Ge'
print('system.symbols ->', system.symbols)
print('system.natypes ->', system.natypes)
setting: system.symbols = 'Ge'
system.symbols -> ('Ge',)
system.natypes -> 1

4. Scaling Additions

Since atomic positions are stored in absolute Cartesian coordinates, the system has methods for scaling/unscaling vectors relative to the box and which modify methods and attributes of the underlying Atoms and Box classes.

4.1. scale() and unscale()

Updated version 1.4.4: These methods are now aliases of Box.position_relative_to_cartesian() and Box.position_cartesian_to_relative(). System.scale() and System.unscale() are marked for depreciation in the next major atomman version in favor of the more informatively named Box methods.

  • scale() is for absolute Cartesian -> relative box coordinates.

  • unscale() is for relative box -> absolute Cartesian coordinates.

[9]:
# Scale the position vectors
print("setting: spos = system.scale(system.atoms.pos)")
spos = system.scale(system.atoms.pos)
print("spos ->")
print(spos)
print()

# Unscale the scaled position vectors
print("setting: pos = system.unscale(spos)")
pos = system.unscale(spos)
print("pos ->")
print(pos)
setting: spos = system.scale(system.atoms.pos)
spos ->
[[0.   0.   0.  ]
 [0.5  0.5  0.  ]
 [0.5  0.   0.5 ]
 [0.   0.5  0.5 ]
 [0.25 0.25 0.25]
 [0.25 0.75 0.75]
 [0.75 0.25 0.75]
 [0.75 0.75 0.25]]

setting: pos = system.unscale(spos)
pos ->
[[0.      0.      0.     ]
 [2.7155  2.7155  0.     ]
 [2.7155  0.      2.7155 ]
 [0.      2.7155  2.7155 ]
 [1.35775 1.35775 1.35775]
 [1.35775 4.07325 4.07325]
 [4.07325 1.35775 4.07325]
 [4.07325 4.07325 1.35775]]

4.2. atoms_prop()

The atoms_prop() method extends the atoms.prop() method by adding a scale parameter option.

  • scale=False (default): the property values are returned exactly as they are stored, i.e. this is the same as calling system.atoms.prop().

  • scale=True: the property values are automatically scaled/unscaled to/from box relative coordinates. This is convenient as you don’t have to remember which scale()/unscale() to use.

[10]:
# Using atoms_prop() with scale=False is the same as accessing atoms.prop
print("Setting: system.atoms_prop(key='pos', index=2, value=[3,3,3])")
system.atoms_prop(key='pos', index=2, value=[3,3,3])
print("system.atoms.pos[2] ->                    ", system.atoms.pos[2])
print("system.atoms_prop('pos', 2) ->            ", system.atoms_prop('pos', 2))
print("system.atoms_prop('pos', 2, scale=True) ->", system.atoms_prop('pos', 2, scale=True))
print()

# Using atoms_prop(scale=True) properly handles scaling/unscaling
print("Setting: system.atoms_prop(key='pos', index=2, value=[0.5,0.0,0.5], scale=True)")
system.atoms_prop(key='pos', index=2, value=[0.5,0.0,0.5], scale=True)
print("system.atoms.pos[2] ->                    ", system.atoms.pos[2])
print("system.atoms_prop('pos', 2) ->            ", system.atoms_prop('pos', 2))
print("system.atoms_prop('pos', 2, scale=True) ->", system.atoms_prop('pos', 2, scale=True))
print()
Setting: system.atoms_prop(key='pos', index=2, value=[3,3,3])
system.atoms.pos[2] ->                     [3. 3. 3.]
system.atoms_prop('pos', 2) ->             [3. 3. 3.]
system.atoms_prop('pos', 2, scale=True) -> [0.55238446 0.55238446 0.55238446]

Setting: system.atoms_prop(key='pos', index=2, value=[0.5,0.0,0.5], scale=True)
system.atoms.pos[2] ->                     [2.7155 0.     2.7155]
system.atoms_prop('pos', 2) ->             [2.7155 0.     2.7155]
system.atoms_prop('pos', 2, scale=True) -> [0.5 0.  0.5]

4.3. atoms_df()

The atoms_df() method extends the atoms.df() method with an optional scale parameter.

  • scale=False (defaut): the property values are returned exactly as they are stored, i.e. this is the same as calling system.atoms.df()

  • scale=True: the pos values will be scaled to box relative coordinates and all other parameters returned exactly as they are stored.

  • scale=list of property names: all listed property values will be scaled to box relative coordinates.

[11]:
# With scale=False
system.atoms_df()
[11]:
atype pos[0] pos[1] pos[2]
0 1 0.00000 0.00000 0.00000
1 1 2.71550 2.71550 0.00000
2 1 2.71550 0.00000 2.71550
3 1 0.00000 2.71550 2.71550
4 1 1.35775 1.35775 1.35775
5 1 1.35775 4.07325 4.07325
6 1 4.07325 1.35775 4.07325
7 1 4.07325 4.07325 1.35775
[12]:
# With scale=True
system.atoms_df(scale=True)
[12]:
atype pos[0] pos[1] pos[2]
0 1 0.00 0.00 0.00
1 1 0.50 0.50 0.00
2 1 0.50 0.00 0.50
3 1 0.00 0.50 0.50
4 1 0.25 0.25 0.25
5 1 0.25 0.75 0.75
6 1 0.75 0.25 0.75
7 1 0.75 0.75 0.25
[13]:
# With scale=['pos']
system.atoms_df(scale=['pos'])
[13]:
atype pos[0] pos[1] pos[2]
0 1 0.00 0.00 0.00
1 1 0.50 0.50 0.00
2 1 0.50 0.00 0.50
3 1 0.00 0.50 0.50
4 1 0.25 0.25 0.25
5 1 0.25 0.75 0.75
6 1 0.75 0.25 0.75
7 1 0.75 0.75 0.25

4.4. box_set()

The box_set() method extends the box.set() method to include an optional scale parameter. This is necessary to define how atomic positions are affected by the change in box dimensions.

  • scale=False (defaut): the absolute Cartesian coordinates of the atoms are held fixed as the box is changed. This is equivalent to calling box.set() directly.

  • scale=True: the relative box coordinates of the atoms are held fixed by scaling the Cartesian coordinates as the box is changed.

[14]:
# With scale=False, Cartesian coordinates are unchanged,
newa = uc.set_in_units(5.658, 'Å')
system.box_set(a=newa, b=newa, c=newa)
print(system)
print()

# while box relative coordinates are changed
print("system.atoms_prop('pos', scale=True) =")
print(system.atoms_prop('pos', scale=True))
avect =  [ 5.658,  0.000,  0.000]
bvect =  [ 0.000,  5.658,  0.000]
cvect =  [ 0.000,  0.000,  5.658]
origin = [ 0.000,  0.000,  0.000]
natoms = 8
natypes = 1
symbols = ('Ge',)
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       1   2.716   2.716   0.000
      2       1   2.716   0.000   2.716
      3       1   0.000   2.716   2.716
      4       1   1.358   1.358   1.358
      5       1   1.358   4.073   4.073
      6       1   4.073   1.358   4.073
      7       1   4.073   4.073   1.358

system.atoms_prop('pos', scale=True) =
[[0.         0.         0.        ]
 [0.47993991 0.47993991 0.        ]
 [0.47993991 0.         0.47993991]
 [0.         0.47993991 0.47993991]
 [0.23996995 0.23996995 0.23996995]
 [0.23996995 0.71990986 0.71990986]
 [0.71990986 0.23996995 0.71990986]
 [0.71990986 0.71990986 0.23996995]]
[15]:
# Return to original box
system.box_set(a=a, b=a, c=a)

# With scale=True, Cartesian coordinates change,
system.box_set(a=newa, b=newa, c=newa, scale=True)
print(system)
print()

# while box relative coordinates are unchanged.
print("system.atoms_prop('pos', scale=True) =")
print(system.atoms_prop('pos', scale=True))
avect =  [ 5.658,  0.000,  0.000]
bvect =  [ 0.000,  5.658,  0.000]
cvect =  [ 0.000,  0.000,  5.658]
origin = [ 0.000,  0.000,  0.000]
natoms = 8
natypes = 1
symbols = ('Ge',)
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       1   2.829   2.829   0.000
      2       1   2.829   0.000   2.829
      3       1   0.000   2.829   2.829
      4       1   1.414   1.414   1.414
      5       1   1.414   4.244   4.244
      6       1   4.244   1.414   4.244
      7       1   4.244   4.244   1.414

system.atoms_prop('pos', scale=True) =
[[0.   0.   0.  ]
 [0.5  0.5  0.  ]
 [0.5  0.   0.5 ]
 [0.   0.5  0.5 ]
 [0.25 0.25 0.25]
 [0.25 0.75 0.75]
 [0.75 0.25 0.75]
 [0.75 0.75 0.25]]

5. Built-in manipulations

5.1. wrap()

The wrap method adjusts the atoms and box to ensure that all atomic positions are contained within the box. For atoms with positions beyond the box boundaries:

  • If the boundary condition is periodic (as defined in pbc) then the atom’s position is folded to an equivalent position within the boundaries for that dimension.

  • If the boundary condition is non-periodic, the boundary is adjusted to encompass the atom.

[16]:
# Generate ten atom system with atoms between 0 and 10 and box boundaries 0 and 1
system = am.System(atoms=am.Atoms(pos=10*np.random.rand(10,3)))
print(system)
avect =  [ 1.000,  0.000,  0.000]
bvect =  [ 0.000,  1.000,  0.000]
cvect =  [ 0.000,  0.000,  1.000]
origin = [ 0.000,  0.000,  0.000]
natoms = 10
natypes = 1
symbols = (None,)
pbc = [ True  True  True]
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   3.208   0.963   0.701
      1       1   9.325   9.682   0.688
      2       1   1.161   2.090   8.450
      3       1   6.132   0.828   9.739
      4       1   0.960   0.008   4.948
      5       1   7.726   8.181   7.174
      6       1   1.056   1.688   2.894
      7       1   3.526   9.602   9.333
      8       1   0.307   4.185   3.060
      9       1   3.072   9.627   8.682

Atoms are wrapped around periodic boundaries, and non-periodic boundaries are extended to encompass all atoms.

[17]:
# Simple example with mixed periodic and non-periodic boundaries
system.pbc = (True, False, True)
system.wrap()
print(system)
avect =  [ 1.000,  0.000,  0.000]
bvect =  [ 0.000,  9.683,  0.000]
cvect =  [ 0.000,  0.000,  1.000]
origin = [ 0.000,  0.000,  0.000]
natoms = 10
natypes = 1
symbols = (None,)
pbc = [ True False  True]
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   0.208   0.963   0.701
      1       1   0.325   9.682   0.688
      2       1   0.161   2.090   0.450
      3       1   0.132   0.828   0.739
      4       1   0.960   0.008   0.948
      5       1   0.726   8.181   0.174
      6       1   0.056   1.688   0.894
      7       1   0.526   9.602   0.333
      8       1   0.307   4.185   0.060
      9       1   0.072   9.627   0.682

5.2. normalize()

The box vectors for a system may not be compatible with certain codes, such as LAMMPS. The normalize() method helps with this by converting incompatible systems to a compatible representation.

Parameters

  • style (str, optional) Indicates the normalization style to use. Default (and only current option) is ‘lammps’.

  • return_transform (bool, optional) Indicates if the transformation matrix associated with the normalization is to be returned. Default value is False.

For style=’lammps’, the system is altered so that the returned system has:

  1. Right-handed box vectors.

  2. avect = [lx, 0.0, 0.0]

  3. bvect = [xy, ly, 0.0]

  4. cvect = [xz, yz, lz]

  5. All atoms initially inside the box dimensions.

Note: large box tilt factors are not adjusted with this function. As such, the LAMMPS command ‘box tilt large’ may be needed.

[18]:
# Define a system with random box vectors
box = am.Box(vects=np.random.rand(3,3))
atoms = am.Atoms(pos=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]])
system = am.System(atoms=atoms, box=box, scale=True)
print(system)
print('a =', system.box.a)
print('b =', system.box.b)
print('c =', system.box.c)
print('alpha =', system.box.alpha)
print('beta =', system.box.beta)
print('gamma =', system.box.gamma)
avect =  [ 0.362,  0.117,  0.433]
bvect =  [ 0.285,  0.498,  0.284]
cvect =  [ 0.502,  0.344,  0.460]
origin = [ 0.000,  0.000,  0.000]
natoms = 2
natypes = 1
symbols = (None,)
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       1   0.575   0.480   0.588
a = 0.5764813377650477
b = 0.640181680893545
c = 0.7632007394471146
alpha = 24.32057393003292
beta = 16.700319253896822
gamma = 39.59254765877076
[19]:
# Normalize box and show that lattice parameters and box relative positions are unchanged
system = system.normalize()
print(system)
print('a =', system.box.a)
print('b =', system.box.b)
print('c =', system.box.c)
print('alpha =', system.box.alpha)
print('beta =', system.box.beta)
print('gamma =', system.box.gamma)
print('Box relative positions:')
print(system.atoms_prop(key='pos', scale=True))
avect =  [ 0.576,  0.000,  0.000]
bvect =  [ 0.493,  0.408,  0.000]
cvect =  [-0.731, -0.207,  0.071]
origin = [ 0.000,  0.000,  0.000]
natoms = 2
natypes = 1
symbols = (None,)
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       1   0.169   0.100   0.036
a = 0.5764813377650477
b = 0.640181680893545
c = 0.7632007394471146
alpha = 155.67942606996712
beta = 163.29968074610318
gamma = 39.59254765877076
Box relative positions:
[[0.  0.  0. ]
 [0.5 0.5 0.5]]

5.3. rotate()

The System class also has a built-in rotate() method that can be used to rotate the system to a new orientation. The rotated system will be expanded to retain periodicity across its boundaries.

Parameters

  • uvws (array-like object) 3x3 array of three [uvw] Miller crystal vectors or 3x4 array of three [uvtw] Miller-Bravais hexagonal crystal vectors relative to the original system. These must define full Miller vectors, i.e. all u, v, w values be integers. These crystal vectors will align with the rotated system’s box vectors.

  • tol (float, optional) Tolerance parameter used in rounding atomic positions near the boundaries to the boundary values. In box-relative coordinates, any atomic positions within tol of 0 or 1 will be rounded to 0 or 1, respectively. Default value is 1e-5.

  • return_transform (bool, optional) Indicates if the transformation matrix associated with the normalization is to be returned. Default value is False.

Returns

  • newsystem (atomman.System) a new System based on rotating and expanding the original.

  • transform (numpy.ndarray) the transformation matrix associated with the rotation. Returned if return_transform is True.

[20]:
# Define a bcc unit cell for vanadium
alat = uc.set_in_units(3.03, 'Å')
box = am.Box(a=alat, b=alat, c=alat)
atoms = am.Atoms(pos=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]])
system = am.System(atoms=atoms, box=box, scale=True, symbols='V')

print(system)
avect =  [ 3.030,  0.000,  0.000]
bvect =  [ 0.000,  3.030,  0.000]
cvect =  [ 0.000,  0.000,  3.030]
origin = [ 0.000,  0.000,  0.000]
natoms = 2
natypes = 1
symbols = ('V',)
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       1   1.515   1.515   1.515
[21]:
# Rotate the system to coincide with the following crystal vectors
a_uvw = [ 1, 1,-2]
b_uvw = [ 1, 1, 1]
c_uvw = [ 1,-1, 0]

system, transform = system.rotate([a_uvw, b_uvw, c_uvw], return_transform=True)

print('Rotated system:')
print(system)
print()
print('Transformation matrix:')
print(transform)
Rotated system:
avect =  [ 7.422,  0.000,  0.000]
bvect =  [ 0.000,  5.248,  0.000]
cvect =  [ 0.000,  0.000,  4.285]
origin = [ 0.000,  0.000,  0.000]
natoms = 12
natypes = 1
symbols = ('V',)
pbc = [ True  True  True]
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   6.185   0.875   2.143
      1       1   2.474   0.875   4.285
      2       1   3.711   5.248   2.143
      3       1   3.711   2.624   2.143
      4       1   4.948   1.749   4.285
      5       1   4.948   4.373   4.285
      6       1   6.185   3.499   2.143
      7       1   0.000   0.000   0.000
      8       1   7.422   2.624   4.285
      9       1   1.237   1.749   2.143
     10       1   1.237   4.373   2.143
     11       1   2.474   3.499   4.285

Transformation matrix:
[[ 4.08248290e-01  4.08248290e-01 -8.16496581e-01]
 [ 5.77350269e-01  5.77350269e-01  5.77350269e-01]
 [ 7.07106781e-01 -7.07106781e-01 -2.22044605e-16]]

5.4. supersize()

A supercell version of a system can be generated using the supersize() method.

Parameters

  • a_size (int or tuple of int) size multipliers for the system along the a box vector.

  • b_size (int or tuple of int) size multipliers for the system along the b box vector.

  • c_size (int or tuple of int) size multipliers for the system along the c box vector.

Returns

  • (atomman.System) a new System constructed by replicating the original along its box vectors.

All three size terms can be positive or negative integers, or a tuple of (negative, positive) integers. Negative values replicate the system below the origin and positive values replicate the system above the origin.

[22]:
# Create 2x2x2 supercell
# new avect will start at the old origin
a_size = 2

# new bvect will end at the old origin
b_size = -2

# new cvect will be centered around the old origin
c_size =(-1,1)

system = system.supersize(a_size, b_size, c_size)

print(system)
avect =  [14.844,  0.000,  0.000]
bvect =  [ 0.000, 10.496,  0.000]
cvect =  [ 0.000,  0.000,  8.570]
origin = [ 0.000, -10.496, -4.285]
natoms = 96
natypes = 1
symbols = ('V',)
pbc = [ True  True  True]
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   6.185  -9.622  -2.143
      1       1   2.474  -9.622  -0.000
      2       1   3.711  -5.248  -2.143
      3       1   3.711  -7.872  -2.143
      4       1   4.948  -8.747  -0.000
      5       1   4.948  -6.123  -0.000
      6       1   6.185  -6.997  -2.143
      7       1   0.000 -10.496  -4.285
      8       1   7.422  -7.872  -0.000
      9       1   1.237  -8.747  -2.143
     10       1   1.237  -6.123  -2.143
     11       1   2.474  -6.997  -0.000
     12       1  13.607  -9.622  -2.143
     13       1   9.896  -9.622  -0.000
     14       1  11.133  -5.248  -2.143
     15       1  11.133  -7.872  -2.143
     16       1  12.370  -8.747  -0.000
     17       1  12.370  -6.123  -0.000
     18       1  13.607  -6.997  -2.143
     19       1   7.422 -10.496  -4.285
     20       1  14.844  -7.872  -0.000
     21       1   8.659  -8.747  -2.143
     22       1   8.659  -6.123  -2.143
     23       1   9.896  -6.997  -0.000
     24       1   6.185  -4.373  -2.143
     25       1   2.474  -4.373  -0.000
     26       1   3.711   0.000  -2.143
     27       1   3.711  -2.624  -2.143
     28       1   4.948  -3.499  -0.000
     29       1   4.948  -0.875  -0.000
     30       1   6.185  -1.749  -2.143
     31       1   0.000  -5.248  -4.285
     32       1   7.422  -2.624  -0.000
     33       1   1.237  -3.499  -2.143
     34       1   1.237  -0.875  -2.143
     35       1   2.474  -1.749  -0.000
     36       1  13.607  -4.373  -2.143
     37       1   9.896  -4.373  -0.000
     38       1  11.133   0.000  -2.143
     39       1  11.133  -2.624  -2.143
     40       1  12.370  -3.499  -0.000
     41       1  12.370  -0.875  -0.000
     42       1  13.607  -1.749  -2.143
     43       1   7.422  -5.248  -4.285
     44       1  14.844  -2.624  -0.000
     45       1   8.659  -3.499  -2.143
     46       1   8.659  -0.875  -2.143
     47       1   9.896  -1.749  -0.000
     48       1   6.185  -9.622   2.143
     49       1   2.474  -9.622   4.285
     50       1   3.711  -5.248   2.143
     51       1   3.711  -7.872   2.143
     52       1   4.948  -8.747   4.285
     53       1   4.948  -6.123   4.285
     54       1   6.185  -6.997   2.143
     55       1   0.000 -10.496   0.000
     56       1   7.422  -7.872   4.285
     57       1   1.237  -8.747   2.143
     58       1   1.237  -6.123   2.143
     59       1   2.474  -6.997   4.285
     60       1  13.607  -9.622   2.143
     61       1   9.896  -9.622   4.285
     62       1  11.133  -5.248   2.143
     63       1  11.133  -7.872   2.143
     64       1  12.370  -8.747   4.285
     65       1  12.370  -6.123   4.285
     66       1  13.607  -6.997   2.143
     67       1   7.422 -10.496   0.000
     68       1  14.844  -7.872   4.285
     69       1   8.659  -8.747   2.143
     70       1   8.659  -6.123   2.143
     71       1   9.896  -6.997   4.285
     72       1   6.185  -4.373   2.143
     73       1   2.474  -4.373   4.285
     74       1   3.711   0.000   2.143
     75       1   3.711  -2.624   2.143
     76       1   4.948  -3.499   4.285
     77       1   4.948  -0.875   4.285
     78       1   6.185  -1.749   2.143
     79       1   0.000  -5.248   0.000
     80       1   7.422  -2.624   4.285
     81       1   1.237  -3.499   2.143
     82       1   1.237  -0.875   2.143
     83       1   2.474  -1.749   4.285
     84       1  13.607  -4.373   2.143
     85       1   9.896  -4.373   4.285
     86       1  11.133   0.000   2.143
     87       1  11.133  -2.624   2.143
     88       1  12.370  -3.499   4.285
     89       1  12.370  -0.875   4.285
     90       1  13.607  -1.749   2.143
     91       1   7.422  -5.248   0.000
     92       1  14.844  -2.624   4.285
     93       1   8.659  -3.499   2.143
     94       1   8.659  -0.875   2.143
     95       1   9.896  -1.749   4.285

5.5. atoms_ix

Added version 1.2.5

The atoms_ix extends the indexing functionality of the Atoms class to operate at the System level. This allows for systems containing a subset of the atoms to be easily generated.

[23]:
# Indexing directly on the system's atoms returns a new Atoms object
subatoms = system.atoms[[1,2,7,8]]
print(subatoms)
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   2.474  -9.622  -0.000
      1       1   3.711  -5.248  -2.143
      2       1   0.000 -10.496  -4.285
      3       1   7.422  -7.872  -0.000
[24]:
# Using atoms_ix will return a new System containing the specified subset of atoms
subsystem = system.atoms_ix[[1,2,7,8]]
print(subsystem)
avect =  [14.844,  0.000,  0.000]
bvect =  [ 0.000, 10.496,  0.000]
cvect =  [ 0.000,  0.000,  8.570]
origin = [ 0.000, -10.496, -4.285]
natoms = 4
natypes = 1
symbols = ('V',)
pbc = [ True  True  True]
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   2.474  -9.622  -0.000
      1       1   3.711  -5.248  -2.143
      2       1   0.000 -10.496  -4.285
      3       1   7.422  -7.872  -0.000

Also, atoms_ix can be used to set (i.e. copy) a subset of atoms by passing in either a compatible Atoms or System object.

[25]:
# Copy atom 0 to atom 1 by passing a compatible Atoms object
subsystem.atoms_ix[1] = subsystem.atoms[0]

# Copy atom 0 to atom 2 by passing a compatible System object
subsystem.atoms_ix[2] = subsystem.atoms_ix[0]

print(subsystem)
avect =  [14.844,  0.000,  0.000]
bvect =  [ 0.000, 10.496,  0.000]
cvect =  [ 0.000,  0.000,  8.570]
origin = [ 0.000, -10.496, -4.285]
natoms = 4
natypes = 1
symbols = ('V',)
pbc = [ True  True  True]
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   2.474  -9.622  -0.000
      1       1   2.474  -9.622  -0.000
      2       1   2.474  -9.622  -0.000
      3       1   7.422  -7.872  -0.000

5.6. atoms_extend()

Added version 1.2.8

The atoms_extend() method allows the extend() method of the Atoms class to operate at the System level. This allows for new Systems to be generated by copying the current System object with additional atoms.

Parameters - value (atomman.Atoms or int) An int value will result in the atoms object being extended by that number of atoms, with all per-atom properties having default values (atype = 1, everything else = 0). For an Atoms value, the current atoms list will be extended by the correct number of atoms and all per-atom properties in value will be copied over. Any properties defined in one Atoms object and not the other will be set to default values. - scale (bool, optional) Flag indicating if position values in a supplied Atoms value are to be taken as absolute Cartesian (False, default) or in scaled box relative units (True). - symbols (tuple, list or None, optional) Allows for the system’s symbols list to be updated. If not given, will use the current object’s symbols. - safecopy (bool, optional) Flag indicating if values are to be copied before setting. If False (default), underlying objects may be shared between the new system and the current system and input parameters. If True, atoms and box will be deepcopied before setting. Note that safecopy=True may be considerably slower for large numbers of atoms and/or properties.

Returns - (atomman.System) A new System object with Atoms extended to contain all atoms and properties of the current object plus the additional atoms. The cuurent System object’s box and pbc (and symbols if not specified) will be copied over.

[26]:
# Add two empty atoms to subsystem
print(subsystem.atoms_extend(2))
avect =  [14.844,  0.000,  0.000]
bvect =  [ 0.000, 10.496,  0.000]
cvect =  [ 0.000,  0.000,  8.570]
origin = [ 0.000, -10.496, -4.285]
natoms = 6
natypes = 1
symbols = ('V',)
pbc = [ True  True  True]
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   2.474  -9.622  -0.000
      1       1   2.474  -9.622  -0.000
      2       1   2.474  -9.622  -0.000
      3       1   7.422  -7.872  -0.000
      4       1   0.000   0.000   0.000
      5       1   0.000   0.000   0.000
[27]:
# double the atoms in subsystem by copying them
print(subsystem.atoms_extend(subsystem.atoms))
avect =  [14.844,  0.000,  0.000]
bvect =  [ 0.000, 10.496,  0.000]
cvect =  [ 0.000,  0.000,  8.570]
origin = [ 0.000, -10.496, -4.285]
natoms = 8
natypes = 1
symbols = ('V',)
pbc = [ True  True  True]
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   2.474  -9.622  -0.000
      1       1   2.474  -9.622  -0.000
      2       1   2.474  -9.622  -0.000
      3       1   7.422  -7.872  -0.000
      4       1   2.474  -9.622  -0.000
      5       1   2.474  -9.622  -0.000
      6       1   2.474  -9.622  -0.000
      7       1   7.422  -7.872  -0.000

6. Built-in analysis tools

6.1. dvect() and dmag()

The dvect() and dmag() methods calculate the shortest vector difference between two positions, accounting for the system’s periodic boundaries. dvect returns the vector(s), while dmag returns the magnitudes of the vectors.

Parameters

  • pos_0 (numpy.ndarray or index) Absolute Cartesian vector position(s) to use as reference point(s). If the value can be used as an index, then self.atoms.pos[pos_0] is taken.

  • pos_1 (numpy.ndarray or index) Absolute Cartesian vector position(s) to find relative to pos_0. If the value can be used as an index, then self.atoms.pos[pos_1] is taken.

[28]:
# Show simple position difference vector between atoms 7 and 12
print("system.atoms.pos[7] - system.atoms.pos[12] ->")
print(system.atoms.pos[7] - system.atoms.pos[12])

# Show shortest periodic distance vector between atoms 7 and 12
print("system.dvect(12, 7) ->")
print(system.dvect(12, 7))
system.atoms.pos[7] - system.atoms.pos[12] ->
[-13.60691552  -0.87468566  -2.14253355]
system.dvect(12, 7) ->
[ 1.23699232 -0.87468566 -2.14253355]
[29]:
# Compute the shortest periodic distance between atom 34 and all atoms
print("system.dmag(34, system.atoms.pos) ->")
print(system.dmag(34, system.atoms.pos))
system.dmag(34, system.atoms.pos) ->
[ 5.24811395  3.03        5.02468656  4.28506709  5.02468656  6.77528597
  6.6037319   2.62405697  7.42195392  2.62405697  5.24811395  5.02468656
  3.03        6.77528597  6.6037319   6.06        5.02468656  6.77528597
  5.02468656  6.6037319   4.28506709  7.87217092  9.09        7.87217092
  6.06        4.28506709  2.62405697  3.03        5.02468656  4.28506709
  5.02468656  5.02468656  6.77528597  2.62405697  0.          2.62405697
  4.28506709  7.42195392  5.02468656  5.24811395  5.02468656  4.28506709
  2.62405697  7.87217092  3.03        7.87217092  7.42195392  6.6037319
  6.77528597  3.03        6.6037319   6.06        5.02468656  6.77528597
  7.87217092  2.62405697  7.42195392  5.02468656  6.77528597  5.02468656
  5.24811395  6.77528597  7.87217092  7.42195392  5.02468656  6.77528597
  6.6037319   6.6037319   4.28506709  8.96286087 10.04937311  7.87217092
  7.42195392  4.28506709  5.02468656  5.24811395  5.02468656  4.28506709
  6.6037319   5.02468656  6.77528597  5.02468656  4.28506709  2.62405697
  6.06        7.42195392  6.6037319   6.77528597  5.02468656  4.28506709
  5.02468656  7.87217092  3.03        8.96286087  8.57013419  6.6037319 ]

6.2. neighborlist()

The neighborlist() method returns a NeighborList class object for the system.

Parameters

  • cutoff (float, optional) Radial cutoff distance for identifying neighbors. Must be given if model is not given.

  • model (str or file-like object, optional) Gives the file path or content to load. If given, initialsize is the only other allowed parameter.

  • initialsize (int, optional) The number of neighbor positions to initially assign to each atom. Default value is 20.

[30]:
# Compute NeighborList for system
cutoff = 0.90 *alat
print('Computing neighbor list using cutoff of', cutoff, 'angstrom')
neighbors = system.neighborlist(cutoff=cutoff)
Computing neighbor list using cutoff of 2.727 angstrom
[31]:
# Show each atom's coordination
print("neighbors.coord ->")
print(neighbors.coord)
neighbors.coord ->
[8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8]
[32]:
# Show identified neighbors for atom 4
print("neighbors[4] ->")
print(neighbors[4])
neighbors[4] ->
[ 0  1  3  5  8 29 48 51]
[33]:
# Show that all identified neighbors are within the cutoff of atom 4
print("np.linalg.norm(system.dvect(4, neighbors[4]), axis=1) ->")
print(np.linalg.norm(system.dvect(4, neighbors[4]), axis=1))
np.linalg.norm(system.dvect(4, neighbors[4]), axis=1) ->
[2.62405697 2.62405697 2.62405697 2.62405697 2.62405697 2.62405697
 2.62405697 2.62405697]

6.3. r0()

added version 1.3.2

The r0() method identifies the shortest interatomic spacing for the system.

Parameters

  • neighborlist (NeighborList, optional) A pre-computed NeighborList for the system. If not given, a new NeighborList will be used based on a cutoff distance related to the smallest dmag between atom 0 and the rest of the system’s atoms.

[34]:
system.r0()
[34]:
2.624056973466846

7. model() and dump()

model() added version 1.2.7

A JSON/XML equivalent data model representation of the Systems object can be generated using the model() method.

Parameters

  • box_unit (str, optional) Length unit to use for the box. Default value is ‘angstrom’.

  • symbols (list, optional) List of atom-model symbols corresponding to the atom types. If not given, will use system.symbols.

  • prop_name (list, optional) The Atoms properties to include. If neither prop_name nor prop_unit are given, all system properties will be included.

  • unit (list, optional) Lists the units for each prop_name as stored in the table. For a value of None, no conversion will be performed for that property. For a value of ‘scaled’, the corresponding table values will be taken in box-scaled units. If neither unit nor prop_units given, pos will be given in Angstroms and all other values will not be converted.

  • prop_unit (dict, optional) Dictionary where the keys are the property keys to include, and the values are units to use. If neither unit nor prop_units given, pos will be given in Angstroms and all other values will not be converted.

Returns

  • (DataModelDict.DataModelDict) A JSON/XML data model for the current Systems object.

[35]:
model = system.model()
print(model.json())
{"atomic-system": {"box": {"avect": {"value": [14.843907841266057, 0.0, 0.0]}, "bvect": {"value": [0.0, 10.496227893867395, 0.0]}, "cvect": {"value": [0.0, 0.0, 8.570134187980956]}, "origin": {"value": [0.0, -10.496227893867395, -4.285067093990478]}}, "periodic-boundary-condition": [true, true, true], "atom-type-symbol": "V", "atoms": {"natoms": 96, "property": [{"name": "atype", "data": {"value": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}}, {"name": "pos", "data": {"value": [6.184961600527525, -9.621542236045114, -2.1425335469952396, 2.4739846402110097, -9.621542236045114, -8.881784197001252e-16, 3.7109769603165144, -5.248113946933698, -2.1425335469952396, 3.7109769603165144, -7.872170920400547, -2.142533546995239, 4.9479692804220194, -8.746856578222829, -8.881784197001252e-16, 4.9479692804220194, -6.122799604755978, -8.881784197001252e-16, 6.184961600527525, -6.997485262578263, -2.1425335469952396, 0.0, -10.496227893867395, -4.285067093990478, 7.421953920633027, -7.872170920400547, -8.881784197001252e-16, 1.2369923201055044, -8.746856578222829, -2.1425335469952396, 1.2369923201055035, -6.12279960475598, -2.142533546995239, 2.473984640211009, -6.997485262578263, -8.881784197001252e-16, 13.606915521160554, -9.621542236045114, -2.1425335469952396, 9.895938560844039, -9.621542236045114, -8.881784197001252e-16, 11.132930880949543, -5.248113946933698, -2.1425335469952396, 11.132930880949543, -7.872170920400547, -2.142533546995239, 12.369923201055048, -8.746856578222829, -8.881784197001252e-16, 12.369923201055048, -6.122799604755978, -8.881784197001252e-16, 13.606915521160554, -6.997485262578263, -2.1425335469952396, 7.421953920633029, -10.496227893867395, -4.285067093990478, 14.843907841266056, -7.872170920400547, -8.881784197001252e-16, 8.658946240738532, -8.746856578222829, -2.1425335469952396, 8.658946240738532, -6.12279960475598, -2.142533546995239, 9.895938560844037, -6.997485262578263, -8.881784197001252e-16, 6.184961600527525, -4.373428289111415, -2.1425335469952396, 2.4739846402110097, -4.373428289111415, -8.881784197001252e-16, 3.7109769603165144, 0.0, -2.1425335469952396, 3.7109769603165144, -2.624056973466849, -2.142533546995239, 4.9479692804220194, -3.498742631289132, -8.881784197001252e-16, 4.9479692804220194, -0.8746856578222797, -8.881784197001252e-16, 6.184961600527525, -1.7493713156445647, -2.1425335469952396, 0.0, -5.248113946933698, -4.285067093990478, 7.421953920633027, -2.624056973466849, -8.881784197001252e-16, 1.2369923201055044, -3.498742631289131, -2.1425335469952396, 1.2369923201055035, -0.8746856578222815, -2.142533546995239, 2.473984640211009, -1.7493713156445647, -8.881784197001252e-16, 13.606915521160554, -4.373428289111415, -2.1425335469952396, 9.895938560844039, -4.373428289111415, -8.881784197001252e-16, 11.132930880949543, 0.0, -2.1425335469952396, 11.132930880949543, -2.624056973466849, -2.142533546995239, 12.369923201055048, -3.498742631289132, -8.881784197001252e-16, 12.369923201055048, -0.8746856578222797, -8.881784197001252e-16, 13.606915521160554, -1.7493713156445647, -2.1425335469952396, 7.421953920633029, -5.248113946933698, -4.285067093990478, 14.843907841266056, -2.624056973466849, -8.881784197001252e-16, 8.658946240738532, -3.498742631289131, -2.1425335469952396, 8.658946240738532, -0.8746856578222815, -2.142533546995239, 9.895938560844037, -1.7493713156445647, -8.881784197001252e-16, 6.184961600527525, -9.621542236045114, 2.1425335469952396, 2.4739846402110097, -9.621542236045114, 4.2850670939904765, 3.7109769603165144, -5.248113946933698, 2.1425335469952396, 3.7109769603165144, -7.872170920400547, 2.1425335469952396, 4.9479692804220194, -8.746856578222829, 4.2850670939904765, 4.9479692804220194, -6.122799604755978, 4.2850670939904765, 6.184961600527525, -6.997485262578263, 2.1425335469952396, 0.0, -10.496227893867395, 0.0, 7.421953920633027, -7.872170920400547, 4.2850670939904765, 1.2369923201055044, -8.746856578222829, 2.1425335469952396, 1.2369923201055035, -6.12279960475598, 2.1425335469952396, 2.473984640211009, -6.997485262578263, 4.2850670939904765, 13.606915521160554, -9.621542236045114, 2.1425335469952396, 9.895938560844039, -9.621542236045114, 4.2850670939904765, 11.132930880949543, -5.248113946933698, 2.1425335469952396, 11.132930880949543, -7.872170920400547, 2.1425335469952396, 12.369923201055048, -8.746856578222829, 4.2850670939904765, 12.369923201055048, -6.122799604755978, 4.2850670939904765, 13.606915521160554, -6.997485262578263, 2.1425335469952396, 7.421953920633029, -10.496227893867395, 0.0, 14.843907841266056, -7.872170920400547, 4.2850670939904765, 8.658946240738532, -8.746856578222829, 2.1425335469952396, 8.658946240738532, -6.12279960475598, 2.1425335469952396, 9.895938560844037, -6.997485262578263, 4.2850670939904765, 6.184961600527525, -4.373428289111415, 2.1425335469952396, 2.4739846402110097, -4.373428289111415, 4.2850670939904765, 3.7109769603165144, 0.0, 2.1425335469952396, 3.7109769603165144, -2.624056973466849, 2.1425335469952396, 4.9479692804220194, -3.498742631289132, 4.2850670939904765, 4.9479692804220194, -0.8746856578222797, 4.2850670939904765, 6.184961600527525, -1.7493713156445647, 2.1425335469952396, 0.0, -5.248113946933698, 0.0, 7.421953920633027, -2.624056973466849, 4.2850670939904765, 1.2369923201055044, -3.498742631289131, 2.1425335469952396, 1.2369923201055035, -0.8746856578222815, 2.1425335469952396, 2.473984640211009, -1.7493713156445647, 4.2850670939904765, 13.606915521160554, -4.373428289111415, 2.1425335469952396, 9.895938560844039, -4.373428289111415, 4.2850670939904765, 11.132930880949543, 0.0, 2.1425335469952396, 11.132930880949543, -2.624056973466849, 2.1425335469952396, 12.369923201055048, -3.498742631289132, 4.2850670939904765, 12.369923201055048, -0.8746856578222797, 4.2850670939904765, 13.606915521160554, -1.7493713156445647, 2.1425335469952396, 7.421953920633029, -5.248113946933698, 0.0, 14.843907841266056, -2.624056973466849, 4.2850670939904765, 8.658946240738532, -3.498742631289131, 2.1425335469952396, 8.658946240738532, -0.8746856578222815, 2.1425335469952396, 9.895938560844037, -1.7493713156445647, 4.2850670939904765], "shape": [96, 3], "unit": "angstrom"}}]}}}

Any stored model information can then be reloaded in as a new System object by passing the ‘model’ parameter to the class initializer.

[36]:
print(am.System(model=model))
avect =  [14.844,  0.000,  0.000]
bvect =  [ 0.000, 10.496,  0.000]
cvect =  [ 0.000,  0.000,  8.570]
origin = [ 0.000, -10.496, -4.285]
natoms = 96
natypes = 1
symbols = ('V',)
pbc = [ True  True  True]
per-atom properties = ['atype', 'pos']
     id   atype  pos[0]  pos[1]  pos[2]
      0       1   6.185  -9.622  -2.143
      1       1   2.474  -9.622  -0.000
      2       1   3.711  -5.248  -2.143
      3       1   3.711  -7.872  -2.143
      4       1   4.948  -8.747  -0.000
      5       1   4.948  -6.123  -0.000
      6       1   6.185  -6.997  -2.143
      7       1   0.000 -10.496  -4.285
      8       1   7.422  -7.872  -0.000
      9       1   1.237  -8.747  -2.143
     10       1   1.237  -6.123  -2.143
     11       1   2.474  -6.997  -0.000
     12       1  13.607  -9.622  -2.143
     13       1   9.896  -9.622  -0.000
     14       1  11.133  -5.248  -2.143
     15       1  11.133  -7.872  -2.143
     16       1  12.370  -8.747  -0.000
     17       1  12.370  -6.123  -0.000
     18       1  13.607  -6.997  -2.143
     19       1   7.422 -10.496  -4.285
     20       1  14.844  -7.872  -0.000
     21       1   8.659  -8.747  -2.143
     22       1   8.659  -6.123  -2.143
     23       1   9.896  -6.997  -0.000
     24       1   6.185  -4.373  -2.143
     25       1   2.474  -4.373  -0.000
     26       1   3.711   0.000  -2.143
     27       1   3.711  -2.624  -2.143
     28       1   4.948  -3.499  -0.000
     29       1   4.948  -0.875  -0.000
     30       1   6.185  -1.749  -2.143
     31       1   0.000  -5.248  -4.285
     32       1   7.422  -2.624  -0.000
     33       1   1.237  -3.499  -2.143
     34       1   1.237  -0.875  -2.143
     35       1   2.474  -1.749  -0.000
     36       1  13.607  -4.373  -2.143
     37       1   9.896  -4.373  -0.000
     38       1  11.133   0.000  -2.143
     39       1  11.133  -2.624  -2.143
     40       1  12.370  -3.499  -0.000
     41       1  12.370  -0.875  -0.000
     42       1  13.607  -1.749  -2.143
     43       1   7.422  -5.248  -4.285
     44       1  14.844  -2.624  -0.000
     45       1   8.659  -3.499  -2.143
     46       1   8.659  -0.875  -2.143
     47       1   9.896  -1.749  -0.000
     48       1   6.185  -9.622   2.143
     49       1   2.474  -9.622   4.285
     50       1   3.711  -5.248   2.143
     51       1   3.711  -7.872   2.143
     52       1   4.948  -8.747   4.285
     53       1   4.948  -6.123   4.285
     54       1   6.185  -6.997   2.143
     55       1   0.000 -10.496   0.000
     56       1   7.422  -7.872   4.285
     57       1   1.237  -8.747   2.143
     58       1   1.237  -6.123   2.143
     59       1   2.474  -6.997   4.285
     60       1  13.607  -9.622   2.143
     61       1   9.896  -9.622   4.285
     62       1  11.133  -5.248   2.143
     63       1  11.133  -7.872   2.143
     64       1  12.370  -8.747   4.285
     65       1  12.370  -6.123   4.285
     66       1  13.607  -6.997   2.143
     67       1   7.422 -10.496   0.000
     68       1  14.844  -7.872   4.285
     69       1   8.659  -8.747   2.143
     70       1   8.659  -6.123   2.143
     71       1   9.896  -6.997   4.285
     72       1   6.185  -4.373   2.143
     73       1   2.474  -4.373   4.285
     74       1   3.711   0.000   2.143
     75       1   3.711  -2.624   2.143
     76       1   4.948  -3.499   4.285
     77       1   4.948  -0.875   4.285
     78       1   6.185  -1.749   2.143
     79       1   0.000  -5.248   0.000
     80       1   7.422  -2.624   4.285
     81       1   1.237  -3.499   2.143
     82       1   1.237  -0.875   2.143
     83       1   2.474  -1.749   4.285
     84       1  13.607  -4.373   2.143
     85       1   9.896  -4.373   4.285
     86       1  11.133   0.000   2.143
     87       1  11.133  -2.624   2.143
     88       1  12.370  -3.499   4.285
     89       1  12.370  -0.875   4.285
     90       1  13.607  -1.749   2.143
     91       1   7.422  -5.248   0.000
     92       1  14.844  -2.624   4.285
     93       1   8.659  -3.499   2.143
     94       1   8.659  -0.875   2.143
     95       1   9.896  -1.749   4.285

The system can also be exported to a number of other formats using the dump() method.

See the 1.4. Load and dump conversions Jupyter Notebook for more detailed information on the different styles and options.

[37]:
poscar = system.dump('poscar')
print(poscar)

1.0000000000000e+00
1.4843907841266e+01 0.0000000000000e+00 0.0000000000000e+00
0.0000000000000e+00 1.0496227893867e+01 0.0000000000000e+00
0.0000000000000e+00 0.0000000000000e+00 8.5701341879810e+00
V
96
direct
4.1666666666667e-01 8.3333333333333e-02 2.5000000000000e-01
1.6666666666667e-01 8.3333333333333e-02 5.0000000000000e-01
2.5000000000000e-01 5.0000000000000e-01 2.5000000000000e-01
2.5000000000000e-01 2.5000000000000e-01 2.5000000000000e-01
3.3333333333333e-01 1.6666666666667e-01 5.0000000000000e-01
3.3333333333333e-01 4.1666666666667e-01 5.0000000000000e-01
4.1666666666667e-01 3.3333333333333e-01 2.5000000000000e-01
0.0000000000000e+00 0.0000000000000e+00 0.0000000000000e+00
5.0000000000000e-01 2.5000000000000e-01 5.0000000000000e-01
8.3333333333333e-02 1.6666666666667e-01 2.5000000000000e-01
8.3333333333333e-02 4.1666666666667e-01 2.5000000000000e-01
1.6666666666667e-01 3.3333333333333e-01 5.0000000000000e-01
9.1666666666667e-01 8.3333333333333e-02 2.5000000000000e-01
6.6666666666667e-01 8.3333333333333e-02 5.0000000000000e-01
7.5000000000000e-01 5.0000000000000e-01 2.5000000000000e-01
7.5000000000000e-01 2.5000000000000e-01 2.5000000000000e-01
8.3333333333333e-01 1.6666666666667e-01 5.0000000000000e-01
8.3333333333333e-01 4.1666666666667e-01 5.0000000000000e-01
9.1666666666667e-01 3.3333333333333e-01 2.5000000000000e-01
5.0000000000000e-01 0.0000000000000e+00 0.0000000000000e+00
1.0000000000000e+00 2.5000000000000e-01 5.0000000000000e-01
5.8333333333333e-01 1.6666666666667e-01 2.5000000000000e-01
5.8333333333333e-01 4.1666666666667e-01 2.5000000000000e-01
6.6666666666667e-01 3.3333333333333e-01 5.0000000000000e-01
4.1666666666667e-01 5.8333333333333e-01 2.5000000000000e-01
1.6666666666667e-01 5.8333333333333e-01 5.0000000000000e-01
2.5000000000000e-01 1.0000000000000e+00 2.5000000000000e-01
2.5000000000000e-01 7.5000000000000e-01 2.5000000000000e-01
3.3333333333333e-01 6.6666666666667e-01 5.0000000000000e-01
3.3333333333333e-01 9.1666666666667e-01 5.0000000000000e-01
4.1666666666667e-01 8.3333333333333e-01 2.5000000000000e-01
0.0000000000000e+00 5.0000000000000e-01 0.0000000000000e+00
5.0000000000000e-01 7.5000000000000e-01 5.0000000000000e-01
8.3333333333333e-02 6.6666666666667e-01 2.5000000000000e-01
8.3333333333333e-02 9.1666666666667e-01 2.5000000000000e-01
1.6666666666667e-01 8.3333333333333e-01 5.0000000000000e-01
9.1666666666667e-01 5.8333333333333e-01 2.5000000000000e-01
6.6666666666667e-01 5.8333333333333e-01 5.0000000000000e-01
7.5000000000000e-01 1.0000000000000e+00 2.5000000000000e-01
7.5000000000000e-01 7.5000000000000e-01 2.5000000000000e-01
8.3333333333333e-01 6.6666666666667e-01 5.0000000000000e-01
8.3333333333333e-01 9.1666666666667e-01 5.0000000000000e-01
9.1666666666667e-01 8.3333333333333e-01 2.5000000000000e-01
5.0000000000000e-01 5.0000000000000e-01 0.0000000000000e+00
1.0000000000000e+00 7.5000000000000e-01 5.0000000000000e-01
5.8333333333333e-01 6.6666666666667e-01 2.5000000000000e-01
5.8333333333333e-01 9.1666666666667e-01 2.5000000000000e-01
6.6666666666667e-01 8.3333333333333e-01 5.0000000000000e-01
4.1666666666667e-01 8.3333333333333e-02 7.5000000000000e-01
1.6666666666667e-01 8.3333333333333e-02 1.0000000000000e+00
2.5000000000000e-01 5.0000000000000e-01 7.5000000000000e-01
2.5000000000000e-01 2.5000000000000e-01 7.5000000000000e-01
3.3333333333333e-01 1.6666666666667e-01 1.0000000000000e+00
3.3333333333333e-01 4.1666666666667e-01 1.0000000000000e+00
4.1666666666667e-01 3.3333333333333e-01 7.5000000000000e-01
0.0000000000000e+00 0.0000000000000e+00 5.0000000000000e-01
5.0000000000000e-01 2.5000000000000e-01 1.0000000000000e+00
8.3333333333333e-02 1.6666666666667e-01 7.5000000000000e-01
8.3333333333333e-02 4.1666666666667e-01 7.5000000000000e-01
1.6666666666667e-01 3.3333333333333e-01 1.0000000000000e+00
9.1666666666667e-01 8.3333333333333e-02 7.5000000000000e-01
6.6666666666667e-01 8.3333333333333e-02 1.0000000000000e+00
7.5000000000000e-01 5.0000000000000e-01 7.5000000000000e-01
7.5000000000000e-01 2.5000000000000e-01 7.5000000000000e-01
8.3333333333333e-01 1.6666666666667e-01 1.0000000000000e+00
8.3333333333333e-01 4.1666666666667e-01 1.0000000000000e+00
9.1666666666667e-01 3.3333333333333e-01 7.5000000000000e-01
5.0000000000000e-01 0.0000000000000e+00 5.0000000000000e-01
1.0000000000000e+00 2.5000000000000e-01 1.0000000000000e+00
5.8333333333333e-01 1.6666666666667e-01 7.5000000000000e-01
5.8333333333333e-01 4.1666666666667e-01 7.5000000000000e-01
6.6666666666667e-01 3.3333333333333e-01 1.0000000000000e+00
4.1666666666667e-01 5.8333333333333e-01 7.5000000000000e-01
1.6666666666667e-01 5.8333333333333e-01 1.0000000000000e+00
2.5000000000000e-01 1.0000000000000e+00 7.5000000000000e-01
2.5000000000000e-01 7.5000000000000e-01 7.5000000000000e-01
3.3333333333333e-01 6.6666666666667e-01 1.0000000000000e+00
3.3333333333333e-01 9.1666666666667e-01 1.0000000000000e+00
4.1666666666667e-01 8.3333333333333e-01 7.5000000000000e-01
0.0000000000000e+00 5.0000000000000e-01 5.0000000000000e-01
5.0000000000000e-01 7.5000000000000e-01 1.0000000000000e+00
8.3333333333333e-02 6.6666666666667e-01 7.5000000000000e-01
8.3333333333333e-02 9.1666666666667e-01 7.5000000000000e-01
1.6666666666667e-01 8.3333333333333e-01 1.0000000000000e+00
9.1666666666667e-01 5.8333333333333e-01 7.5000000000000e-01
6.6666666666667e-01 5.8333333333333e-01 1.0000000000000e+00
7.5000000000000e-01 1.0000000000000e+00 7.5000000000000e-01
7.5000000000000e-01 7.5000000000000e-01 7.5000000000000e-01
8.3333333333333e-01 6.6666666666667e-01 1.0000000000000e+00
8.3333333333333e-01 9.1666666666667e-01 1.0000000000000e+00
9.1666666666667e-01 8.3333333333333e-01 7.5000000000000e-01
5.0000000000000e-01 5.0000000000000e-01 5.0000000000000e-01
1.0000000000000e+00 7.5000000000000e-01 1.0000000000000e+00
5.8333333333333e-01 6.6666666666667e-01 7.5000000000000e-01
5.8333333333333e-01 9.1666666666667e-01 7.5000000000000e-01
6.6666666666667e-01 8.3333333333333e-01 1.0000000000000e+00