lammpslib module

ASE LAMMPS Calculator Library Version

class lammpslib.LAMMPSlib(restart=None, ignore_bad_restart_file=<object object>, label=None, atoms=None, directory='.', **kwargs)[source]

Bases: Calculator

LAMMPSlib Interface Documentation

Introduction

LAMMPSlib is an interface and calculator for LAMMPS. LAMMPSlib uses the python interface that comes with LAMMPS to solve an atoms model for energy, atom forces and cell stress. This calculator creates a ‘.lmp’ object which is a running lammps program, so further commands can be sent to this object executed until it is explicitly closed. Any additional variables calculated by lammps can also be extracted. This is still experimental code.

Arguments

Keyword

Description

lmpcmds

list of strings of LAMMPS commands. You need to supply enough to define the potential to be used e.g.

[“pair_style eam/alloy”,

“pair_coeff * * potentials/NiAlH_jea.eam.alloy Ni Al”]

atom_types

dictionary of “atomic_symbol”:lammps_atom_type pairs, e.g. {‘Cu’:1} to bind copper to lammps atom type 1. Default method assigns lammps atom types in order that they appear in the atoms model. Mandatory.

log_file

string path to the desired LAMMPS log file

lammps_header

string to use for lammps setup. Default is to use metal units and simple atom simulation.

lammps_header=[‘units metal’,

‘atom_style atomic’, ‘atom_modify map array sort 0 0’])

keep_alive

Boolean whether to keep the lammps routine alive for more commands

Requirements

To run this calculator you must have LAMMPS installed and compiled to enable the python interface. See the LAMMPS manual.

If the following code runs then lammps is installed correctly.

>>> from lammps import lammps
>>> lmp = lammps()

The version of LAMMPS is also important. LAMMPSlib is suitable for versions after approximately 2011. Prior to this the python interface is slightly different from that used by LAMMPSlib. It is not difficult to change to the earlier format.

LAMMPS and LAMMPSlib

The LAMMPS calculator is another calculator that uses LAMMPS (the program) to calculate the energy by generating input files and running a separate LAMMPS job to perform the analysis. The output data is then read back into python. LAMMPSlib makes direct use of the LAMMPS (the program) python interface. As well as directly running any LAMMPS comand line it allows the values of any of LAMMPS variables to be extracted and returned to python.

Example

from ase import Atom, Atoms
from lammpslib import LAMMPSlib

cmds = ["pair_style eam/alloy",
        "pair_coeff * * NiAlH_jea.eam.alloy Al H"]

a = 4.05
al = Atoms([Atom('Al')], cell=(a, a, a), pbc=True)
h = Atom([Atom('H')])
alh = al + h

lammps = LAMMPSlib(lmpcmds = cmds, logfile='test.log')

alh.set_calculator(lammps)
print "Energy ", alh.get_potential_energy()

Implementation

LAMMPS provides a set of python functions to allow execution of the underlying C++ LAMMPS code. The functions used by the LAMMPSlib interface are:

from lammps import lammps

lmp = lammps(cmd_args) # initiate LAMMPS object with command line args

lmp.scatter_atoms('x',1,3,positions) # atom coords to LAMMPS C array
lmp.command(cmd) # executes a one line cmd string
lmp.extract_variable(...) # extracts a per atom variable
lmp.extract_global(...) # extracts a global variable
lmp.close() # close the lammps object

For a single atom model the following lammps file commands would be run by invoking the get_potential_energy() method:

units metal
atom_style atomic
atom_modify map array sort 0 0

region cell prism 0 xhi 0 yhi 0 zhi xy xz yz units box
create_box 1 cell
create_atoms 1 single 0 0 0 units box
mass * 1.0

## user lmpcmds get executed here
pair_style eam/alloy
pair_coeff * * lammps/potentials/NiAlH_jea.eam.alloy Al
## end of user lmmpcmds

run 0

