LAMMPS#

In this example, we show how to run simulations with the popular molecular dynamics program LAMMPS through aiida-shell. A complete script can be downloaded here. Below we will go through the script step-by-step, followed by some tips for basic analysis of the results.

Warning

This example purely serves to illustrate how to use aiida-shell. There is no guarantee that LAMMPS is used correctly or in the most efficient way.

The most basic LAMMPS invocation looks as follows:

lmp -in input.file

The lmp executable is called passing the input.file file as an input using the -in command line option:

For the purposes of this example, we will take the input script for one of the official benchmarks. The complete input script can be downloaded here. We start our example script with some imports and by defining the input script:

Initial imports and script definition simulating the NVE ensemble for a simple Lennard-Jones fluid.#
#!/usr/bin/env runaiida
"""Simulation of Lennard-Jones fluid using LAMMPS."""
from aiida import orm
from aiida_shell import launch_shell_job

script = """
# 3d Lennard-Jones melt

variable      x index 1
variable      y index 1
variable      z index 1

variable      xx equal 20*$x
variable      yy equal 20*$y
variable      zz equal 20*$z

units         lj
atom_style    atomic

lattice       fcc 0.8442
region        box block 0 ${xx} 0 ${yy} 0 ${zz}
create_box    1 box
create_atoms  1 box
mass          1 1.0

velocity      all create 1.44 87287 loop geom

pair_style    lj/cut 2.5
pair_coeff    1 1 1.0 1.0 2.5

neighbor      0.3 bin
neigh_modify  delay 0 every 20 check no

fix           1 all nve
run           100
"""

The next step is to call the lmp for this input script. To do so, we use the launch_shell_job function of aiida-shell:

Run the lmp executable for the example script through aiida-shell.#
results, node = launch_shell_job(
    'lmp',
    arguments='-in {script}',
    nodes={
        'script': orm.SinglefileData.from_string(script),
    },
)

The first argument is the command that should be executed, which is lmp in this example. The arguments argument takes any command line options that should be passed. As shown in the introduction, this should be -in input.file. The difference here is that the script we want to run is not a file on disk, but defined in memory assigned to the script variable. Therefore, the input script filename in the arguments is replaced by the {script} placeholder. The actual script is then added to the nodes dictionary, where the content of the script is wrapped in AiiDA’s SinglefileData node class. This allows the script to be stored in the provenance graph. When launch_shell_job is called, it will ensure that the content of the script is copied to a file inside the working directory where lmp is invoked and the {script} placeholder is replaced with the filename.

The launch_shell_job function returns a tuple of two elements once the command has completed:

  • results: A dictionary of the outputs produced by the command

  • node: The node that represents the execution of the command in AiiDA’s provenance graph

These outputs can be used to inspect the results of the executed command:

Printing the state of the completed command and its results#
print(f'Calculation terminated: {node.process_state}')
print('Outputs:')
for key, node in results.items():
    print(f'{key}: {node.__class__.__name__}<{node.pk}>')

The output should look something like the following:

Calculation terminated: ProcessState.FINISHED
Outputs:
stderr: SinglefileData<100>
stdout: SinglefileData<101>

The numbers between the <> brackets are the pks of the output nodes. In this case, there are just two SinglefileData nodes that contain the output that was written to the stdout and stderr file descriptors. Their content can be retrieved by loading the node through its pk using AiiDA’s load_node function, and then calling the get_content method:

from aiida.orm import load_node
node = load_node(101)
print(node.get_content())

This should print the output written by LAMMPS which looks something like the following:

LAMMPS (20 Nov 2019)
Lattice spacing in x,y,z = 1.6796 1.6796 1.6796
Created orthogonal box = (0 0 0) to (33.5919 33.5919 33.5919)
  1 by 1 by 1 MPI processor grid
Created 32000 atoms
  create_atoms CPU = 0.00462803 secs
Neighbor list info ...
  update every 20 steps, delay 0 steps, check no
  max neighbors/atom: 2000, page size: 100000
  master list distance cutoff = 2.8
  ghost atom cutoff = 2.8
  binsize = 1.4, bins = 24 24 24
  1 neighbor lists, perpetual/occasional/extra = 1 0 0
  (1) pair lj/cut, perpetual
      attributes: half, newton on
      pair build: half/bin/atomonly/newton
      stencil: half/bin/3d/newton
      bin: standard
Setting up Verlet run ...
  Unit style    : lj
  Current step  : 0
  Time step     : 0.005
Per MPI rank memory allocation (min/avg/max) = 13.82 | 13.82 | 13.82 Mbytes
Step Temp E_pair E_mol TotEng Press
       0         1.44   -6.7733681            0   -4.6134356   -5.0197073
     100    0.7574531   -5.7585055            0   -4.6223613   0.20726105
Loop time of 2.32985 on 1 procs for 100 steps with 32000 atoms

Performance: 18541.947 tau/day, 42.921 timesteps/s
100.0% CPU use with 1 MPI tasks x no OpenMP threads

MPI task timing breakdown:
Section |  min time  |  avg time  |  max time  |%varavg| %total
---------------------------------------------------------------
Pair    | 1.9495     | 1.9495     | 1.9495     |   0.0 | 83.67
Neigh   | 0.30639    | 0.30639    | 0.30639    |   0.0 | 13.15
Comm    | 0.026903   | 0.026903   | 0.026903   |   0.0 |  1.15
Output  | 0.0001828  | 0.0001828  | 0.0001828  |   0.0 |  0.01
Modify  | 0.040458   | 0.040458   | 0.040458   |   0.0 |  1.74
Other   |            | 0.006424   |            |       |  0.28

Nlocal:    32000 ave 32000 max 32000 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost:    19657 ave 19657 max 19657 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs:    1.20283e+06 ave 1.20283e+06 max 1.20283e+06 min
Histogram: 1 0 0 0 0 0 0 0 0 0

Total # of neighbors = 1202833
Ave neighs/atom = 37.5885
Neighbor list builds = 5
Dangerous builds not checked
Total wall time: 0:00:02