Atomic and Molecular Modeling Language

The Atomic and Molecular Modeling Language (AMML) is designed as a modular extension of the Scientific Computing Language (SCL).

The language provides builtin types, expressions and functions specific for atomistic modeling and simulation.

Structure

An atomic structure can be defined using the Structure literal. It has the following syntax

Structure [optional name] <Table>

The <Table> parameter is a Table literal with specific constraints listed in the following.

name

description

data struct

type

shape

dimensionality

atoms

individual atoms structures

Series

Table

columns: symbols, x, y, z, px, py, pz, tags, masses

None

cell

unit cell

Series

FloatArray

(3, 3)

[length]

pbc

periodic boundary conditions

Series

BoolArray

(3)

None

Every tuple (row, record) in the top-level Table corresponds to an individual atomic, or molecular, structure. The atoms column is a special case: every element of the atoms column, is also a Table whose own columns hold the properties of chemical species such as: atomic symbols, positions, masses, momenta, etc. So the Table parameter of the Structure literal contains the atoms Table nested within. The columns of the atoms sub-table have the following constraints:

name

description

data struct

type

shape

dimensionality

symbols

the chemical symbols

Series

String

scalar

None

x

the cartesian x position

Series

Float

scalar

[length]

y

the cartesian y position

Series

Float

scalar

[length]

z

the cartesian z position

Series

Float

scalar

[length]

px

cartesian momentum along x

Series

Float

scalar

[length mass time-1]

py

cartesian momentum along y

Series

Float

scalar

[length mass time-1]

pz

cartesian momentum along z

Series

Float

scalar

[length mass time-1]

masses

the atomic mass

Series

Float

scalar

[mass]

tags

tag

Series

Integer

scalar

[dimensionless]

Example:

water = Structure H2O (
         (atoms: ((symbols: 'O', 'H', 'H'),
                  (x: 0., 0., 0.) [nm],
                  (y: 0., 0.763239, -0.763239) [angstrom],
                  (z: 0.119262, -0.477047, -0.477047) [angstrom],
                  (tags: 1, 0, 0),
                  (masses: 16., 1., 1.) [amu]
                 )
         ),
         (cell: [[5., 0., 0.], [0., 5., 0.], [0., 0., 5.]] [bohr]),
         (pbc: [false, false, false])
       )

An atomic structure can be loaded from a file, e.g.:

water = Structure from file 'h2o.xyz'

Note that, when loading from file, there would be no water.name parameter.

The parameters contained in a Structure parameter can be accessed using the common subscripting or slice syntax:

print(water.name) # name of structure
print(water.atoms) # the series with atoms tables
print(water.atoms[0]) # atoms table of the first structure
print(water.atoms[0:1]) # series with atoms inluding only the first structure
print(water.pbc) # series of boolean arrays
print(water.cell) # series of float arrays
print(water.cell[0]) # the cell of the first structure as float array
print(water[0]) # a tuple (atoms, cell, pbc) of the first structure
print(water[0:1]) # a table containing the first structure

Computed parameters available in Structure

All parameters of the structure do not depend on external parameters but some of them depend on other Structure parameters. These dependent parameters can be computed without further input. For example, the kinetic energy depends on the momenta and the masses. These parameters can be accessed in the same way as the parameters in the Structure literal, for example the kinetic energy of the nuclei:

print(water.kinetic_energy)

The computed parameters are summarized in the following table.

name

description

data struct

type

shape

dimensionality

kinetic_energy

nuclear kinetic energy

Series

float

scalar

[length2 mass time-2]

temperature

temperature

Series

float

scalar

[temperature]

distance_matrix

matrix of inter-atomic distances

Series

FloatArray

(N, N)

[length]

chemical_formula

brute formula / composition

Series

String

scalar

None

number_of_atoms

number of atoms

Series

Integer

scalar

None

cell_volume

volume of the cell

Series

Float

scalar

[length]3

center_of_mass

center of mass

Series

FloatArray

(3, )

[length]

radius_of_gyration

radius of gyration

Series

Float