Notes

  • Units: The default lammps_header sets the units to Angstrom and eV and for compatibility with ASE Stress is in GPa.

  • The global energy is currently extracted from LAMMPS using extract_variable since lammps.lammps currently extract_global only accepts the following [‘dt’, ‘boxxlo’, ‘boxxhi’, ‘boxylo’, ‘boxyhi’, ‘boxzlo’, ‘boxzhi’, ‘natoms’, ‘nlocal’].

  • If an error occurs while lammps is in control it will crash Python. Check the output of the log file to find the lammps error.

  • If the are commands direfctly sent to the LAMMPS object this may change the energy value of the model. However the calculator will not know of it and still return the original energy value.

End LAMMPSlib Interface Documentation

calculate(atoms, properties, system_changes)[source]

Do the calculation.

properties: list of str

List of what needs to be calculated. Can be any combination of ‘energy’, ‘forces’, ‘stress’, ‘dipole’, ‘charges’, ‘magmom’ and ‘magmoms’.

system_changes: list of str

List of what has changed since last calculation. Can be any combination of these six: ‘positions’, ‘numbers’, ‘cell’, ‘pbc’, ‘initial_charges’ and ‘initial_magmoms’.

Subclasses need to implement this, but can ignore properties and system_changes if they want. Calculated properties should be inserted into results dictionary like shown in this dummy example:

self.results = {'energy': 0.0,
                'forces': np.zeros((len(atoms), 3)),
                'stress': np.zeros(6),
                'dipole': np.zeros(3),
                'charges': np.zeros(len(atoms)),
                'magmom': 0.0,
                'magmoms': np.zeros(len(atoms))}

The subclass implementation should first call this implementation to set the atoms attribute and create any missing directories.

default_parameters: Dict[str, Any] = {'atom_types': None, 'boundary': True, 'comm': None, 'create_atoms': True, 'create_box': True, 'keep_alive': False, 'lammps_header': ['units metal', 'atom_style atomic', 'atom_modify map array sort 0 0'], 'lammps_name': '', 'log_file': None, 'read_molecular_info': False}

Default parameters

implemented_properties: List[str] = ['energy', 'forces', 'stress']

Properties calculator can handle (energy, forces, …)

initialise_lammps(atoms)[source]
initialized = False
lammpsbc(pbc)[source]
parse_angles(atoms)[source]
parse_bonds(atoms)[source]
parse_dihedrals(atoms)[source]
parse_impropers(atoms)[source]
propagate(atoms, properties, system_changes, n_steps, dt=None, dt_not_real_time=False, velocity_field=None)[source]
“atoms: Atoms object

Contains positions, unit-cell, …

properties: list of str

List of what needs to be calculated. Can be any combination of ‘energy’, ‘forces’, ‘stress’, ‘dipole’, ‘charges’, ‘magmom’ and ‘magmoms’.

system_changes: list of str

List of what has changed since last calculation. Can be any combination of these five: ‘positions’, ‘numbers’, ‘cell’, ‘pbc’, ‘charges’ and ‘magmoms’.

rebuild(atoms)[source]
redo_atom_types(atoms)[source]
restart_lammps(atoms)[source]
set_angles(atoms)[source]
set_bonds(atoms)[source]
set_cell(atoms, change=False)[source]
set_charges(atoms)[source]
set_dihedrals(atoms)[source]
set_impropers(atoms)[source]
set_lammps_pos(atoms)[source]
start_lammps()[source]
started = False
lammpslib.convert_cell(ase_cell)[source]

Convert a parallel piped (forming right hand basis) to lower triangular matrix LAMMPS can accept. This function transposes cell matrix so the bases are column vectors

lammpslib.is_upper_triangular(mat)[source]

test if 3x3 matrix is upper triangular

lammpslib.unit_convert(quantity, units='metal')[source]
lammpslib.write_lammps_data(filename, atoms, atom_types, comment=None, cutoff=None, molecule_ids=None, charges=None, units='metal', bond_types=None, angle_types=None, dihedral_types=None, improper_types=None)[source]