Engines

The engines are the core of the Amsterdam Modeling Suite: While the AMS driver steers the calculation over the potential energy surface in e.g. a geometry optimization or molecular dynamics calculation, the engines calculate energies and gradients and in this way define the PES on which the driver works.

The engine used for an AMS calculation is selected and configured with the special Engine block in the AMS input:

Engine DFTB
   ... input for the DFTB engine ...
EndEngine

Here the type of engine, e.g. DFTB as in the example above, is specified on the line that opens the block. Note that the Engine block ends with EndEngine, and is in this way different from all the other blocks in the AMS input, which close just with End. The content of the engine block is what we call the “engine input”. Generally the engine input consists of a series of blocks and keywords, and looks just like the AMS driver input. However, many engines have a lot of options and keywords, which are documented in a separate engine manual. In other words: This AMS driver manual documents all the keywords outside of the Engine block, while the individual engine manuals document the contents of the engine block.

Available engines

The following engines are available in the 2019 release of the Amsterdam Modeling Suite:

  • BAND
    An atomic-orbital based DFT engine aimed at periodic systems (crystals, slabs, chains) but supporting also molecular systems.
  • DFTB
    An engine implementing Density Functional based Tight-Binding, a fast approximation to DFT.
  • ReaxFF
    An engine for modeling chemical reactions with atomistic potentials based on the reactive force field approach.
  • UFF
    An implementation of the Universal Force Field, a simple non-reactive force field covering the entire periodic table.
  • MOPAC
    An engine wrapping the MOPAC code, a general-purpose semiempirical molecular orbital package for the study of solid state and molecular structures and reactions.
  • ADF
    A wrapper around the standalone ADF program, allowing it to be used as an engine from within the AMS driver.
  • External
    A flexible scripting interface that allows advanced users to use external atomistic modeling programs as engines in AMS.
  • LennardJones
    A simple toy engine implementing a Lennard-Jones potential.

External programs as engines

The AMS driver allows running external programs as an engine. In this way users can combine the functionality in the AMS driver (tasks and PES point properties) with the energies and gradients of any molecular modeling program they have access to. Furthermore the graphical interface of the Amsterdam Modeling Suite can be used to analyze the results of these calculations. The interfacing between the AMS driver and the external program has to be done by the user in form of a small script, which allows users to hook up any external program without access to the source code of AMS.

The Engine block for the external engine has just one important keyword, which is the command that is run to execute the external program:

Engine External
    Execute /path/to/my_interface_script.sh
EndEngine

The command can in principle be anything, as it will just be executed as is by the system shell. However, it should not use relative paths (e.g. to files in the directory where the input file is). We recommend writing the interfacing script in Python and using the Python interpreter that ships with AMS:

Engine External
    Execute $ADFBIN/startpython /path/to/my_python_interface_script.py
EndEngine

AMS then starts running and for every geometry prepares a folder in which the external engine is supposed to run. This is the folder in which the interface script specified with the Execute key is executed (so any relative paths are relative to that folder). AMS puts two files into this folder:

system.xyz
request.json

The system.xyz just contains the geometry AMS wants the external engine to calculate. It is an extended format XYZ file with the VEC1, VEC2, VEC3 extension at the end for periodic systems, e.g. diamond would look like this:

2

C       -0.51292147    -0.51292147    -0.51292147
C        0.51292147     0.51292147     0.51292147
VEC1     0.00000000     2.05168587     2.05168587
VEC2     2.05168587    -0.00000000     2.05168587
VEC3     2.05168587     2.05168587     0.00000000

The request.json file is just a small JSON file that specifies what exactly AMS wants the external engine to calculate:

{
   "title": "GOStep28",
   "quiet": false,
   "gradients": true,
   "stressTensor": false,
   "hessian": true,
   "dipoleMoment": false,
   "properties": true,
   "prevResults": "GOStep27"
}

The job of the interfacing script is now to read these files, run the external program and convert its output into a format understood by AMS. Generally these are simple text files with the name of the property and the extension .txt. The bare minimum the interfacing script needs to produce is the file energy.txt containing a single number, i.e. the total energy in atomic units (Hartree). Other properties are optional, and it is easiest to go through the request.json entries one by one to see what AMS might request and what the interfacing script could produce in response.

title
Just a title for this particular engine run. It can be passed on to the external program if desired, or can just be ignored.
quiet
Whether AMS wants the external engine to write to standard output. This can be ignored in principle, but that might lead to really incomprehensible text output files of AMS if the external engine has to be called many times, e.g. for numerical derivatives.
gradients
Whether or not to calculate nuclear gradients. The interface script should put the gradients in a file called gradients.txt with nAtoms lines of 3 real numbers each, in atomic units, i.e. Hartree/Bohr. Note that AMS wants the gradients, not forces (beware the - sign!).
stressTensor
Whether to calculate the stressTensor for periodic systems. Should be written to stresstensor.txt in atomic units.
hessian
Whether to calculate the Hessian, that is just the second derivative of the energy with respect to the nuclear coordinates, without applying any mass weighing to it. If the Hessian has been calculated, it should be put in hessian.txt as a 3 nAtoms x 3 nAtoms matrix in atomic units.
dipoleMoment
If true, calculate the dipole moment and put it in dipolemoment.txt in atomic units, in one line with three numbers.
properties
This is set to true if AMS considers this “geometry” important and wants the engine to calculate further properties that the user might be interested in. In practice this is set to “true” for e.g. the final converged step in a geometry optimization, so that the user can then let the engine calculate e.g. the band structure, which one would not want to do at all the steps during the optimization. AMS can’t do anything with the properties that the engine might calculate, but the files will remain on disk for people to inspect them.
prevResults
This is the title of a previous similar calculation that the engine has already performed. These results can be accessed in ../$prevResults/, so for the example above GOStep28 can access the results from the previous step in the geometry optimization in ../GOStep27/. This is just the directory in which the interfacing script was run when the title field was set to GOStep27, so files that were written back then are still accessible. They can in principle be used to restart for example the SCF of the engine from step to step. Of course all of that has to be done by the interfacing script. The AMS driver does not know anything about how to restart the external program and can only point the interfacing script to the right location.

