Skip to main content

AiiDA plugin for LAMMPS

Project description

CI Status Coverage Status PyPI Code style: black

AiiDA LAMMPS plugin

This a LAMMPS plugin for AiiDA. This plugin contains 4 code types:

  • lammps.forces: Atomic single-point forces calculation
  • lammps.optimize: Crystal structure optimization
  • lammps.md: Molecular dynamics calculation
  • lammps.combinate: DynaPhoPy calculation using LAMMPS MD trajectory (currently untested)

Note: lammps.combinate requires aiida-phonopy (https://github.com/abelcarreras/aiida-phonopy) plugin to work, DynaPhoPy can be found in: https://github.com/abelcarreras/aiida-phonopy

Installation

To install from pypi:

pip install aiida-lammps

Built-in Potential Support

  • EAM
  • Lennad Jones
  • Tersoff
  • ReaxFF

Examples

More example calculations are found in the folder /examples, and there are many test examples in /aiida_lammps/tests/test_calculations.

Code Setup

from aiida_lammps.tests.utils import (
    get_or_create_local_computer, get_or_create_code)
from aiida_lammps.tests.utils import lammps_version

computer_local = get_or_create_local_computer('work_directory', 'localhost')
code_lammps_force = get_or_create_code('lammps.force', computer_local, 'lammps')
code_lammps_opt = get_or_create_code('lammps.optimize', computer_local, 'lammps')
code_lammps_md = get_or_create_code('lammps.md', computer_local, 'lammps')

meta_options = {
    "resources": {
        "num_machines": 1,
        "num_mpiprocs_per_machine": 1}
}

Structure Setup

from aiida.plugins import DataFactory
import numpy as np

cell = [[3.1900000572, 0, 0],
        [-1.5950000286, 2.762621076, 0],
        [0.0, 0, 5.1890001297]]

positions = [(0.6666669, 0.3333334, 0.0000000),
             (0.3333331, 0.6666663, 0.5000000),
             (0.6666669, 0.3333334, 0.3750000),
             (0.3333331, 0.6666663, 0.8750000)]

symbols = names = ['Ga', 'Ga', 'N', 'N']

structure = DataFactory('structure')(cell=cell)
for position, symbol, name in zip(positions, symbols, names):
    position = np.dot(position, cell).tolist()
    structure.append_atom(
        position=position, symbols=symbol, name=name)

structure
<StructureData: uuid: 96f9c02b-77c7-4889-9de2-dbda27bb03fa (unstored)>

Potential Setup

pair_style = 'tersoff'
potential_dict = {
    'Ga Ga Ga': '1.0 0.007874 1.846 1.918000 0.75000 -0.301300 1.0 1.0 1.44970 410.132 2.87 0.15 1.60916 535.199',
    'N  N  N': '1.0 0.766120 0.000 0.178493 0.20172 -0.045238 1.0 1.0 2.38426 423.769 2.20 0.20 3.55779 1044.77',
    'Ga Ga N': '1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 0.0 0.00000 0.00000 2.90 0.20 0.00000 0.00000',
    'Ga N  N': '1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 1.0 2.63906 3864.27 2.90 0.20 2.93516 6136.44',
    'N  Ga Ga': '1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 1.0 2.63906 3864.27 2.90 0.20 2.93516 6136.44',
    'N  Ga N ': '1.0 0.766120 0.000 0.178493 0.20172 -0.045238 1.0 0.0 0.00000 0.00000 2.20 0.20 0.00000 0.00000',
    'N  N  Ga': '1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 0.0 0.00000 0.00000 2.90 0.20 0.00000 0.00000',
    'Ga N  Ga': '1.0 0.007874 1.846 1.918000 0.75000 -0.301300 1.0 0.0 0.00000 0.00000 2.87 0.15 0.00000 0.00000'}
potential = DataFactory("lammps.potential")(
    structure=structure, type=pair_style, data=potential_dict
)
potential.attributes
{'kind_elements': ['Ga', 'N'],
 'potential_type': 'tersoff',
 'atom_style': 'atomic',
 'default_units': 'metal',
 'potential_md5': 'b3b7d45ae7b92eba05ed99ffe69810d0',
 'input_lines_md5': '3145644a408a6d464e80866b833115a2'}

Force Calculation

from aiida.engine import run_get_node
parameters = DataFactory('dict')(dict={
    'lammps_version': lammps_version(),
    'output_variables': ["temp", "etotal", "pe", "ke"],
    'thermo_keywords': []
})
builder = code_lammps_force.get_builder()
builder.metadata.options = meta_options
builder.structure = structure
builder.potential = potential
builder.parameters = parameters
result, calc_node = run_get_node(builder)
$ verdi process list -D desc -a -l 1
  PK  Created    Process label     Process State    Process status
----  ---------  ----------------  ---------------  ----------------
2480  32s ago    ForceCalculation  Finished [0]

Total results: 1

Info: last time an entry changed state: 28s ago (at 02:02:36 on 2019-06-21)

$ verdi process show 2480
Property       Value
-------------  ------------------------------------
type           CalcJobNode
pk             2480
uuid           c754f044-b190-4505-b121-776b79d2d1c8
label
description
ctime          2019-06-21 02:02:32.894858+00:00
mtime          2019-06-21 02:02:33.297377+00:00
process state  Finished
exit status    0
computer       [2] localhost

Inputs        PK  Type
----------  ----  ------------------
code        1351  Code
parameters  2479  Dict
potential   2478  EmpiricalPotential
structure   2477  StructureData

Outputs          PK  Type
-------------  ----  ----------
arrays         2483  ArrayData
remote_folder  2481  RemoteData
results        2484  Dict
retrieved      2482  FolderData
calc_node.outputs.results.attributes
{'parser_version': '0.4.0b3',
 'parser_class': 'ForceParser',
 'errors': [],
 'warnings': '',
 'distance_units': 'Angstroms',
 'force_units': 'eV/Angstrom',
 'energy_units': 'eV',
 'energy': -18.1098859130104,
 'final_variables': {'ke': 0.0,
  'pe': -18.1098859130104,
  'etotal': -18.1098859130104,
  'temp': 0.0},
 'units_style': 'metal'}
calc_node.outputs.arrays.attributes
{'array|forces': [1, 4, 3]}

Optimisation Calculation

from aiida.engine import run_get_node
parameters = DataFactory('dict')(dict={
    'lammps_version': lammps_version(),
    'output_variables': ["temp", "etotal", "pe", "ke"],
    'thermo_keywords': [],
    'units': 'metal',
    'relax': {
        'type': 'iso',
        'pressure': 0.0,
        'vmax': 0.001,
    },
    "minimize": {
        'style': 'cg',
        'energy_tolerance': 1.0e-25,
        'force_tolerance': 1.0e-25,
        'max_evaluations': 100000,
        'max_iterations': 50000}
})
builder = code_lammps_opt.get_builder()
builder.metadata.options = meta_options
builder.structure = structure
builder.potential = potential
builder.parameters = parameters
result, calc_node = run_get_node(builder)
$ verdi process list -D desc -a -l 1
  PK  Created    Process label        Process State    Process status
----  ---------  -------------------  ---------------  ----------------
2486  1m ago     OptimizeCalculation  ⏹ Finished [0]

Total results: 1

Info: last time an entry changed state: 1m ago (at 02:09:54 on 2019-06-21)

$ verdi process show 2486
Property       Value
-------------  ------------------------------------
type           CalcJobNode
pk             2486
uuid           5c64433d-6337-4352-a0a8-0acb4083a0c3
label
description
ctime          2019-06-21 02:09:50.872336+00:00
mtime          2019-06-21 02:09:51.128639+00:00
process state  Finished
exit status    0
computer       [2] localhost

Inputs        PK  Type
----------  ----  ------------------
code        1344  Code
parameters  2485  Dict
potential   2478  EmpiricalPotential
structure   2477  StructureData

Outputs          PK  Type
-------------  ----  -------------
arrays         2490  ArrayData
remote_folder  2487  RemoteData
results        2491  Dict
retrieved      2488  FolderData
structure      2489  StructureData
calc_node.outputs.results.attributes
{'parser_version': '0.4.0b3',
 'parser_class': 'OptimizeParser',
 'errors': [],
 'warnings': '',
 'stress_units': 'bars',
 'distance_units': 'Angstroms',
 'force_units': 'eV/Angstrom',
 'energy_units': 'eV',
 'energy': -18.1108516231423,
 'final_variables': {'ke': 0.0,
  'pe': -18.1108516231423,
  'etotal': -18.1108516231423,
  'temp': 0.0},
 'units_style': 'metal'}
calc_node.outputs.arrays.attributes
{'array|positions': [56, 4, 3],
 'array|stress': [3, 3],
 'array|forces': [56, 4, 3]}

MD Calculation

from aiida.engine import submit
parameters = DataFactory('dict')(dict={
    'lammps_version': lammps_version(),
    'output_variables': ["temp", "etotal", "pe", "ke"],
    'thermo_keywords': [],
    'units': 'metal',
    'timestep': 0.001,
    'integration': {
        'style': 'nvt',
        'constraints': {
            'temp': [300, 300, 0.5]
        }
    },
    "neighbor": [0.3, "bin"],
    "neigh_modify": {"every": 1, "delay": 0, "check": False},
    'equilibrium_steps': 100,
    'total_steps': 1000,
    'dump_rate': 10,
    'restart': 100
})
builder = code_lammps_md.get_builder()
builder.metadata.options = meta_options
builder.structure = structure
builder.potential = potential
builder.parameters = parameters
result, calc_node = run_get_node(builder)
$ verdi process list -D desc -a -l 1
  PK  Created    Process label    Process State    Process status
----  ---------  ---------------  ---------------  ----------------
2493  12s ago    MdCalculation    ⏹ Finished [0]

Total results: 1

Info: last time an entry changed state: 4s ago (at 02:15:02 on 2019-06-21)

$ verdi process show 2493
Property       Value
-------------  ------------------------------------
type           CalcJobNode
pk             2493
uuid           351b4721-10ff-406c-8f1c-951317091524
label
description
ctime          2019-06-21 02:14:54.986384+00:00
mtime          2019-06-21 02:14:55.282272+00:00
process state  Finished
exit status    0
computer       [2] localhost

Inputs        PK  Type
----------  ----  ------------------
code        1540  Code
parameters  2492  Dict
potential   2478  EmpiricalPotential
structure   2477  StructureData

Outputs            PK  Type
---------------  ----  --------------
remote_folder    2494  RemoteData
results          2496  Dict
retrieved        2495  FolderData
system_data      2498  ArrayData
trajectory_data  2497  TrajectoryData
calc_node.outputs.results.attributes
{'parser_version': '0.4.0b3',
 'parser_class': 'MdParser',
 'errors': [],
 'warnings': '',
 'time_units': 'picoseconds',
 'distance_units': 'Angstroms',
 'energy': -17.8464193488116,
 'units_style': 'metal'}
calc_node.outputs.system_data.attributes
{'units_style': 'metal',
 'array|step': [100],
 'array|ke': [100],
 'array|pe': [100],
 'array|etotal': [100],
 'array|temp': [100]}
calc_node.outputs.trajectory_data.attributes
{'array|times': [101],
 'array|cells': [101, 3, 3],
 'array|steps': [101],
 'array|positions': [101, 4, 3],
 'symbols': ['Ga', 'Ga', 'N', 'N']}

Development

Coding Style Requirements

The code is formatted and linted using pre-commit, which runs in an isolated, virtual environment:

>> pip install pre-commit
>> pre-commit run --all

or to automate runs, triggered before each commit:

>> pre-commit install

Testing

the test suite can be run in an isolated, virtual environment using tox (see tox.ini in the repo):

>> pip install tox
>> tox -e py37

or directly:

>> pip install -e .[testing]
>> reentry scan -r aiida
>> pytest -v

The tests require that both PostgreSQL and RabbitMQ are running. If you wish to run an isolated RabbitMQ instance, see the docker-compose.yml file in the repo.

Some tests require that a lammps executable be present.

The easiest way to achieve this is to use Conda:

>> conda install lammps==2019.06.05
# this will install lmp_serial and lmp_mpi

You can specify a different executable name for LAMMPS with:

>> tox -e py37 -- --lammps-exec lmp_exec

To output the results of calcjob executions to a specific directory:

>> pytest --lammps-workdir "test_workdir"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aiida-lammps-0.8.0.tar.gz (274.9 kB view hashes)

Uploaded Source

Built Distribution

aiida_lammps-0.8.0-py3-none-any.whl (295.0 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page