scalar

[length]

moments_of_inertia

moments of inertia along the principal axes

Series

FloatArray

(3, )

[mass length2]

angular_momentum

the total angular momentum with respect to the center of mass

Series

FloatArray

(3, )

[mass length2 time-1]

Calculator

A Calculator parameter describes operations to be performed on a Structure parameter typically employing computational tools external to the AMML, e.g. molecular dynamics or quantum chemistry packages. It is commonly used within the Property parameter. The Calculator has the following syntax:

Calculator <name> [ >|<|==|>=|<= <version>] <Table>[, task: <task>]
Calculator <name> [ >|<|==|>=|<= <version>] (default)[, task: <task>]
Calculator <name> [ >|<|==|>=|<= <version>] ()[, task: <task>]

The specification of name is mandatory. Currently name must be one of vasp, turbomole, lj, emt.

The version specification is optional. Currently it is not interpreted.

The actual calculator parameters can be specified as series in the top-level table. The paramater names, type and units depend on the calculator. The table below lists the parameters of the currently supported calculators. If only default parameters have to be used then no Table parameter is needed and the syntax is (default) or simply ().

Example for a VASP calculator with one parameter set:

calc = Calculator vasp == 5.4.4 (
        (algo: 'Fast'),
        (ediff: 1e-06) [eV],
        (ediffg: -0.01) [eV/angstrom],
        (encut: 400.0) [eV],
        (ibrion: 2),
        (icharg: 2),
        (isif: 2),
        (ismear: 0),
        (ispin: 2),
        (istart: 0),
        (kpts: [5, 5, 1]),
        (lcharg: false),
        (lreal: 'Auto'),
        (lwave: false),
        (nelm: 250),
        (nsw: 1500),
        (potim: 0.1),
        (prec: 'Normal'),
        (sigma: 0.1) [eV],
        (xc: 'PBE')
), task: local minimum

NOTE: The AMML language can be extended to support further calculators. This is fairly straight forward because the current implementation of AMML interpreter is based on the Atomic Simulation Environment (ASE). Particularly, the AMML Calculator parameter can reuse any existing ASE Calculator class. The process of integration of further calculators into AMML is basically a registration of the name in the grammar and of function to check calculator parameter types and units.

The parameters stored in the calculator can be accessed using the subscripting and slice syntax:

print(calc.parameters) # top-level table of parameters
print(new.name) # calculator's name
print(calc.pinning, calc.version) # if not set `null` will be printed
print(calc[0]) # a tuple of the first parameter set
print(new_calc[0:1]) # table with the first parameter set

NOTE: The calculator parameter names and types are identical with those in the Atomic Simulation Environment (ASE). For this information we refer to the ASE documentation of the calculators. The physical units (or their dimension) of the calculator parameters are not always fully and systematically documented. While units / dimensionality checks are already performed independently by the AMML interpreter (with error messages suggesting relevant corrections), this information is not yet provided here. For now, the user of AMML should consult the manuals of the original codes.

The special parameter task can be currently one of the following strings: single point, local minimum, global minimum, transition state, normal modes, micro-canonical,canonical, isothermal-isobaric, grand-canonical. Currently, the task parameter is only used to perform consistency checks.

Constraint

The Constraint parameter describes constraints to be applied to atomic positions. A constraints is pertaining to (but not an integral part of) a specific Structure parameter.

c1 = FixedAtoms where <fixed>
c2 = FixedLine collinear to <direction> where <fixed>
c3 = FixedPlane normal to <direction> where <fixed>

The <fixed> parameter is a Series of Boolean type, whose length should be equal to the number of atoms in the structure to which the constraint will be applied. It indicates which atoms are included in the constraint (true elemenets) and which are not (false elements).

The <direction> parameter is an Array of Integer type of length 3 and represents a vector in cartesian space [x, y, z].

Examples:

h2o_plane = FixedPlane normal to [0, 0, 1] where (fix: true, true, true) # allow changes in xy plane
h2_line = FixedLine collinear to [0, 0, 1] where (fix: true, true) # allow changes along z axis
h2_fix0 = FixedAtoms where (fix: true, false) # fix first atom in H2