That is really all there is to the external engine: AMS prepares a folder with system.xyz and request.json and runs the user’s interfacing script in there, which has to take care of preparing the input for the external engine, running it, and putting the results in the text files that AMS expects, e.g. gradients.txt.

Note for properties that are in one way or another derivatives of the energy, it is generally ok if the external engine does not calculate what was requested by the AMS driver in request.json. If AMS requests, for example, the gradients from the external engine, but then does not find the gradients.txt in the directory after the interfacing script has run, it will just assume that the engine was not capable of calculating the gradient analytically. AMS will then just do the gradient numerically by rerunning the external engine for displaced geometries, reading only the energy from energy.txt. In this sense it is only absolutely required for the external engine to produce the energy, the rest can be done numerically by AMS if required. It is of course best to let the engine do as much as possible, especially if it implements analytical derivatives. Note that currently AMS can not calculate the Hessian numerically for engines that do not provide gradients. This is just a technical limitation, as it is of course possible to do a second derivative numerically, but it is just not implemented in AMS yet. (And it would also be a very slow way to calculate a Hessian.)

In addition to the Execute keyword that specifies the interfacing script, the Engine External block also needs to contain some information about the capabilities of the external engines:

Engine External
   Execute {...}
   Supports
      DipoleMoment     {true|false}
      PeriodicityNone  {true|false}
      PeriodicityChain {true|false}
      PeriodicitySlab  {true|false}
      PeriodicityBulk  {true|false}
   End
EndEngine

The normal engines that come with AMS (e.g. DFTB and BAND) produce the engine output files with extension .rkf in the results directory, see here. These files are also produced when an external engine is used and the information on them (anything related to the shape of the PES at that point, e.g. normal modes, phonons, ...) can be visualized normally with the graphical interface. In addition to each engine output .rkf file, external engines will also produce a correspondingly named folder per engine file, which is just the working directory of the interfacing script for that particular invocation of the external program. These folders just contain the full output of the external program and anything that the interfacing script might have produced. In this way users still have access to all results from the external program, even if these results were not communicated back to the AMS driver.

This last point is probably best illustrated with a simple example. Consider the following job that uses an external engine to do a linear transit calculation of ethane, going from the staggered to the eclipsed configuration, calculating normal modes at all converged points along the path:

AMS_JOBNAME=ethane_torsion $ADFBIN/ams << EOF

Task PESScan

System
   Atoms
      C       0.00000000       0.00000000       0.76576000
      C       0.00000000       0.00000000      -0.76576000
      H      -0.88668938       0.51193036       1.16677000
      H       0.88668938       0.51193036       1.16677000
      H       0.00000000      -1.02386071       1.16677000
      H       0.00000000       1.02386071      -1.16677000
      H      -0.88668938      -0.51193036      -1.16677000
      H       0.88668938      -0.51193036      -1.16677000
   End
End

PESScan
   CalcPropertiesAtPESPoints True
   ScanCoordinate
      nPoints 5
      Dihedral  3 1 2 6   60.0  0.0
   End
End

Properties
   NormalModes True
End

Engine External
   ...
EndEngine

EOF

If we run this job and look into the results folder, we will find the standard ams.log and ams.rkf as well as the usual engine result files PESPoint(1).rkf to PESPoint(5).rkf. Just as if we had used one of the native AMS engines, like DFTB. Each of these files can be opened in ADFSpectra to visualize the normal modes for this particular point. For an external engine we additionally have one folder per engine file, so for this example we would have PESPoint(1)/ to PESPoint(5)/. These are the folders in which the interfacing script ran for these particular points, so they contain all the native output files of the external program.

Toy engines

The AMS driver comes with a simple built-in toy engine that implements a Lennard-Jones potential. This can sometimes be useful for testing, as many properties of the Lennard-Jones gas/liquid/solid can be calculated analytically and compared to the results from AMS. Note that the potential is exactly the same for all elements, i.e. the N-N bond has exactly the same strength as the He-He bond.

The Lennard-Jones engine only has three keywords, which define the shape of the potential:

Engine LennardJones
   RMin   float
   Eps    float
   Cutoff float
EndEngine
Cutoff
Type:Float
Default value:15.0
Unit:Angstrom
Description:The distance at which the interaction is truncated.
Eps
Type:Float
Default value:1.0
Unit:Hartree
Description:The depth of the potential well.
RMin
Type:Float
Default value:1.0
Unit:Angstrom
Description:The distance of the potential minimum.