Introduction to atomman: System class
Lucas M. Hale, lucas.hale@nist.gov, Materials Science and Engineering Division, NIST.
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:
Right-handed box vectors.
avect = [lx, 0.0, 0.0]
bvect = [xy, ly, 0.0]
cvect = [xz, yz, lz]
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