NOTE: Extensions of the AMML with further types of contstraints is possible.

Algorithm

The AMML Algorithm parameter describes operations that are either available as algorithms in the Atomic Simulation Environment (ASE) or are user-defined routines. For example, the BFGS structure optimization is an algorithm. Further available algorithms are: BFGSLineSearch, LBFGS, LBFGSLineSearch, GPMin, MDMin, QuasiNewton, FIRE, VelocityVerlet, Langevin, Andersen, NVTBerendsen, NPTBerendsen, NPT, RDF, RMSD. Not implemented: BFGSClimbFixInternals, NEB, Dimer, BasinHopping, MinimaHopping, GA, PourbaixDiagram, PhaseDiagram, Inertia.

The general syntax of Algorithm is:

Algorithm <name> <Table>
Algorithm <name> (default)
Algorithm <name> ()

Example: Structure optimization of a structure h2o with calculator calc.

algo = Algorithm BFGS ((fmax: 1e-4) [hartree/bohr], (steps: 30))
prop = Property energy, forces ((structure: h2o), (calculator: calc), (algorithm: algo))

As for the calculators, the numerical parameters of algorithms must have explicit units.

Algorithms

Parameter name

Parameter type

Default value

Dimensionality

Sample unit

BFGS

steps

Integer

100000000

[dimensionless]

maxstep

Float

0.2 [Å]

[length]

[Å]

fmax

Float

0.05 [eV Å-1]

[length mass time2]

[eV Å-1]

logfile

String

null

trajectory

Boolean

null

interval

Integer

1

[dimensionless]

alpha

Float

70.0 [eV Å-2]

[mass time-2]

[eV Å-2]

BFGSLineSearch

steps

Integer

100000000

[dimensionless]

maxstep

Float

0.2 [Å]

[length]

[Å]

fmax

Float

0.05 [eV Å-1]

[length mass time-2]

[eV Å-1]

logfile

String

null

trajectory

Boolean

null

interval

Integer

1

[dimensionless]

LBFGS

steps

Integer

100000000

[dimensionless}

maxstep

Float

0.2 [Å]

[length]

[Å]

fmax

Float

0.05 [eV Å-1]

[length mass time-2]

[eV Å-1]

logfile

String

null

trajectory

Boolean

null

interval

Integer

1

[dimensionless]

memory

Integer

100

[dimensionless]

damping

Float

1.0

[dimensionless]

alpha

Float

70.0 [eV Å-2]

[mass time-2]

[eV Å-2]

LBFGSLineSearch

steps

Integer

100000000

[dimensionless]

maxstep

Float

0.2 [Å]

[length]

[Å]

fmax

Float

0.05 [eV Å-1]

[length mass time-2]

[eV Å-1]

logfile

String

null

trajectory

Boolean

null

interval

Integer

1

[dimensionless]

memory

Integer

100

[dimensionless]

damping

Float

1.0

[dimensionless]

alpha

Float

70.0 [eV Å-2]

[mass time-2]

[eV Å-2]

QuasiNewton

steps

Integer

100000000

[dimensionless]

maxstep

Float

0.2 [Å]

[length]

[Å]

fmax

Float

0.05 [eV Å-1]

[length mass time-2]

[eV Å-1]

logfile

String

null

trajectory

Boolean

null

interval

Integer

1

[dimensionless]

GPMin

steps

Integer

100000000

[dimensionless]

fmax

Float

0.05 [eV Å-1]

[length mass time-2]

[eV Å-1]

logfile

String

null

trajectory

Boolean

null

interval

Integer

1

[dimensionless]

prior

Object

null

kernel

Object

null

update_prior_strategy

String

‘maximum’

update_hyperparams

Boolean

false

noise

Float

0.005

[dimensionless]

weight

Float

1.0

[dimensionless]

scale

Float

0.4

[dimensionless]

FIRE

steps

Integer

100000000

[dimensionless]

maxstep

Float

0.2 [Å]

[length]

[Å]

fmax

Float

0.05 [eV Å-1]

[length mass time-2]

[eV Å-1]

logfile

String

null

trajectory

Boolean

null

interval

Integer

1

[dimensionless]

dt

Float

0.1 [Å (amu / eV)1/2]

[time]

[ps]

dtmax

Float

1.0 [Å (amu / eV)1/2]

[time]

[ps]

downhill_check

Boolean

false

MDMin

steps

Integer

100000000

[dimensionless]

maxstep

Float

0.2 [Å]

[length]

[Å]

fmax

Float

0.05 [eV Å]-1

[length mass time-2]

[eV Å-1]

logfile

String

null

trajectory

Boolean

null

interval

Integer

1

[dimensionless]

dt

Float

0.2 [Å (amu / eV)1/2]

[time]

[ps]

RMSD

reference

Structure

adjust

Boolean

true

RDF

rmax

Float

null [Å]

[length]

[Å]

nbins

Integer

400

[dimensionless]

neighborlist

NeighborList

null

neighborlist_pars

Table

()

elements

String

null

VelocityVerlet

steps

Integer

50

[dimensionless]

logfile

String

null

trajectory

String

null

interval

Integer

1

[dimensionless]

timestep

Float

[time]

[ps]

Langevin

steps

Integer

50

[dimensionless]

logfile

String

null

trajectory

String

null

interval

Integer

1

[dimensionless]

timestep

Float

[time]

[ps]

temperature_K

Float

[temperature]

[K]

friction

Float

[time-1]

[ps-1]

fixcm

Boolean

true

NPT

steps

Integer

50

[dimensionless]

logfile

String

null

trajectory

String

null

interval

Integer

1

[dimensionless]

timestep

Float

[time]

[ps]

temperature_K

Float

[temperature]

[K]

externalstress

Float

[mass length-1 time-2]

[N m-2], [Pa]

ttime

Float

[time]

[ps]

pfactor

Float

[mass length-1]

[amu Å-1]

Andersen

steps

Integer

50

[dimensionless]

logfile

String

null

trajectory

String

null

interval

Integer

1

[dimensionless]

timestep

Float

[time]

[ps]

temperature_K

Float

[temperature]

[K]

andersen_prob

Float

[dimensionless]

fixcm

Boolean

true

NVTBerendsen

step

Integer

50

[dimensionless]

logfile

String

null

trajectory

String

null

interval

Integer

1

[dimensionless]

timestep

Float

[time]

[ps]

temperature_K

Float

[temperature]

[K]

taut

Float

[time]

[ps]

fixcm

Boolean

true

NPTBerendsen

step

Integer

50

[dimensionless]

logfile

String

null

trajectory

String

null

interval

Integer

1

[dimensionless]

timestep

Float

[time]

[ps]

temperature_K

Float

[temperature]

[K]

pressure_au

Float

[mass length-1 time-2]

[N m-2], [Pa]

taut

Float

0.5 [ps]

[time]

[ps]

taup

Float

1.0 [ps]

[time]

[ps]

compressibility

Float

[mass length-1 time]-2]

[N m-2], [Pa]

fixcm

Boolean

true

Trajectory

Some algorithms return trajectories as properties. The trajectory type has these properties:

  • description: A table including information about the algorith that has produced the trajectory. For example, here the description from a Langevin molecular dynamics run:

    ((type: 'molecular-dynamics'),
     (md-type: 'Langevin'),
     (timestep: 0.09822694750253275) [angstrom * unified_atomic_mass_unit ** 0.5 / electron_volt ** 0.5],
     (temperature_K: 300.0) [kelvin],
     (friction: 0.5090252855379708) [electron_volt ** 0.5 / angstrom / unified_atomic_mass_unit ** 0.5],
     (fixcm: true),
     (interval: 1))
    

    Note that the units are the units used by ASE internally.

  • structure: A structure containing all configurations of the processed structure.

  • properties: A table with the properties stored for each configuration.

  • constraints: A tuple of constraints

  • filename: The path to the file where the trajectory is stored.

The trajectory can be extracted from the property using the common syntax prop.trajectory which returns a series of trajectory parameters. The individual trajectories can be accessed by subscripting, e.g. the first element can be retrieved with prop.trajectory[0]. The trajectory attributes can be then accessed using the common syntax trajectory[0].description.

Property

Using the AMML Property parameter a set of properties will be computed for a specific AMML Structure with a specific method. The method can be specified either by an AMML Calculator or by an AMML Algorithm, or a combination of Algorithm and Calculator.

Syntax:

prop = Property name1[, name2[...]]
        ((structure: struct),
         (calculator: calc),
         (algorithm: algo),
         (constraints: (c1[, c2[, ...]]))
        )

The names of currently interpreted properties are summarized in the table below. The parameters struct, calc, algo, and c1, … are names of variables of the corresponding types Structure, Calculator, Algorithm and Constraint respectively. The ordering of these parameters is arbitrary. Only the structure parameter is mandatory. The following table provides an overview of currently supported properties with their types and default output units. The output units can be changed using a modifier.

propery name

type

units (of output)

description

energy_minimum

Boolean

None

true if geometry is minimum, false otherwise; available only with a calculator with task normal modes

transition_state

Boolean

None

true if geometry is transition state, false otherwise; available only with a calculator with task normal modes

energy

Float

[eV]

total energy without nuclear kinetic energy; if the structure has been modified by the algorithm or calculator then this is the energy of the final structure

forces

FloatArray

[eV / Å]

the forces for each atom, i.e. the first derivative of energy with a minus sign; if the structure has been modified by the algorithm or calculator then these are the forces in the final structure

dipole

FloatArray

[e Å]

the total electrostatic dipole moment; if the structure has been modified by the algorithm or calculator then this is the dipole moment of the final structure

vibrational_energies

Series(Float)

[eV]

vibrational energies (frequencies) corresponding to the non-negative eigenvalues of the harmonic normal modes; available only with a calculator with task normal modes

stress

FloatArray

[eV / Å3]

the total stress in Voigt notation

trajectory

Trajectory

None

a Series of trajectory parameters, each with the attributes: description, structure, properties, constraints, and filename; available only through selected algorithms

After initializing a variable with a Property parameter, the individual properties can be accessed using subscripting.

Examples:

props = Property energy, forces ((structure: h2o), (calculator: calc))

print(props) # print the whole property parameter
print(props[0]) # return the first tuple of the property parameter
print(props.structure) # return the initial Structure parameter
print(props.calculator) # return the initial Calculator parameter
print(props.names) # return the property names
print(props.calculator[0:1]) # return a slice of the initial calc
print(props.calculator.name) # return the name of the inital calc
print(props.calculator.parameters) # return a Table of the calc parameters
print(props.calculator.version) # return the calc version
print(props.results) # return a Table with all calculated properties
print(props.output_structure) # return the output Structure shich should contain only one geometry
print(props.output_structure[0:1]) # return only the first geometry (slice) of a Structure parameter containing several geometries
print(props.energy) # return energy as Series for all output structures
print(props.energy[0:1]) # return a slice (Series) with the energy of the first output structure
print(props.energy[0]) # return energy (Float) of the first output structure
print(props.forces) # return forces as series for all output structures
print(props.forces[0]) # return an Array of forces for the first output structure

The Property parameter is evaluated in the following way. The input Structure and Calculator parameters are subscriptable and contain Series of structure geometries and calculator parameters, respectively. The cartesian product of these two Series is taken to find all combinations and for each combination a calculation is performed. Every calculation is captured as a tuple (a row) in props.results Table. The props.results Table has as columns the names of all requested properties, as well as the corresponding input geometry, calculator parameters and final (output) geometry.

For example, if two geometries of the same molecule have to be processed by the same calculator with three different parameter sets, then the results Table will contain six tuples. The computed constraints and the properties are the same for all structure-calculator-algorithm combinations. The results can be accessed via subscripting the Property parameter, as it is shown in the examples above.