• Introduction to ASE - what is it? • Download and installation instructions • Tutorials • Documentation for modules in ASE • Frequently Asked Questions • Mailing Lists • Glossary • License • ASE development • Bugs! • Porting old ASE-2 code to version 3 The complete table of contents:
CONTENTS
1
ASE Manual, Release 3.9.0.3484
2
CONTENTS
CHAPTER
ONE
ATOMIC SIMULATION ENVIRONMENT The Atomic Simulation Environment (ASE) is the common part of the simulation tools developed at CAMd. ASE provides Python modules for manipulating atoms, analyzing simulations, visualization etc. Note:
The old ASE-2 webpage has moved to http://wiki.fysik.dtu.dk/ase2.
Supported calculators:
Gaussian
3
ASE Manual, Release 3.9.0.3484
Mopac
1.1 News • ASE version 3.8.0 released (22 October 2013). • ASE version 3.7.0 released (13 May 2013). • ASE version 3.6.0 released (24 February 2012). • Bugfix release: ASE version 3.5.1 (24 May 2011). • ASE version 3.5.0 released (13 April 2011). • ASE version 3.4.1 released (11 August 2010). • ASE version 3.4 released (23 April 2010). • ASE version 3.3 released (11 January 2010). • ASE version 3.2 released (4 September 2009). • ASE has reached revision 1000 (16 July 2009). • ASE version 3.1.0 released (27 March 2009). • Improved vibrations module: More accurate and possibility to calculate infrared intensities (13 March 2009). • ASE version 3.0.0 released (13 November 2008). 4
Chapter 1. Atomic Simulation Environment
ASE Manual, Release 3.9.0.3484
• Asap version 3.0.2 released (15 October 2008). • An experimental abinit interface released (9 June 2008). • Thursday April 24 will be ASE documentation-day. Ten people from CAMd/Cinf will do a “doc-sprint” from 9 to 16. (17 Apr 2008) • The new ASE-3.0 Sphinx page is now up and running! (2 Apr 2008) • A beta version of the new ASE-3.0 will be used for the electronic structure course at CAMd. (10 Jan 2008)
1.1. News
5
ASE Manual, Release 3.9.0.3484
6
Chapter 1. Atomic Simulation Environment
CHAPTER
TWO
OVERVIEW ASE is an Atomistic Simulation Environment written in the Python programming language with the aim of setting up, steering, and analyzing atomistic simulations. The ASE has been constructed with a number of “design goals” that make it: • Easy to use: Setting up an atomistic total energy calculation or molecular dynamics simulation with ASE is simple and straightforward. ASE can be used via a graphical user interface , a Command line tool and the Python language. Python scripts are easy to follow (see What is Python? for a short introduction). It is simple for new users to get access to all of the functionality of ASE. • Flexible: Since ASE is based on the Python scripting language it is possible to perform very complicated simulation tasks without any code modifications. For example, a sequence of calculations may be performed with the use of simple “for-loop” constructions. There exist ASE modules for performing many standard simulation tasks. • Customizable: The Python code in ASE is structured in modules intended for different purposes. There are calculators for calculating energies, forces and stresses, md and optimize modules for controlling the motion of atoms, constraint objects and filters for performing nudged-elastic-band calculations etc. The modularity of the object-oriented code make it simple to contribute new functionality to ASE. • Pythonic: It fits nicely into the rest of the Python world with use of the popular NumPy package for numerical work (see Numeric arrays in Python for a short introduction). The use of the Python language allows ASE to be used both interactively as well as in scripts. • Open to participation: The CAMPOS Atomic Simulation Environment is released under the GNU Lesser General Public License version 2.1 or any later version. See the files COPYING and COPYING.LESSER which accompany the downloaded files, or see the license at GNU’s web server at http://www.gnu.org/licenses/ . Everybody is invited to participate in using and developing the code .
7
ASE Manual, Release 3.9.0.3484
8
Chapter 2. Overview
CHAPTER
THREE
INSTALLATION REQUIREMENTS The following packages are required for basic ASE functionality: 1. Python 2.6 - 2.7. 2. NumPy. It is highly recommended (but not required) to install also these: 3. matplotlib. 4. libpng. 5. pygtk. 6. SciPy. Matplotlib and libpng are needed for writing png files, and together with pygtk are needed for ASE’s simple GUI (called ase-gui, see gui). Some of these packages may already be installed on your system. Specific information for different operating systems is provided at Installation.
9
ASE Manual, Release 3.9.0.3484
10
Chapter 3. Installation requirements
CHAPTER
FOUR
DOWNLOAD 4.1 Latest stable release The latest stable release can be obtained from svn or as a tarball. The recommended installation path is $HOME.
Note:
When using svn please set the following variable: • bash: export ASE_TAGS=https://svn.fysik.dtu.dk/projects/ase/tags/
4.2 Latest development release The latest revision can be obtained like this: $ svn checkout https://svn.fysik.dtu.dk/projects/ase/trunk ase
or from the daily snapshot: python-ase-snapshot.tar.gz. Note:
The recommended checkout path is $HOME.
11
ASE Manual, Release 3.9.0.3484
12
Chapter 4. Download
CHAPTER
FIVE
INSTALLATION After performing the installation do not forget to Run the tests !
5.1 Installation on OS X For installation with http://mxcl.github.com/homebrew/ please follow instructions at Homebrew.
5.2 Installation with package manager on Linux Install the binaries with the software package manager of your Linux distribution. This is the preferred way to install on a Linux system. If you prefer to install from sources follow Manual installation . The currently supported systems include (issue the commands below as root): • RHEL/CentOS 6: yum install wget cd /etc/yum.repos.d/ wget http://download.opensuse.org/repositories/home:/dtufys/CentOS_CentOS-6/home:dtufys.repo yum install python-ase yum install python-matplotlib # optionally
$ find . -name "*.*sh" | xargs -t -I file sh -c "chmod u+x file" # source the scripts (example for bash)
$ for f in ‘find . -name "*.sh"‘; do source $f; done # verify the desired installation location is used
$ python -c "import ase; print ase.__file__"
This method works for all the RPM packages from the repository (like gpaw), however not for the external, distribution provided packages, which may require manually creating the environment scripts.
5.3 Windows Note:
ASE is not yet fully functional on Windows! https://trac.fysik.dtu.dk/projects/ase/ticket/62
On Windows the following packages need to installed. On the command prompt: installation assumes the python TARGETDIR C:\Python27, leave also the default C:\Program Files\pythonxy. Note:
• pythonxy. Download the exe installer and install with: Python(x,y)-2.7.2.2.exe /Log="%TMP%\pythonxy_install.log" /S
Note:
Open Task Manager and control when the process in finished.
• pygtk_win32. Download the msi pygtk-all-in-one installer. Specify the correct TARGETDIR and install:
If performing clicking-installation make sure that the default python Windows TARGETDIR is selected.
• Download the python-ase-win32.msi installer and install with: python-ase-X.X.X.win32.msi /l *vx "%TMP%\python-ase_install.log" /passive
Note:
You can build the msi ASE package on Windows with:
python setup.py bdist_msi
The msi package will be created under the dist directory.
5.4 Manual installation After the Download of ASE source create the link to the requested version, e.g.: • if retrieved from svn: $ cd $HOME $ ln -s ase-3.8.0 ase
• if retrieved as tarball: $ cd $HOME $ tar zxf python-ase-3.8.0.3420.tar.gz $ ln -s python-ase-3.8.0.3420 ase
It is sufficient to put the directory $HOME/ase in your PYTHONPATH environment variable, and the directory $HOME/ase/tools in your PATH environment variable. Do this permanently in your ~/.bashrc file: export PYTHONPATH=$HOME/ase:$PYTHONPATH export PATH=$HOME/ase/tools:$PATH
or your ~/.cshrc file: setenv PYTHONPATH ${HOME}/ase:${PYTHONPATH} setenv PATH ${HOME}/ase/tools:${PATH}
Instead of HOME, you may use any other directory. Alternatively, you can install ASE to the user-specific site-packages directory with: $ cd ase $ python setup.py install --user
This way, the ASE modules are found on the python path without any explicit configuration, though you still need to ensure that $HOME/.local/bin (or on Windows, %APPDATA%/Python/Scripts ) is on your PATH. Optional, NOT recommended way of installing ASE system-wide is: $ cd ase $ sudo python setup.py install
This is one of the best ways to ruin a Linux system.
5.4. Manual installation
15
ASE Manual, Release 3.9.0.3484
5.5 Run the tests Make sure that everything works by running the test suite. This will create many files, so run the tests in a new directory (preferably using bash): $ bash $ mkdir /tmp/testase.$$; cd /tmp/testase.* $ python -c "from ase.test import test; test(verbosity=2, display=True)" 2>&1 | tee testase.log
Note: The
Note:
last test ase/test/COCu111.py requires closing the graphics windows to terminate the whole test-suite.
If matplotlib or pygtk is not installed, this test will fail - avoid this with display=False .
If any of the tests fail, then please send us testase.log (see Bugs!).
5.6 Video tutorial In the video: Overview of the features of ASE, followed by a Manual installation of ASE on a Linux system. Note:
16
Use “Right Click -> Play” to play.
Chapter 5. Installation
CHAPTER
SIX
TUTORIALS 6.1 Python If you are not familiar with Python please read What is Python? .
6.1.1 What is Python? This section will give a very brief introduction to the Python language. See Also:
• The Python home page. • Python Recipes. • Try a Python quick reference card or a different reference card. Executing Python code
You can execute Python code interactively by starting the interpreter like this: $ python Python 2.5.1 (r251:54863, Mar 7 2008, 04:10:12) [GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> print ’hello’ hello
You can also put the print ’hello’ line in a file (hello.py ) and execute it as a Python script: $ python hello.py hello
Or like this: $ python -i hello.py hello >>> print ’hi!’ hi!
Finally, you can put #!/usr/bin/env python in the first line of the hello.py file, make it executable (chmod +x hello.py) and execute it like any other executable. Tip:
For interactive Python sessions, it is very convenient to have a personal .pythonrc file:
17
ASE Manual, Release 3.9.0.3484
import rlcompleter import readline
readline.parse_and_bind("tab: complete") from ase import *
and point the PYTHONSTARTUP environment variable at it (see here for details). Tip:
For an even better interactive experience, use ipython.
Types
Python has the following predefined types: type
description
bool int float complex str tuple list dict file
example
boolean False integer 117 floating point number 1.78 0.5 + 2.0j complex number string ’abc’ tuple (1, ’hmm’, 2.0) list [1, ’hmm’, 2.0] dictionary {’a’: 7.0, 23: True} open(’stuff.dat’, ’w’) file
A dict object is mapping from keys to values: >>> d = {’s’: 0, ’p’: 1} >>> d[’d’] = 2 >>> d
{’p’: 1, ’s’: 0, ’d’: 2} >>> d[’p’] 1
A list object is an ordered collection of arbitrary objects: >>> l = [1, (’gg’, 7), ’hmm’] >>> l[1]
(’gg’, 7) >>> l.append(1.2) >>> l[-2] ’hmm’
A tuple behaves like a list - except that it can’t be modified in place. Objects of types list and dict are mutable - all the other types listed in the table are immutable, which means that once an object has been created, it can not change. Note:
List and dictionary objects can change. Variables in Python are references to objects. This is demonstrated
here: a = [’q’, ’w’] b = a a.append(’e’) a [’q’, ’w’, ’e’] >>> b [’q’, ’w’, ’e’] >>> >>> >>> >>>
Note:
18
Another very important type is the ndarray type described here: Numeric arrays in Python . Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
Loops
A loop in Python can be done like this: >>> things = [’a’, 7] >>> for x in things: ... print x ...
a 7
The things object could be any sequence. Strings, tuples, lists, dictionaries, ndarrays and files are sequences. Functions and classes
A function is defined like this: >>> def f(x, m=2, n=1): ... y = x + n ... return y**m
Here f is a function, x is an argument, m and n are keywords with default values 2 and 1 and y is a variable. A class is defined like this: >>> class A : ... def __init__ (self, b): ... self.c = b ... def m(self): ... return f(self.c, n=0)
The __init__() function is called a constructor . You can think of a class as a template for creating user defined objects. In the class A __init__ is a constructor, c is an attribute and m is a method. >>> a = A(7) >>> a.c
7 >>> a.m()
49 >>> g = a.m >>> g()
49
Here we make an instance / object a of type A and g is a method bound to a. Importing modules
If you put the definitions of the function f and the class C in a file stuff.py, then you can use that code from another piece of code: from stuff import f, C print f(1, 2) print C(1).m(2)
or: import stuff as st print st.f(1, 2) print st.C(1).m(2)
Python will look for stuff.py in these directories: 1. current working directory 2. directories listed in your PYTHONPATH 3. Python’s own system directory (typically /usr/lib/python2.5 ) and import the first one found.
6.2 ASE Most of the tutorials will use the EMT potential, but any other Calculator could be plugged in instead.
6.2.1 Introduction: Nitrogen on copper This section gives a quick (and incomplete) overview of what ASE can do. We will calculate the adsorption energy of a nitrogen molecule on a copper surface. This is done by calculating the total energy for the isolated slab and for the isolated molecule. The adsorbate is then added to the slab and relaxed, and the total energy for this composite system is calculated. The adsorption energy is obtained as the sum of the isolated energies minus the energy of the composite system. Here is a picture of the system after the relaxation:
Please have a look at the following script doc/tutorials/N2Cu.py: from ase import Atoms from ase.visualize import view from ase.calculators.emt import EMT from ase.constraints import FixAtoms from ase.optimize import QuasiNewton from ase.lattice.surface import fcc111,add_adsorbate
h = 1.85 d = 1.10 slab = fcc111(’Cu’, size=(4,4,2), vacuum=10.0) slab.set_calculator(EMT())
Assuming you have ASE setup correctly ( Installation requirements) run the script: python N2Cu.py
Please read below what the script does. Atoms
The Atoms object is a collection of atoms. Here is how to define a N2 molecule by directly specifying the position of two nitrogen atoms: from ase import Atoms
You can also build crystals using, for example, the lattice module which returns Atoms objects corresponding to common crystal structures. Let us make a Cu (111) surface: from ase.lattice.surface import fcc111
slab = fcc111(’Cu’, size=(4,4,2), vacuum=10.0)
Calculators
Many calculators can be used with ASE, including emt, Asap, Dacapo, GPAW, Abinit, Vasp. See the ASE home page for the full list. In this overview we use the effective medium theory (EMT) calculator, as it is very fast and hence useful for getting started. We can attach a calculator to the previously created Atoms objects: from ase.calculators.emt import EMT
and use it to calculate the total energies for the systems by using the get_potential_energy() method from the Atoms class: e_slab = slab.get_potential_energy() e_N2 = molecule.get_potential_energy()
Structure relaxation
Let’s use the QuasiNewton minimizer to optimize the structure of the N2 molecule adsorbed on the Cu surface. First add the adsorbate to the Cu slab, for example in the on-top position: 6.2. ASE
21
ASE Manual, Release 3.9.0.3484
h = 1.85 add_adsorbate(slab, molecule, h, ’ontop’)
In order to speed up the relaxation, let us keep the Cu atoms fixed in the slab by using FixAtoms from the constraints module. Only the N2 molecule is then allowed to relax to the equilibrium structure: from ase.constraints import FixAtoms
constraint = FixAtoms(mask=[a.symbol != ’N’ for a in slab]) slab.set_constraint(constraint)
Now attach the QuasiNewton minimizer to the system and save the trajectory file. Run the minimizer with the convergence criteria that the force on all atoms should be less than some fmax: from ase.optimize import QuasiNewton
The general documentation on structure optimizations contains information about different algorithms, saving the state of an optimizer and other functionality which should be considered when performing expensive relaxations. Note:
Input-output
Writing the atomic positions to a file is done with the write() function: from ase.io import write
write(’slab.xyz’, slab)
This will write a file in the xyz-format. Possible formats are: format
description
xyz cube pdb traj py
Simple xyz-format Gaussian cube file Protein data bank file ASE’s own trajectory format Python script
Reading from a file is done like this: from ase.io import read
slab_from_file = read(’slab.xyz’)
If the file contains several configurations, the default behavior of the write() function is to return the last configuration. However, we can load a specific configuration by doing: read(’slab.traj’) read(’slab.traj’, -1) read(’slab.traj’, 0)
# last configuration # same as above # first configuration
Visualization
The simplest way to visualize the atoms is the view() function: from ase.visualize import view
view(slab)
This will pop up a gui window. Alternative viewers can be used by specifying the optional keyword viewer=... - use one of ‘ase.gui’, ‘gopenmol’, ‘vmd’, or ‘rasmol’. (Note that these alternative viewers are not a part of ASE and will need to be installed by the user separately.) The VMD viewer can take an optional data argument to show 3D data: 22
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
view(slab, viewer=’VMD’, data=array)
Molecular dynamics
Let us look at the nitrogen molecule as an example of molecular dynamics with the VelocityVerlet algorithm. We first create the VelocityVerlet object giving it the molecule and the time step for the integration of Newton’s law. We then perform the dynamics by calling its run() method and giving it the number of steps to take: from ase.md.verlet import VelocityVerlet from ase import units
dyn = VelocityVerlet(molecule, dt=1.0 * units.fs) for i in range(10): pot = molecule.get_potential_energy() kin = molecule.get_kinetic_energy() print ’%2d : %.5f eV, %.5f eV, %.5f eV’ % (i, pot + kin, pot, kin) dyn.run(steps=20)
6.2.2 Manipulating atoms XXX rewrite this: use fcc111() function and do some relaxation ...
We will set up a one layer slab of Ni atoms with one Ag adatom. Define the slab atoms: >>> from ase import Atoms >>> atoms = Atoms(’Ni4’, [(0, 0, 0), (0.45, 0, 0), ... (0, 0.5, 0), ... (0.5, 0.5, 0)]) ...
Let us assume we forgot how many atoms we set up: >>> atoms[4] Traceback (most recent call last): File "", line 1, in ? IndexError: list index out of range
Wrong because we only have four atoms >>> len(atoms)
4
Change the position of the 2nd atom in the list >>> atoms[1].x = 0.5 >>> atoms.get_positions()
array([[ 0. , [ 0.5,
6.2. ASE
0. , 0. ,
0. ], 0. ],
23
ASE Manual, Release 3.9.0.3484
[ 0. , [ 0.5,
0.5, 0.5,
0. ], 0. ]])
What is the unit cell so far? >>> atoms.get_cell()
array([[ 1., [ 0., [ 0.,
0., 1., 0.,
0.], 0.], 1.]])
Now, setup a p(2x2) cell in a hexagonal surface. Here, a is the fcc lattice constant, the cell is 10 layers high: >>> from numpy import sqrt >>> a = 3.55 >>> cell = [(2/sqrt(2.)*a, 0, 0), (1/sqrt(2.)*a, sqrt(3./2.)*a, 0), ... (0, 0, 10*sqrt(3.)/3.*a)] ... >>> cell
The argument scale_atoms=True indicates that the atomic positions should be scaled with the unit cell. The default is scale_atoms=False indicating that the cartesian coordinates remain the same when the cell is changed. >>> atoms.get_positions()
array([[ [ [ [
0. , 2.51022907, 1.25511454, 3.76534361,
0. , 0. , 2.17392215, 2.17392215,
0. 0. 0. 0.
], ], ], ]])
Plot the whole system by bringing up the gui: >>> from ase.visualize import view >>> view(atoms)
Within the viewer (called ase-gui or ase.gui ) it is possible to repeat the unit cell in all three directions (using the Repeat → View window).
24
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
We now add an adatom. Since the supercell is now declared as the unit cell for our atoms we can either add the atom using its cartesian coordinates in Angstrom or rescale the unit cell and use scaled coordinates. We try the latter: >>> from numpy import identity >>> from ase import Atom >>> xyzcell = identity(3) # The 3x3 unit matrix >>> atoms.set_cell(xyzcell, scale_atoms=True) # Set the unit cell and rescale >>> atoms.append(Atom(’Ni’, (1/6., 1/6., .1))) >>> atoms.set_cell(cell, scale_atoms=True) # Set the unit cell and scale back
The structure now looks like this: >>> view(atoms)
6.2.3 Atomization energy The following script will calculate the atomization energy of a nitrogen molecule: from ase import Atoms from ase.calculators.emt import EMT
First, an Atoms object containing one nitrogen is created and a fast EMT calculator is attached to it simply as an argument. The total energy for the isolated atom is then calculated and stored in the e_atom variable. The molecule object is defined, holding the nitrogen molecule at the experimental bond length. The EMT calculator is then attached to the molecule and the total energy is extracted into the e_molecule variable. Running the script will produce the output: Nitrogen atom energy: 4.97 eV Nitrogen molecule energy: 0.04 eV Atomization energy: 9.90 eV
6.2.4 Finding lattice constants See Also: Equation of state .
HCP
Let’s try to find the a and c lattice constants for HCP nickel using the EMT potential. First, we make a good initial guess for a and c using the FCC nearest neighbor distance and the ideal c/a ratio: import numpy as np
a0 = 3.52 / np.sqrt(2) c0 = np.sqrt(8 / 3.0) * a0
and create a trajectory for the results: from ase.io import PickleTrajectory
traj = PickleTrajectory(’Ni.traj’, ’w’)
Finally, we do the 9 calculations (three values for a and three for c): from ase.lattice import bulk from ase.calculators.emt import EMT
eps = 0.01 for a in a0 * np.linspace(1 - eps, 1 + eps, 3): for c in c0 * np.linspace(1 - eps, 1 + eps, 3): ni = bulk(’Ni’, ’hcp’, a=a, c=c) ni.set_calculator(EMT()) ni.get_potential_energy() traj.write(ni)
Analysis
Now, we need to extract the data from the trajectory. Try this: >>> from ase.lattice import bulk >>> ni = bulk(’Ni’, ’hcp’, a=2.5, c=4.0) >>> ni.cell
array([[ 2.5 [-1.25 [ 0.
, , ,
0. , 2.16506351, 0. ,
0. 0. 4.
], ], ]])
So, we can get a and c from ni.cell[0, 0] and ni.cell[2, 2]: from ase.io import read
configs = read(’Ni.traj@:’) energies = [config.get_potential_energy() for config in configs]
26
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
a = np.array([config.cell[0, 0] for config in configs]) c = np.array([config.cell[2, 2] for config in configs])
We fit the energy to this expression: p0 + p1 a + p2 c + p3 a2 + p4 ac + p5 c2
The best fit is found like this: functions = np.array([a**0, a , c , a **2, a * c, c**2]) p = np.linalg.lstsq(functions.T, energies)[0]
and we can find the minimum like this: p0 = p[0] p1 = p[1:3] p2 = np.array([(2 * p[3], p[4]), (p[4], 2 * p[5])]) a0, c0 = np.linalg.solve(p2.T, -p1)
Results: a
c
2.466
4.023
Using the stress tensor
One can also use the stress tensor to optimize the unit cell: from ase.optimize import BFGS from ase.constraints import StrainFilter
sf = StrainFilter(ni) opt = BFGS(sf) opt.run(0.005)
If you want the optimization path in a trajectory, add these lines before calling the run() method: traj = PickleTrajectory(’path.traj’, ’w’, ni) opt.attach(traj)
6.2.5 Equation of state First, do a bulk calculation for different lattice constants: import numpy as np from ase import Atoms from ase.io.trajectory import PickleTrajectory from ase.calculators.emt import EMT
a = 4.0 # approximate lattice constant b = a / 2 ag = Atoms(’Ag’, cell=[(0,b,b), (b,0,b), (b,b,0)], pbc=1, calculator=EMT()) # use EMT potential cell = ag.get_cell() traj = PickleTrajectory(’Ag.traj’, ’w’) for x in np.linspace(0.95, 1.05, 5): ag.set_cell(cell * x, scale_atoms=True) traj.write(ag)
6.2. ASE
27
ASE Manual, Release 3.9.0.3484
This will write a trajectory file containing five configurations of FCC silver for five different lattice constans. Now, analyse the result with the EquationOfState class and this script: from ase.io import read from ase.units import kJ from ase.utils.eos import EquationOfState configs = read(’Ag.traj@0:5’) # read 5 configurations # Extract volumes and energies: volumes = [ag.get_volume() for ag in configs] energies = [ag.get_potential_energy() for ag in configs]
eos = EquationOfState(volumes, energies) v0, e0, B = eos.fit() print B / kJ * 1.0e24, ’GPa’ eos.plot(’Ag-eos.png’)
A quicker way to do this analysis, is to use the gui tool: $ ase-gui Ag.traj
And then choose Tools → Bulk modulus .
6.2.6 Using the spacegroup subpackage The most evident usage of the spacegroup subpackage is to set up an initial unit of a bulk structure. For this you only need to supply the unique atoms and their scaled positions, space group and lattice parameters. Examples of setting up bulk structures
We start by showing some examples of how to set up some common or interesting bulk structures using ase.lattice.spacegroup.crystal(). This function takes a lot of arguments, of which the most important are: symbols [string
| sequence of strings] Either a string formula or sequence of element symbols. E.g. ‘NaCl’ and (‘Na’, ‘Cl’) are equivalent.
basis
28
[list of scaled coordinates] Coordinates of the non-equivalent sites in units of the lattice vectors. Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
[int | string | Spacegroup instance] Space group given either as its number in International Tables or as its Hermann-Mauguin (or international) symbol.
spacegroup
setting [1 | 2] Space group setting.
[[a, b, c, alpha, beta, gamma]] Cell parameters with angles in degree. Is not used when cell is given.
cellpar
Aluminium (fcc)
from ase.lattice.spacegroup import crystal
a = 4.05 al = crystal(’Al’, [(0,0,0)], spacegroup=225, cellpar=[a, a, a, 90, 90, 90])
The spacegroup argument can also be entered with its Hermann-Mauguin symbol, e.g. spacegroup=225 is equivalent to spacegroup=’F m -3 m’ . Iron (bcc)
from ase.lattice.spacegroup import crystal
a = 2.87 fe = crystal(’Fe’, [(0,0,0)], spacegroup=229, cellpar=[a, a, a, 90, 90, 90])
Magnesium (hcp)
from ase.lattice.spacegroup import crystal
a = 3.21 c = 5.21 mg = crystal(’Mg’, [(1./3., 2./3., 3./4.)], spacegroup=194, cellpar=[a, a, c, 90, 90, 120])
6.2. ASE
29
ASE Manual, Release 3.9.0.3484
Diamond
from ase.lattice.spacegroup import crystal
a = 3.57 diamond = crystal(’C’, [(0,0,0)], spacegroup=227, cellpar=[a, a, a, 90, 90, 90])
Sodium chloride
from ase.lattice.spacegroup import crystal
a = 5.64 nacl = crystal([’Na’, ’Cl’], [(0, 0, 0), (0.5, 0.5, 0.5)], spacegroup=225, cellpar=[a, a, a, 90, 90, 90])
Rutile
from ase.lattice.spacegroup import crystal
a = 4.6 c = 2.95 rutile =crystal([’Ti’, ’O’], basis=[(0, 0, 0), (0.3, 0.3, 0.0)], spacegroup=136, cellpar=[a, a, c, 90, 90, 90])
30
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
CoSb3 skutterudite
Skutterudites are quite interesting structures with 32 atoms in the unit cell. from ase.lattice.spacegroup import crystal
a = 9.04 skutterudite = crystal((’Co’, ’Sb’), basis=[(0.25,0.25,0.25), (0.0, 0.335, 0.158)], spacegroup=204, cellpar=[a, a, a, 90, 90, 90]) #ase.view(skutterudite)
Often this structure is visualised with the Cobalt atoms on the corners. This can easily be accomplished with ASE using ase.utils.geomegry.cut(). Below is the origo argument used to put the Cobalt atom on the corners and extend to include all corner and edge atoms, even those belonging to neighbouring unit cells.
6.2. ASE
31
ASE Manual, Release 3.9.0.3484
import numpy as np import ase.utils.geometry as geometry import ase.io as io # Create a new atoms instance with Co at origo including all atoms on the # surface of the unit cell
cosb3 = geometry.cut(skutterudite, origo=(0.25, 0.25, 0.25), extend=1.01) # Define the atomic bonds to show
bondatoms = [] symbols = cosb3.get_chemical_symbols() for i in xrange(len(cosb3)): for j in xrange(i): if (symbols[i] == symbols[j] == ’Co’ and cosb3.get_distance(i, j) < 4.53): bondatoms.append((i, j)) elif (symbols[i] == symbols[j] == ’Sb’ and cosb3.get_distance(i, j) < 2.99): bondatoms.append((i, j)) # Create nice-looking image using povray
The Spacegroup class is used internally by the ase.lattice.spacegroup.crystal() function, but might sometimes also be useful if you want to know e.g. the symmetry operations of a given space group. Instances of the Spacegroup class are immutable objects holding space group information, such as symmetry operations. Let us e.g. consider the fcc structure. To print information about the space group, do from ase.lattice.spacegroup import Spacegroup
Or, if you want to figure out what sites in the unit cell are equivalent to (0, 0, 0.5), simply do sites,kinds = sg.equivalent_sites([(0, 0, 0.5)])
where sites will be an array containing the scaled positions of the four symmetry-equivalent sites.
6.2.7 Dissociation tutorial from ase import Atoms from ase.calculators.emt import EMT from ase.constraints import FixAtoms from ase.optimize import QuasiNewton from ase.io import write # Find the initial and final states for the reaction. # Set up a (3 x 3) two layer slab of Ru:
a = 2.70 c = 1.59 * a sqrt3 = 3. ** .5 bulk = Atoms(’2Cu’, [(0., 0., 0.), (1./3, 1./3, -0.5*c)], tags=(1, 1), pbc=(1, 1, 0)) bulk.set_cell([(a, 0, 0), (a / 2, sqrt3 * a / 2, 0), (0, 0, 1)]) slab = bulk.repeat((4, 4, 1)) # Initial state. # Add the molecule:
x y z d
= a / 2. = a * 3. ** .5 / 6. = 1.8 = 1.10 # N2 bond length
# Molecular state parallel to the surface:
slab += Atoms(’2N’, [(x, y, z), (x + sqrt3 * d / 2, y + d / 2, z)])
6.2. ASE
33
ASE Manual, Release 3.9.0.3484
# Use the EMT calculator for the forces and energies:
slab.set_calculator(EMT()) # We don’t want to worry about the Cu degrees of freedom:
mask = [atom.symbol == ’Cu’ for atom in slab] slab.set_constraint(FixAtoms(mask=mask)) relax = QuasiNewton(slab) relax.run(fmax=0.05) print ’initial state:’, slab.get_potential_energy() write(’N2.traj’, slab) # Now the final state. # Move the second N atom to a neighboring hollow site:
slab[-1].position = (x + a, y, z) relax.run() print ’final state: ’, slab.get_potential_energy() write(’2N.traj’, slab) import numpy as np from ase.io import read from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.neb import NEB from ase.optimize.fire import FIRE as QuasiNewton
initial = read(’N2.traj’) final = read(’2N.traj’) configs = [initial.copy() for i in range(8)] + [final] constraint = FixAtoms(mask=[atom.symbol != ’N’ for atom in initial]) for config in configs: config.set_calculator(EMT()) config.set_constraint(constraint) band = NEB(configs) band.interpolate() # Create a quickmin object:
relax = QuasiNewton(band) relax.run(steps=20) e0 = initial.get_potential_energy() for config in configs: d = config[-2].position - config[-1].position print np.linalg.norm(d), config.get_potential_energy() - e0
6.2.8 Diffusion of gold atom on Al(100) surface (NEB) First, set up the initial and final states:
34
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
from ase.lattice.surface import fcc100, add_adsorbate from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.optimize import QuasiNewton # 2x2-Al(001) surface with 3 layers and an # Au atom adsorbed in a hollow site:
slab = fcc100(’Al’, size=(2, 2, 3)) add_adsorbate(slab, ’Au’, 1.7, ’hollow’) slab.center(axis=2, vacuum=4.0) # Make sure the structure is correct: #view(slab) # Fix second and third layers:
mask = [atom.tag > 1 for atom in slab] #print mask
slab.set_constraint(FixAtoms(mask=mask)) # Use EMT potential:
slab.set_calculator(EMT()) # Initial state:
qn = QuasiNewton(slab, trajectory=’initial.traj’) qn.run(fmax=0.05) # Final state:
Notice how the tags are used to select the constrained atoms
Now, do the NEB calculation: from ase.io import read from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.neb import NEB from ase.optimize import BFGS
initial = read(’initial.traj’) final = read(’final.traj’)
6.2. ASE
35
ASE Manual, Release 3.9.0.3484
constraint = FixAtoms(mask=[atom.tag > 1 for atom in initial]) images = [initial] for i in range(3): image = initial.copy() image.set_calculator(EMT()) image.set_constraint(constraint) images.append(image) images.append(final) neb = NEB(images) neb.interpolate() qn = BFGS(neb, trajectory=’neb.traj’) qn.run(fmax=0.05)
For this reaction, the reaction coordinate is very simple: The x -coordinate of the Au atom. In such cases, the NEB method is overkill, and a simple constraint method should be used like in this tutorial: Diffusion of gold atom on Al(100) surface (constraint) . Note:
See Also:
• neb • constraints •
Diffusion of gold atom on Al(100) surface (constraint)
• fcc100() Parallelizing over images
Instead of having one process do the calculations for all three internal images in turn, it will be faster to have three processes do one image each. This can be done like this: from ase.io import read from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.neb import NEB from ase.optimize import BFGS from ase.io.trajectory import PickleTrajectory
36
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
from ase.parallel import rank, size
initial = read(’initial.traj’) final = read(’final.traj’) constraint = FixAtoms(mask=[atom.tag > 1 for atom in initial]) images = [initial] j = rank * 3 // size # my image number for i in range(3): image = initial.copy() if i == j: image.set_calculator(EMT()) image.set_constraint(constraint) images.append(image) images.append(final) neb = NEB(images, parallel=True) neb.interpolate() qn = BFGS(neb) if rank % (size // 3) == 0: traj = PickleTrajectory(’neb%d .traj’ % j, ’w’, images[1 + j], master=True) qn.attach(traj) qn.run(fmax=0.05)
6.2.9 Diffusion of gold atom on Al(100) surface (constraint) In this tutorial, we will calculate the energy barrier that was found using the NEB method in the Diffusion of gold atom on Al(100) surface (NEB) tutorial. Here, we use a siple FixedPlane constraint that forces the Au atom to relax in the yz-plane only: from ase.lattice.surface import fcc100, add_adsorbate from ase.constraints import FixAtoms, FixedPlane from ase.calculators.emt import EMT from ase.optimize import QuasiNewton # 2x2-Al(001) surface with 3 layers and an # Au atom adsorbed in a hollow site:
slab = fcc100(’Al’, size=(2, 2, 3)) add_adsorbate(slab, ’Au’, 1.7, ’hollow’) slab.center(axis=2, vacuum=4.0) # Make sure the structure is correct: #view(slab) # Fix second and third layers:
mask = [atom.tag > 1 for atom in slab] #print mask
fixlayers = FixAtoms(mask=mask) # Constrain the last atom (Au atom) to move only in the yz-plane:
The result can be analysed with the command ase-gui mep?.traj -n -1 (choose Tools → NEB). The barrier is found to be 0.35 eV - exactly as in the NEB tutorial. Here is a side-view of the path (unit cell repeated twice):
See Also:
• neb • constraints • Diffusion of gold atom on Al(100) surface (NEB) • fcc100()
6.2.10 Molecular dynamics Note: These
examples can be used without Asap installed, then the ase.EMT calculator (implemented in Python) is used, but nearly superhuman patience is required. Here we demonstrate now simple molecular dynamics is performed. A crystal is set up, the atoms are given momenta corresponding to a temperature of 300K, then Newtons second law is integrated numerically with a time step of 5 fs (a good choice for copper). "Demonstrates molecular dynamics with constant energy." from ase.calculators.emt import EMT from ase.lattice.cubic import FaceCenteredCubic from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase.md.verlet import VelocityVerlet from ase import units # Use Asap for a huge performance increase if it is installed
useAsap = False if useAsap: from asap3 import EMT
size = 10 else:
38
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
size = 3 # Set up a crystal
atoms = FaceCenteredCubic(directions=[[1,0,0],[0,1,0],[0,0,1]], symbol="Cu", size=(size,size,size), pbc=True) # Describe the interatomic interactions with the Effective Medium Theory
atoms.set_calculator(EMT()) # Set the momenta corresponding to T=300K
MaxwellBoltzmannDistribution(atoms, 300*units.kB) # We want to run MD with constant energy using the VelocityVerlet algorithm. dyn = VelocityVerlet(atoms, 5*units.fs) # 5 fs time step. #Function to print the potential, kinetic and total energy
def printenergy(a):
epot = a.get_potential_energy() / len(a) ekin = a.get_kinetic_energy() / len(a) print ("Energy per atom: Epot = %.3f eV Ekin = %.3f e V (T=%3.0f K) (epot, ekin, ekin/(1.5*units.kB), epot+ekin))
Etot = %.3f eV" %
# Now run the dynamics
printenergy(atoms) for i in range(20): dyn.run(10) printenergy(atoms)
Note how the total energy is conserved, but the kinetic energy quickly drops to half the expected value. Why? Instead of printing within a loop, it is possible to use an “observer” to observe the atoms and do the printing (or more sophisticated analysis). "Demonstrates molecular dynamics with constant energy." from ase.calculators.emt import EMT from ase.lattice.cubic import FaceCenteredCubic from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase.md.verlet import VelocityVerlet from ase import units # Use Asap for a huge performance increase if it is installed
useAsap = True if useAsap: from asap3 import EMT
size = 10 else:
size = 3 # Set up a crystal
atoms = FaceCenteredCubic(directions=[[1,0,0],[0,1,0],[0,0,1]], symbol="Cu", size=(size,size,size), pbc=True) # Describe the interatomic interactions with the Effective Medium Theory
atoms.set_calculator(EMT()) # Set the momenta corresponding to T=300K
MaxwellBoltzmannDistribution(atoms, 300*units.kB) # We want to run MD with constant energy using the VelocityVerlet algorithm. dyn = VelocityVerlet(atoms, 5*units.fs) # 5 fs time step.
6.2. ASE
39
ASE Manual, Release 3.9.0.3484
#Function to print the potential, kinetic and total energy. def printenergy(a=atoms): #store a reference to atoms in the definition.
epot = a.get_potential_energy() / len(a) ekin = a.get_kinetic_energy() / len(a) print ("Energy per atom: Epot = %.3f eV Ekin = %.3f e V (T=%3.0f K) (epot, ekin, ekin/(1.5*units.kB), epot+ekin))
Often, you want to control the temperature of an MD simulation. This can be done with the Langevin dynamics module. In the previous examples, replace the line dyn = VelocityVerlet(...) with: dyn = Langevin(atoms, 5*units.fs, T*units.kB, 0.002)
where T is the desired temperature in Kelvin. You also need to import Langevin, see the class below. The Langevin dynamics will then slowly adjust the total energy of the system so the temperature approaches the desired one. As a slightly less boring example, let us use this to melt a chunk of copper by starting the simulation without any momentum of the atoms (no kinetic energy), and with a desired temperature above the melting point. We will also save information about the atoms in a trajectory file called moldyn3.traj. "Demonstrates molecular dynamics with constant energy." from ase.calculators.emt import EMT from ase.lattice.cubic import FaceCenteredCubic from ase.md.langevin import Langevin from ase.io.trajectory import PickleTrajectory from ase import units from asap3 import EMT
# Way too slow with ase.EMT !
size = 10 T = 1500 # Kelvin # Set up a crystal
atoms = FaceCenteredCubic(directions=[[1,0,0],[0,1,0],[0,0,1]], symbol="Cu", size=(size,size,size), pbc=False) # Describe the interatomic interactions with the Effective Medium Theory
atoms.set_calculator(EMT()) # We want to run MD with constant energy using the Langevin algorithm # with a time step of 5 fs, the temperature T and the friction # coefficient to 0.02 atomic units.
dyn = Langevin(atoms, 5*units.fs, T*units.kB, 0.002) #Function to print the potential, kinetic and total energy. def printenergy(a=atoms): #store a reference to atoms in the definition.
epot = a.get_potential_energy() / len(a) ekin = a.get_kinetic_energy() / len(a) print ("Energy per atom: Epot = %.3f eV Ekin = %.3f e V (T=%3.0f K) (epot, ekin, ekin/(1.5*units.kB), epot+ekin)) dyn.attach(printenergy, interval=50)
Etot = %.3f eV" %
#We also want to save the positions of all atoms after every 100th time step.
40
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
traj = PickleTrajectory("moldyn3.traj", ’w’, atoms) dyn.attach(traj.write, interval=50) # Now run the dynamics
printenergy() dyn.run(5000)
After running the simulation, you can study the result with the command ase-gui moldyn3.traj
Try plotting the kinetic energy. You will not see a well-defined melting point due to finite size effects (including surface melting), but you will probably see an almost flat region where the inside of the system melts. The outermost layers melt at a lower temperature. The Langevin dynamics will by default keep the position and momentum of the center of mass unperturbed. This is another improvement over just setting momenta corresponding to a temperature, as we did before. Note:
Isolated particle MD
When simulating isolated particles with MD, it is sometimes preferable to set random momenta corresponding to a specific temperature and let the system evolve freely. With a relatively high temperature, the is however a risk that the collection of atoms will drift out of the simulation box because the randomized momenta gave the center of mass a small but non-zero velocity too. Let us see what happens when we propagate a nanoparticle for a long time: "Demonstrates molecular dynamics for isolated particles." from ase.calculators.emt import EMT from ase.cluster.cubic import FaceCenteredCubic from ase.optimize import QuasiNewton from ase.md.velocitydistribution import MaxwellBoltzmannDistribution, \
Stationary, ZeroRotation from ase.md.verlet import VelocityVerlet from ase import units # Use Asap for a huge performance increase if it is installed
useAsap = True if useAsap: from asap3 import EMT
size = 4 else:
size = 2 # Set up a nanoparticle
atoms = FaceCenteredCubic(’Cu’, surfaces=[[1,0,0],[1,1,0],[1,1,1]], layers=(size,size,size), vacuum=4) # Describe the interatomic interactions with the Effective Medium Theory
atoms.set_calculator(EMT()) # Do a quick relaxation of the cluster
qn = QuasiNewton(atoms) qn.run(0.001, 10) # Set the momenta corresponding to T=1200K
MaxwellBoltzmannDistribution(atoms, 1200*units.kB) Stationary(atoms) # zero linear momentum ZeroRotation(atoms) # zero angular momentum
6.2. ASE
41
ASE Manual, Release 3.9.0.3484
# We want to run MD using the VelocityVerlet algorithm.
dyn = VelocityVerlet(atoms, 5*units.fs, trajectory=’moldyn4.traj’) # save trajectory. #Function to print the potential, kinetic and total energy. def printenergy(a=atoms): #store a reference to atoms in the definition.
epot = a.get_potential_energy() / len(a) ekin = a.get_kinetic_energy() / len(a) print ("Energy per atom: Epot = %.3f eV Ekin = %.3f e V (T=%3.0f K) (epot, ekin, ekin/(1.5*units.kB), epot+ekin)) dyn.attach(printenergy, interval=10)
Etot = %.3f eV" %
# Now run the dynamics
printenergy() dyn.run(2000)
After running the simulation, use ase-gui to compare the results with how it looks if you comment out either the line that says Stationary (atoms), ZeroRotation (atoms) or both. ase-gui moldyn4.traj
Try playing the movie with a high frame rate and set frame skipping to a low number. Can you spot the subtle difference?
6.2.11 Partly occupied Wannier Functions from ase.data.molecules import molecule from gpaw import GPAW
atoms, calc = restart(’benzene.gpw’, txt=None) # Make wannier functions of occupied space only
wan = Wannier(nwannier=15, calc=calc) wan.localize() for i in range(wan.nwannier): wan.write_cube(i, ’benzene15_ %i.cube’ % i) # Make wannier functions using (three) extra degrees of freedom.
wan = Wannier(nwannier=18, calc=calc, fixedstates=15) wan.localize() wan.save(’wan18.pickle’) for i in range(wan.nwannier): wan.write_cube(i, ’benzene18_ %i.cube’ % i) from ase.dft import Wannier from gpaw import restart
42
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
atoms, calc = restart(’benzene.gpw’, txt=None) wan = Wannier(nwannier=18, calc=calc, fixedstates=15, file=’wan18.pickle’) import pylab as pl
weight_n = pl.sum(abs(wan.V_knw[0])**2, 1) N = len(weight_n) F = wan.fixedstates_k[0] pl.figure(1, figsize=(12, 4)) pl.bar(range(1, N+1), weight_n, width=0.65, bottom=0, color=’k’, edgecolor=’k’, linewidth=None, align=’center’, orientation=’vertical’) pl.plot([F+.5, F+.5], [0, 1], ’k--’) pl.axis(xmin=.32, xmax=N+1.33, ymin=0, ymax=1) pl.xlabel(’Eigenstate’) pl.ylabel(’Projection of wannier functions’) pl.savefig(’spectral_weight.png’) pl.show() import numpy as np from ase import Atoms from ase.dft.kpoints import monkhorst_pack from gpaw import GPAW
kpts = monkhorst_pack((13, 1, 1)) + [1e-5, 0, 0] calc = GPAW(h=.21, xc=’PBE’, kpts=kpts, nbands=12, txt=’poly.txt’, eigensolver=’cg’, convergence={’bands’: 9}) CC = 1.38 CH = 1.094 a = 2.45 x = a / 2. y = np.sqrt(CC**2 - x**2) atoms = Atoms(’C2H2’, pbc=(True, False, False), cell=(a, 8., 6.), calculator=calc, positions=[[0, 0, 0], [x, y, 0], [x, y+CH, 0], [0, -CH, 0]]) atoms.center() atoms.get_potential_energy() calc.write(’poly.gpw’, mode=’all’) import numpy as np from ase.dft import Wannier from gpaw import restart
atoms, calc = restart(’poly.gpw’, txt=None) # Make wannier functions using (one) extra degree of freedom
wan = Wannier(nwannier=6, calc=calc, fixedenergy=1.5) wan.localize() wan.save(’poly.pickle’) wan.translate_all_to_cell((2, 0, 0)) for i in range(wan.nwannier): wan.write_cube(i, ’polyacetylene_ %i.cube’ % i) # Print Kohn-Sham bandstructure
ef = calc.get_fermi_level() f = open(’KSbands.txt’, ’w’) for k, kpt_c in enumerate(calc.get_ibz_k_points()): for eps in calc.get_eigenvalues(kpt=k):
f = open(’WANbands.txt’, ’w’) for k in np.linspace(-.5, .5, 100): for eps in np.linalg.eigvalsh(wan.get_hamiltonian_kpoint([k, 0, 0])).real: print >> f, k, eps - ef import pylab as pl
6.2.12 Constrained minima hopping (global optimization) Here, we will show a examples of a search for a global optimum geometric configuration using the minima hopping algorithm, along with the Hookean class of constraints. As an example, this type of approach is useful in searching for the global optimum position of adsorbates on a surface while enforcing that the adsorbates’ identity is preserved. A quick example with EMT
The below example looks at finding the optimum configuration of a Cu 2 adsorbate on a fixed Pt (110) surface. Although this is not a physically relevant simulation – these elements (Cu, Pt) were chosen only because they work with the EMT calculator – one can imagine replacing the Cu 2 adsorbate with CO, for example, to find its optimum binding configuration under the constraint that the CO does not dissociate into separate C and O adsorbates. This also uses the Hookean constraint in two different ways. In the first, it constrains the Cu atoms to feel a restorative force if their interatomic distance exceeds 2.6 Angstroms; this preserves the dimer character of the Cu2 , and if they are near each other they feel no constraint. The second constrains one of the Cu atoms to feel a downward force if its position exceeds a z coordinate of 15 Angstroms. Since the Cu atoms are tied together, we don’t necessarily need to put such a force on both of the Cu atoms. This second constraint prevents the Cu 2 adsorbate from flying off the surface, which would lead to it exploring a lot of irrelevant configurational space, such as up in the vacuum or on the bottom of the next periodic slab. from ase import Atoms, Atom from ase.lattice.surface import fcc110 from ase.optimize.minimahopping import MinimaHopping from ase.calculators.emt import EMT from ase.constraints import FixAtoms, Hookean from ase.optimize import BFGS
adsorbate = Atoms([Atom(’Cu’, atoms[7].position + (0., 0., 2.5)), Atom(’Cu’, atoms[7].position + (0., 0., 5.0))]) atoms.extend(adsorbate) # Constrain the surface to be fixed and a Hookean constraint between # the adsorbate atoms.
constraints = [FixAtoms(indices=[atom.index for atom in atoms if atom.symbol==’Pt’]), Hookean(a1=8, a2=9, rt=2.6, k=15.), Hookean(a1=8, a2=(0., 0., 1., -15.), k=15.),] atoms.set_constraint(constraints) # Set the calculator.
calc = EMT() atoms.set_calculator(calc) # Instantiate and run the minima hopping algorithm.
hop = MinimaHopping(atoms, Ediff0=2.5, optimizer=BFGS, T0=4000.) hop(totalsteps=10)
This script will produce 20 molecular dynamics and 21 optimization files. It will also produce a file called ‘minima.traj’ which contains all of the accepted minima. You can look at the progress of the algorithm in the file hop.log in combination with the trajectory files. Alternatively, there is a utility to allow you to visualize the progress of the algorithm. You can use this as: >>> from ase.optimize.minimahopping import MHPlot >>> mhplot = MHPlot() >>> mhplot.save_figure(’summary.pdf’)
This will make a summary figure, which should look something like the one below. As the search is inherently random, yours will look different than this (and this will look different each time the documentation is rebuilt). In this figure, you will see on the E pot axes the energy levels of the conformers found. The flat bars represent the energy at the end of each local optimization step. The checkmark indicates the local minimum was accepted; red arrows indicate it was rejected for the three possible reasons. The black path between steps is the potential energy during the molecular dynamics (MD) portion of the step; the dashed line is the local optimization on termination of the MD step. Note the y axis is broken to allow different energy scales between the local minima and the space explored in the MD simulations.
6.2. ASE
45
ASE Manual, Release 3.9.0.3484
6.3 NumPy If your ASE scripts make extensive use of matrices you may want to familiarize yourself with Numeric arrays in Python.
46
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
6.3.1 Numeric arrays in Python Links to NumPy’s webpage: • Numpy and Scipy Documentation • Numpy guide book • Numpy example list • Numpy functions by category ASE makes heavy use of an extension to Python called NumPy. The NumPy module defines an ndarray type that can hold large arrays of uniform multidimensional numeric data. An array is similar to a list or a tuple, but it is a lot more powerful and efficient. XXX More examples from everyday ASE-life here ... >>> import numpy as np >>> a = np.zeros((3, 2)) >>> a[:, 1] = 1.0 >>> a[1] = 2.0 >>> a
>>> >>> # The eigenvectors of H are the *coloumns* of U: >>> np.allclose(np.dot(H, U[:, 3]), eps[3] * U[:, 3]) >>> np.allclose(np.dot(H, U), eps * U)
The rules for multiplying 1D arrays with 2D arrays: • 1D arrays and treated like shape (1, N) arrays (row vectors). • left and right multiplications are treated identically. • A length m row vector can be multiplied with an n × m matrix, producing the same result as if replaced by a matrix with n copies of the vector as rows.
6.3. NumPy
47
ASE Manual, Release 3.9.0.3484
• A length n column vector can be multiplied with an n × m matrix, producing the same result as if replaced by a matrix with m copies of the vector as columns. Thus, for the arrays below: >>> >>> >>> >>> >>>
M = np.arange(5 * 6).reshape(5, 6) # A matrix af shape (5, 6) # A vector of length 5 v5 = np.arange(5) + 10 # A length 5 column vector v51 = v5[:, None] # A vector of length 6 v6 = np.arange(6) - 12 # A length 6 row vector v16 = v6[None, :]
The following identities hold: v6 * M == v16 * M == M * v6 == M * v16 == M * v16.repeat(5, 0) v51 * M == M * v51 == M * v51.repeat(6, 1)
The exact same rules apply for adding and subtracting 1D arrays to / from 2D arrays.
6.4 Further reading For more details: • Look at the documentation for the individual modules. • See the automatically generated documentation Epydoc: ase. • Browse the source code online. • Have a look at siesta exercises:
6.4.1 Exercises Note:
CAMd summer school participants should read this page before doing the SIESTA exercises.
Exercise 2 contains a script which takes somewhat long time. For this reason you may want to submit the script to Niflheim in advance, before analyzing the results in Exercise 1. Siesta 1: Basis Sets
This exercise is intended to illustrate the definition of basis sets with different numbers of orbitals and localization radii in SIESTA. It is based on the H2 O molecule. You will first use standard basis sets generated by SIESTA, and then a basis set specifically optimized for the H 2 O molecule. The tips at the end of this page will help you in analyzing the results of the calculations. We are going to use the ASE interface to the siesta calculator, for the official SIESTA documentation see here. Part 1: Standard basis sets
In the following script you will relax the structure of the H2 O molecule to find its equilibrium structure. import time import numpy as np from ase import Atoms, units from ase.optimize import QuasiNewton from ase.calculators.siesta import Siesta # Set up a H2O molecule by specifying atomic positions
48
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
h2o = Atoms(symbols=’H2O’, positions=[( 0.776070, 0.590459, 0.00000), (-0.776070, 0.590459, 0.00000), (0.000000, -0.007702, -0.000001)], pbc=(1,1,1)) # Center the molecule in the cell with some vacuum around
h2o.center(vacuum=6.0) # Select some energy-shifts for the basis orbitals
e_shifts = [0.01,0.1,0.2,0.3,0.4,0.5] # Run the relaxation for each energy shift, and print out the # corresponding total energy, bond length and angle
for e_s in e_shifts:
starttime = time.time() calc = Siesta(’h2o’,meshcutoff=200.0 * units.Ry, mix=0.5, pulay=4) calc.set_fdf(’PAO.EnergyShift’, e_s * units.eV) calc.set_fdf(’PAO.SplitNorm’, 0.15) calc.set_fdf(’PAO.BasisSize’, ’SZ’) h2o.set_calculator(calc) # Make a -traj file named h2o_current_shift.traj: dyn = QuasiNewton(h2o, trajectory=’h2o_ %s.traj’ % e_s) # Perform the relaxation dyn.run(fmax=0.02)
E = h2o.get_potential_energy() print print "E_shift: %.2f " %e_s print "----------------" print "Total Energy: %.4f " % E
# Make the output more readable
# Print total energy
d = h2o.get_distance(0,2) print "Bond length: %.4f " % d
Run the script using three different basis sets: single-Z (SZ), double-Z (DZ) and double-Z plus polarization (DZP). Run it in different directories for each basis set, since the run will produce a large amount of output files. The bases are defined in the script through these three lines: calc.set_fdf(’PAO.BasisSize’,’SZ’) calc.set_fdf(’PAO.EnergyShift’,e_s * eV) calc.set_fdf(’PAO.SplitNorm’,0.15)
For each of the basis sets the script will run the relaxation for different EnergyShift parameters. Look at the results as a function of basis size and localization radius (or energy shift). In particular, you should look at: • Total energy • Bond lenghts at the relaxed structure • Bond angles at the relaxed structure • Execution time
6.4. Further reading
49
ASE Manual, Release 3.9.0.3484
• Radius of each of the orbitals • Shape of the orbitals The script will print bond lengths and angles, total energy plus the wall time for each energy shift. The radii of the orbitals from the last run can be found in the file h2o.txt along with miscellaneous other informations. Orbital shapes from the last run are stored in the ORB.* files, which contain the value of the orbitals versus radius. (Note that the standard way to plot the orbitals is to multiply the orbital by r l ). You can visualize both the static atoms and the relaxation trajectory using the the ASE gui. For example you can visualize the relaxation trajectory from the command line by doing: $ ase-gui h2o_0.1.traj
Note that you will get a trajectory file .traj for each energy shift in the loop. Try to get plots like the following, obtained for a SZ basis:
Try to answer these questions: 1. What is the best basis set that you have found? Why? 2. How do the results compare with experiment? 3. What do you consider a reasonable basis for the molecule, if you need an accuracy in the geometry of about 1%? 4. In order to assess convergence with respect to basis set size, should you compare the results with the experimental ones, or with those of a converged basis set calculation?
50
Chapter 6. Tutorials
ASE Manual, Release 3.9.0.3484
Part 2: Optimized basis sets
You will now do the same calculations as in Part 1, but now using a basis set specifically optimized for the H 2 O molecule. Use the following optimized block instead of the basis-definition lines in Part1: calc.set_fdf(’PAO.Basis’, ["""H 2 0.22 n=1 0 2 E 2.07 4.971 1.771 1.000 1.000 n=2 1 1 E 0.89 4.988 1.000 O 3 -0.20 n=2 0 2 E 0.00 5.000 2.581 1.000 1.000 n=2 1 2 E 0.00 6.500 2.487 1.000 1.000 n=3 2 1 E 104.31 3.923 1.000"""])
0.00
0.01
1.31
5.28
0.00
Compare the parameters with those of the calculations in Part 1. Do the runs with this basis set, and compare the results with the previous ones. Tips
Tip 1: You can see the radii of the orbitals in the output file, just after the line reading: printput: Basis input ----------------------------------------------
Tip 2: You can look at the shape of the orbitals by plotting the contents of the ORB* files generated by SIESTA. Tip 3: You will find a lot of information on the run in the .txt output file Tip 4: In ag you can select View → VMD to start the VMD viewer. There you can change the atom representation to what you feel is more convenient. Do that by selecting Graphics → Representations in the top bar. Tip 5: SIESTA will store basis functions in ORB.* files. These files can be plotted using the xmgrace command on the GBAR like this: $ xmgrace ORB.S1.1.O ORB.S2.1.O
Siesta 2: Molecular Dynamics
This exercise is intended to illustrate a Molecular Dynamics run with the SIESTA calculator. The system is a Si(001) surface, in the 2x1 reconstruction with asymmetric dimers. The simulation cell contains two dimers. An H2 molecule approaches the surface, above one of the dimers, and dissociates, ending up with a H atom bonded to each of the Si atoms in the dimer (and thus leading to a symmetric dimer). You can get the xyz file with the initial geometry doc/exercises/siesta2/geom.xyz. from ase.io import read from ase.constraints import FixAtoms from ase.calculators.siesta import Siesta from ase.md import VelocityVerlet from ase import units # Read in the geometry from a xyz file, set the cell, boundary conditions and center
atoms = read(’geom.xyz’)
6.4. Further reading
51
ASE Manual, Release 3.9.0.3484
atoms.set_cell([7.66348,7.66348,7.66348*2]) atoms.set_pbc((1,1,1)) atoms.center() # Set initial velocities for hydrogen atoms along the z-direction
p = atoms.get_momenta() p[0,2]= -1.5 p[1,2]= -1.5 atoms.set_momenta(p) # Keep some atoms fixed during the simulation
atoms.set_constraint(FixAtoms(indices=range(18,38))) # Set the calculator and attach it to the system
calc = Siesta(’si001+h2’,basis=’SZ’,xc=’PBE’,meshcutoff=50*units.Ry) calc.set_fdf(’PAO.EnergyShift’, 0.25 * units.eV) calc.set_fdf(’PAO.SplitNorm’, 0.15) atoms.set_calculator(calc) # Set the VelocityVerlet algorithm and run it
Note that both H atoms are given an initial velocity towards the surface through the lines: p = atoms.get_momenta() p[0,2]= -1.5 p[1,2]= -1.5 atoms.set_momenta(p)
Run the program, and check the results. You can visualize the dynamics using the trajectory file with the help of the ASE gui. For example you can visualize the behaviour of the potential and total energies during the dynamics by doing: $ ase-gui -b si001+h2.traj -g i,e,e+ekin
The -b option turns on plotting of bonds between the atoms. Check that the total energy is a conserved quantity in this microcanonical simulation. You can also use VMD to visualize the trajectory. To do this, you need a .xyz file that you can write using ase-gui: $ ase-gui si001+h2.traj -o si.xyz -r 2,2,1
Then simply open the file using VMD: $ vmd si.xyz
and set Graphics/Representations from the main menu in order to get a nice picture. You can also try to repeat the simulation with a different dynamics. For instance you can model a canonical ensemble with the Langevin dynamics, which couples the system to a heat bath: dyn = Langevin(atoms, 1 * fs, kB * 300, 0.002, trajectory=traj)
6.5 Videos The following video tutorials are available: • Overview and installation of ASE, by Anthony Goodrow (duration: ~5min 30sec; size: 26 MB) - en:
52
Chapter 6. Tutorials
CHAPTER
SEVEN
DOCUMENTATION FOR MODULES IN ASE Quick links: atom atoms db dft infrared io neb optimize spacegroup structure thermochemistry units visualize vtk
calculators constraints data gui lattice md parallel phonons surface transport utils vibrations
See Also:
• Tutorials • Automatically generated documentation ( API ) • Source code List of all modules:
7.1 The Atoms object The Atoms object is a collection of atoms. Here is how to define a CO molecule: from ase import Atoms
d = 1.1 co = Atoms(’CO’, positions=[(0, 0, 0), (0, 0, d)])
Here, the first argument specifies the type of the atoms and we used the positions keywords to specify their positions. Other possible keywords are: numbers, tags, momenta, masses, magmoms and charges. Here is how you could make an infinite gold wire with a bond length of 2.9 Å: from ase import Atoms
d = 2.9 L = 10.0 wire = Atoms(’Au’, positions=[(0, L / 2, L / 2)], cell=(d, L, L), pbc=(1, 0, 0))
53
ASE Manual, Release 3.9.0.3484
Here, two more optional keyword arguments were used: cell: Unit cell size This
can be a sequence of three numbers for an orthorhombic unit cell or three by three numbers for a general unit cell (a sequence of three sequences of three numbers). The default value is [1.0, 1.0, 1.0].
pbc: Periodic boundary conditions The
default value is False - a value of True would give periodic boundary conditions along all three axes. It is possible to give a sequence of three booleans to specify periodicity along specific axes.
You can also use the following methods to work with the unit cell and the boundary conditions: set_pbc(), set_cell() , get_cell(), and get_pbc() .
7.1.1 Working with the array methods of Atoms objects Like with a single Atom the properties of a collection of atoms can be accessed and changed with get- and setmethods. For example the positions of the atoms can be addressed as >>> a = Atoms(’N3’, [(0, 0, 0), (1, 0, 0), (0, 0, 1)]) >>> a.get_positions()
Here is the full list of the get/set methods operating on all the atoms at once. The get methods return an array of quantities, one for each atom; the set methods take similar arrays. E.g. get_positions() return N * 3 numbers, get_atomic_numbers() return N integers. These methods return copies of the internal arrays, it is thus safe to modify the returned arrays.
There are also a number of get/set methods that operate on quantities common to all the atoms or defined for the collection of atoms: get_calculator() get_cell() get_center_of_mass() get_kinetic_energy() get_magnetic_moment() get_name() get_number_of_atoms() get_pbc() get_potential_energy() get_stress() get_total_energy() get_volume()
set_calculator() set_cell()
set_pbc()
7.1.2 Unit cell and boundary conditions The Atoms object holds a unit cell which by default is the 3x3 unit matrix as can be seen from >>> a.get_cell()
array([[ 1., [ 0., [ 0.,
0., 1., 0.,
0.], 0.], 1.]])
The cell can be defined or changed using the set_cell() method. Changing the unit cell does per default not move the atoms: >>> a.set_cell(2 * identity(3)) >>> a.get_cell()
However if we set scale_atoms=True the atomic positions are scaled with the unit cell: >>> a.set_cell(identity(3), scale_atoms=True) >>> a.get_positions()
array([[ 1. , [ 0.5, [ 1. ,
0. , 0.5, 1. ,
7.1. The Atoms object
0. ], 0. ], 0. ]])
55
ASE Manual, Release 3.9.0.3484
The set_pbc() method specifies whether periodic boundary conditions are to be used in the directions of the three vectors of the unit cell. A slab calculation with periodic boundary conditions in x and y directions and free boundary conditions in the z direction is obtained through >>> a.set_pbc((True, True, False))
7.1.3 Special attributes It is also possible to work directly with the attributes positions, numbers, pbc and cell. Here we change the position of the 2nd atom (which has count number 1 because Python starts counting at zero) and the type of the first atom: >>> a.positions[1] = (1, 1, 0) >>> a.get_positions()
7.1.4 Adding a calculator A calculator can be attached to the atoms with the purpose of calculating energies and forces on the atoms. ASE works with many different calculators. A calculator object calc is attached to the atoms like this: >>> a.set_calculator(calc)
After the calculator has been appropriately setup the energy of the atoms can be obtained through >>> a.get_potential_energy()
The term “potential energy” here means for example the total energy of a DFT calculation, which includes both kinetic, electrostatic, and exchange-correlation energy for the electrons. The reason it is called potential energy is that the atoms might also have a kinetic energy (from the moving nuclei) and that is obtained with >>> a.get_kinetic_energy()
In case of a DFT calculator, it is up to the user to check exactly what the get_potential_energy() method returns. For example it may be the result of a calculation with a finite temperature smearing of the occupation numbers extrapolated to zero temperature. More about this can be found for the different calculators. The following methods can only be called if a calculator is present:
56
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
• get_potential_energy() • get_potential_energies() • get_forces() • get_stress() • get_stresses() • get_total_energy() • get_magnetic_moments() • get_magnetic_moment() Not all of these methods are supported by all calculators.
7.1.5 List-methods method
example
+ +=, extend()
wire2 = wire + co wire += co wire.extend(co) append() wire.append(Atom(’H’)) wire3 = wire * (3, 1, 1) * *=, repeat() wire *= (3, 1, 1) wire.repeat((3, 1, 1)) len len(co) del del wire3[0] del wire3[[1,3]] pop() oxygen = wire2.pop()
Note that the del method can be used with the more powerful numpy-style indexing, as in the second example above. This can be combined with python list comprehension in order to selectively delete atoms within an ASE Atoms object. For example, the below code creates an ethanol molecule and subsequently strips all the hydrogen atoms from it: from ase.data.molecules import molecule
atoms = molecule(’CH3CH2OH’) del atoms[[atom.index for atom in atoms if atom.symbol==’H’]]
7.1.7 List of all Methods class ase.atoms. Atoms(symbols=None, positions=None, numbers=None, tags=None, momenta=None, masses=None, magmoms=None , charges=None, scaled_positions=None, cell=None, pbc=None , celldisp=None, constraint=None, calculator=None, info=None)
Atoms object.
The Atoms object can represent an isolated molecule, or a periodically repeated structure. It has a unit cell and there may be periodic boundary conditions along any of the three unit cell axes. Information about the atoms (atomic numbers and position) is stored in ndarrays. Optionally, there can be information about tags, momenta, masses, magnetic moments and charges. In order to calculate energies, forces and stresses, a calculator object has to attached to the atoms object. Parameters: Can be a string formula, a list of symbols or a list of Atom objects. Examples: ‘H2O’, ‘COPt12’, [’H’, ‘H’, ‘O’], [Atom(‘Ne’, (x, y, z)), ...].
symbols: str (formula) or list of str
positions: list of xyz-positions Atomic
positions. Anything that can be converted to an ndarray of shape (n, 3) will do: [(x1,y1,z1), (x2,y2,z2), ...].
scaled_positions: list of scaled-positions
Like positions, but given in units of the unit cell. Can not be set
at the same time as positions. numbers: list of int Atomic numbers (use only one of symbols/numbers). tags: list of int Special purpose tags. momenta: list of xyz-momenta Momenta for all atoms. masses: list of float Atomic masses in atomic units. magmoms: list of float or list of xyz-values Magnetic
moments. Can be either a single value for each atom for collinear calculations or three numbers for each atom for non-collinear calculations.
charges: list of float Atomic
charges.
Unit cell vectors. Can also be given as just three numbers for orthorhombic cells. Default value: [1, 1, 1].
cell: 3x3 matrix
Unit cell displacement vector. To visualize a displaced cell around the center of mass of a Systems of atoms. Default value = (0,0,0)
Used for applying one or more constraints during structure optimization.
Used to attach a calculator for calculating energies and atomic forces.
info: dict of key-value pairs Dictionary
of key-value pairs with additional information about the system. The following keys may be used by ase: • spacegroup: Spacegroup instance
58
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
• unit_cell: ‘conventional’ | ‘primitive’ | int | 3 ints • adsorbate_info: Items in the info attribute survives copy and slicing and can be store to and retrieved from trajectory files given that the key is a string, the value is picklable and, if the value is a user-defined object, its base class is importable. One should not make any assumptions about the existence of keys. Examples: These three are equivalent: >>> >>> >>> >>>
Hydrogen wire: >>> d = 0.9 # H-H distance >>> L = 7.0 >>> h = Atoms(’H’, positions=[(0, L / 2, L / 2)], cell=(d, L, L), ... pbc=(1, 0, 0)) ...
append (atom)
Append atom to end. calc
Calculator object. cell
Attribute for direct manipulation of the unit cell. center(vacuum=None, axis=None)
Center atoms in unit cell. Centers the atoms in the unit cell, so there is the same amount of vacuum on all sides. Parameters: vacuum (default: None): If specified adjust the amount of vacuum when centering. If vacuum=10.0 there will thus be 10 Angstrom of vacuum on each side. axis (default: None): If specified, only act on the specified axis. Default: Act on all axes. constraints
Constraints of the atoms. copy()
Return a copy. edit()
Modify atoms interactively through ase-gui viewer. Conflicts leading to undesirable behaviour might arise when matplotlib has been pre-imported with certain incompatible backends and while trying to use the plot feature inside the interactive ag. To circumvent, please set matplotlib.use(‘gtk’) before calling this method. extend (other )
Extend atoms object by appending atoms from other . 7.1. The Atoms object
59
ASE Manual, Release 3.9.0.3484
get_angle(list )
Get angle formed by three atoms. calculate angle between the vectors list[1]->list[0] and list[1]->list[2], where list contains the atomic indexes in question. get_angular_momentum ()
Get total angular momentum with respect to the center of mass. get_array(name, copy=True )
Get an array. Returns a copy unless the optional argument copy is false. get_atomic_numbers()
Get integer array of atomic numbers. get_calculation_done()
Let the calculator calculate its thing, using the current input. get_calculator()
Get currently attached calculator object. get_cell()
Get the three unit cell vectors as a 3x3 ndarray. get_celldisp()
Get the unit cell displacement vectors . get_center_of_mass(scaled=False )
Get the center of mass. If scaled=True the center of mass in scaled coordinates is returned. get_charges()
Get calculated charges. get_chemical_formula(mode=’hill’)
Get the chemial formula as a string based on the chemical symbols. Parameters: mode:
There are three different modes available:
‘all’: The list of chemical symbols are contracted to at string, e.g. [’C’, ‘H’, ‘H’, ‘H’, ‘O’, ‘H’] becomes ‘CHHHOH’. ‘reduce’: The same as ‘all’ where repeated elements are contracted to a single symbol and a number, e.g. ‘CHHHOCHHH’ is reduced to ‘CH3OCH3’. ‘hill’: The list of chemical symbols are contracted to a string following the Hill notation (alphabetical order with C and H first), e.g. ‘CHHHOCHHH’ is reduced to ‘C2H6O’ and ‘SOOHOHO’ to ‘H2O4S’. This is default. get_chemical_symbols(reduce=False)
Get list of chemical symbol strings. get_dihedral(list )
Calculate dihedral angle. Calculate dihedral angle between the vectors list[0]->list[1] and list[2]->list[3], where list contains the atomic indexes in question. get_dipole_moment()
Calculate the electric dipole moment for the atoms object. Only available for calculators which has a get_dipole_moment() method.
60
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
get_distance(a0, a1 , mic=False)
Return distance between two atoms. Use mic=True to use the Minimum Image Convention. get_forces(apply_constraint=True)
Calculate atomic forces. Ask the attached calculator to calculate the forces and apply constraints. Use to get the raw forces.
apply_constraint=False
get_initial_charges()
Get array of initial charges. get_initial_magnetic_moments()
Get array of initial magnetic moments. get_isotropic_pressure(stress)
Get the current calculated pressure, assume isotropic medium. in Bar get_kinetic_energy()
Get the kinetic energy. get_magnetic_moment()
Get calculated total magnetic moment. get_magnetic_moments()
Get calculated local magnetic moments. get_masses()
Get array of masses. get_momenta()
Get array of momenta. get_moments_of_inertia(vectors=False )
Get the moments of inertia along the principal axes. The three principal moments of inertia are computed from the eigenvalues of the symmetric inertial tensor. Periodic boundary conditions are ignored. Units of the moments of inertia are amu*angstrom**2. get_number_of_atoms()
Returns the number of atoms. Equivalent to len(atoms) in the standard ASE Atoms class. get_pbc()
Get periodic boundary condition flags. get_positions(wrap=False)
Get array of positions. If wrap==True, wraps atoms back into unit cell. get_potential_energies()
Calculate the potential energies of all the atoms. Only available with calculators supporting per-atom energies (e.g. classical potentials). get_potential_energy()
Calculate potential energy. get_reciprocal_cell()
Get the three reciprocal lattice vectors as a 3x3 ndarray. Note that the commonly used factor of 2 pi for Fourier transforms is not included here. get_scaled_positions()
Get positions relative to unit cell.
7.1. The Atoms object
61
ASE Manual, Release 3.9.0.3484
Atoms outside the unit cell will be wrapped into the cell in those directions with periodic boundary conditions so that the scaled coordinates are between zero and one. get_stress(voigt=True )
Calculate stress tensor. Returns an array of the six independent components of the symmetric stress tensor, in the traditional Voigt order (xx, yy, zz, yz, xz, xy) or as a 3x3 matrix. Default is Voigt order. get_stresses()
Calculate the stress-tensor of all the atoms. Only available with calculators supporting per-atom energies and stresses (e.g. classical potentials). Even for such calculators there is a certain arbitrariness in defining per-atom stresses. get_tags()
Get integer array of tags. get_temperature()
Get the temperature. in Kelvin get_total_energy()
Get the total energy - potential plus kinetic energy. get_velocities()
Get array of velocities. get_volume()
Get volume of unit cell. has(name)
Check for existence of array. name must be one of: ‘tags’, ‘momenta’, ‘masses’, ‘magmoms’, ‘charges’. new_array(name, a , dtype=None, shape=None)
Add new array. If shape is not None, the shape of a will be checked. numbers
Attribute for direct manipulation of the atomic numbers. pbc
Attribute for direct manipulation of the periodic boundary condition flags. pop(i=-1)
Remove and return atom at index i (default last). positions
Attribute for direct manipulation of the positions. rattle(stdev=0.001, seed=42)
Randomly displace atoms. This method adds random displacements to the atomic positions, taking a possible constraint into account. The random numbers are drawn from a normal distribution of standard deviation stdev. For a parallel calculation, it is important to use the same seed on all processors! repeat(rep)
Create new repeated atoms object. The rep argument should be a sequence of three positive integers like (2,3,1) or a single integer ( r ) equivalent to (r,r,r). rotate(v, a=None, center=(0, 0 , 0) , rotate_cell=False )
Rotate atoms based on a vector and an angle, or two vectors. Parameters: 62
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
v:
Vector to rotate the atoms around. Vectors can be given as strings: ‘x’, ‘-x’, ‘y’, ... . Angle that the atoms is rotated around the vecor ‘v’. If an angle is not specified, the length of ‘v’ is used as the angle (default). The angle can also be a vector and then ‘v’ is rotated into ‘a’.
a = None:
center = (0, 0, 0): The
center is kept fixed under the rotation. Use ‘COM’ to fix the center of mass, ‘COP’ to fix the center of positions or ‘COU’ to fix the center of cell.
rotate_cell = False: If true the cell is also rotated.
Examples: Rotate 90 degrees around the z-axis, so that the x-axis is rotated into the y-axis: >>> a = pi / 2 >>> atoms.rotate(’z’, a) >>> atoms.rotate((0, 0, 1), a) >>> atoms.rotate(’-z’, -a) >>> atoms.rotate((0, 0, a)) >>> atoms.rotate(’x’, ’y’)
rotate_dihedral(list , angle, mask=None)
Rotate dihedral angle. Complementing the two routines above: rotate a group by a predefined dihedral angle, starting from its current configuration rotate_euler(center=(0, 0 , 0) , phi=0.0, theta=0.0, psi=0.0)
Rotate atoms via Euler angles. See e.g http://mathworld.wolfram.com/EulerAngles.html for explanation. Parameters: center : The
point to rotate about. A sequence of length 3 with the coordinates, or ‘COM’ to select the center of mass, ‘COP’ to select center of positions or ‘COU’ to select center of cell.
phi : The 1st rotation angle around the z axis. theta : Rotation around the x axis. psi : 2nd rotation around the z axis. set_angle(list , angle, mask=None)
Set angle formed by three atoms. Sets the angle between vectors list[1]->list[0] and list[1]->list[2]. Same usage as in set_dihedral. set_array(name, a , dtype=None, shape=None)
Update array. If shape is not None, the shape of a will be checked. If a is None, then the array is deleted. set_atomic_numbers(numbers)
Deprecated method. Use set_initial_charges. set_chemical_symbols(symbols)
Set chemical symbols. set_constraint(constraint=None)
Apply one or more constrains. The constraint argument must be one constraint object or a list of constraint objects. set_dihedral(list , angle, mask=None)
set the dihedral angle between vectors list[0]->list[1] and list[2]->list[3] by changing the atom indexed by list[3] if mask is not None, all the atoms described in mask (read: the entire subgroup) are moved example: the following defines a very crude ethane-like molecule and twists one half of it by 30 degrees. >>> atoms = Atoms(’HHCCHH’, [[-1, 1, 0], [-1, -1, 0], [0, 0, 0],
Set the distance between two atoms. Set the distance between atoms a0 and a1 to distance. By default, the center of the two atoms will be fixed. Use fix=0 to fix the first atom, fix=1 to fix the second atom and fix=0.5 (default) to fix the center of the bond. set_initial_charges(charges=None)
Set the initial charges. set_initial_magnetic_moments(magmoms=None)
Set the initial magnetic moments. Use either one or three numbers for every atom (collinear or non-collinear spins). set_masses(masses=’defaults’)
Set atomic masses. The array masses should contain a list of masses. In case the masses argument is not given or for those elements of the masses list that are None, standard values are set. set_momenta(momenta)
Set momenta. set_pbc( pbc)
Set periodic boundary condition flags. set_positions(newpositions)
Set positions, honoring any constraints. set_scaled_positions(scaled )
Set positions relative to unit cell. set_tags(tags)
Set tags for all atoms. If only one tag is supplied, it is applied to all atoms.
64
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
set_velocities(velocities)
Set the momenta by specifying the velocities. translate(displacement )
Translate atomic positions. The displacement argument can be a float an xyz vector or an nx3 array (where n is the number of atoms). write( filename, format=None, **kwargs)
Write yourself to a file.
7.2 The Atom object ASE defines a python class called Atom to setup and handle atoms in electronic structure and molecular simulations. From a python script, atoms can be created like this: >>> from ase import Atom >>> a1 = Atom(’Si’, (0, 0, 0)) >>> a2 = Atom(’H’, (1.3, 0, 0), mass=2) >>> a3 = Atom(position=(0, 0, 0), Z=14)
# same is a1
class ase.atom. Atom (symbol=’X’, position=(0, 0, 0), tag=None, momentum=None , mass=None, magmom=None, charge=None , atoms=None, index=None)
Class for representing a single atom. Parameters: symbol: str or int
Can be a chemical symbol (str) or an atomic number (int).
position: sequence of 3 floats Atomi
position.
tag: int Special purpose tag. momentum: sequence of 3 floats Momentum for atom. mass: float Atomic mass in atomic units. magmom: float or 3 floats Magnetic charge: float Atomic
moment.
charge.
The first argument to the constructor of an Atom object is the chemical symbol, and the second argument is the position in Å units (see units). The position can be any numerical sequence of length three. The properties of an atom can also be set using keywords like it is done in the a2 and a3 examples above. More examples: >>> a = Atom(’O’, charge=-2) >>> b = Atom(8, charge=-2) >>> c = Atom(’H’, (1, 2, 3), magmom=1) >>> print a.charge, a.position
If the atom object belongs to an Atoms object, then assigning values to the atom attributes will change the corresponding arrays of the atoms object: >>> OH = Atoms(’OH’) >>> OH[0].charge = -1 >>> OH.get_charges()
array([-1.,
0.])
Another example: >>> for atom in bulk: ... if atom.symbol == ’Ni’: ... atom.magmom = 0.7 # set initial magnetic moment
The different properties of an atom can be obtained and changed via attributes ( position , number, tag, momentum , mass, magmom, charge, x, y, z): >>> a1.position = [1, 0, 0] >>> a1.position
That last line will set the initial magnetic moment that some calculators use (similar to the set_initial_magnetic_moments() method). The position and momentum attributes refer to mutable objects, so in some cases, you may want to use a1.position.copy() in order to avoid changing the position of a1 by accident. Note:
7.2.1 Getting an Atom from an Atoms object Indexing an Atoms object returns an Atom object still remembering that it belongs to the collective Atoms: Modifying it will also change the atoms object: >>> atoms = ase.data.molecules.molecule(’CH4’) >>> atoms.get_positions()
More information about how to use collections of atoms.
calculators:
66
Information about how to calculate forces and energies of atoms.
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
7.3 Units Physical units are defined in the ase/units.py module. Electron volts (eV) and angstroms (Ang) are defined as 1.0. Other units are nm, Bohr, Hartree or Ha, kJ, kcal, mol, Rydberg or Ry, second, fs and kB. Note:
7.4 The ase.data module This module defines the following variables: atomic_masses , atomic_names , chemical_symbols , covalent_radii , cpk_colors and reference_states . All of these are lists that should be indexed with an atomic number: >>> atomic_names[92]
’Uranium’ >>> atomic_masses[2] 4.0026000000000002
If you don’t know the atomic number of some element, then you can look it up in the atomic_numbers dictionary: >>> atomic_numbers[’Cu’]
29 >>> covalent_radii[29]
1.1699999999999999
7.5 File input and output The io module has two basic functions: read() and write(). The two methods are described here: ase.io. read ( filename, index=None, format=None)
Read Atoms object(s) from file. filename: str Name of the file to read from. index: int or slice If
the file contains several configurations, the last configuration will be returned by default. Use index=n to get configuration number n (counting from zero).
format: str Used
to specify the file-format. If not given, the file-format will be guessed by the filetype
function. Known formats:
7.3. Units
67
ASE Manual, Release 3.9.0.3484
format
short name
GPAW restart-file Dacapo netCDF output file Old ASE netCDF trajectory Virtual Nano Lab file ASE pickle trajectory ASE bundle trajectory GPAW text output CUBE file XCrySDen Structure File Dacapo text output XYZ-file VASP POSCAR/CONTCAR file VASP OUTCAR file SIESTA STRUCT file ABINIT input file V_Sim ascii file Protein Data Bank CIF-file FHI-aims geometry file FHI-aims output file VTK XML Image Data VTK XML Structured Grid VTK XML Unstructured Grid TURBOMOLE coord file TURBOMOLE gradient file exciting input AtomEye configuration WIEN2k structure file DftbPlus input file CASTEP geom file CASTEP output file CASTEP trajectory file ETSF format DFTBPlus GEN format CMR db/cmr-file CMR db/cmr-file LAMMPS dump file EON reactant.con file Gromacs coordinates Gaussian com (input) file Gaussian output file Quantum espresso in file Quantum espresso out file
Write Atoms object(s) to file. filename: str Name of the file to write to. images: Atoms object or list of Atoms objects A single Atoms object or a list of Atoms objects.
Used to specify the file-format. If not given, the file-format will be taken from suffix of the filename.
format: str
The accepted output formats:
68
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
format
short name
ASE pickle trajectory ASE bundle trajectory CUBE file XYZ-file VASP POSCAR/CONTCAR file ABINIT input file Protein Data Bank CIF-file XCrySDen Structure File FHI-aims geometry file gOpenMol .plt file Python script Encapsulated Postscript Portable Network Graphics Persistance of Vision VTK XML Image Data VTK XML Structured Grid VTK XML Unstructured Grid TURBOMOLE coord file exciting AtomEye configuration WIEN2k structure file CASTEP cell file DftbPlus input file ETSF DFTBPlus GEN format CMR db/cmr-file CMR db/cmr-file EON reactant.con file Gromacs coordinates GROMOS96 (only positions) X3D X3DOM HTML
The use of additional keywords is format specific. The cube and plt formats accept (plt requires it) a data keyword, which can be used to write a 3D array to the file along with the nuclei coordinates. The vti, vts and vtu formats are all specifically directed for use with MayaVi, and the latter is designated for visualization of the atoms whereas the two others are intended for volume data. Further, it should be noted that the vti format is intended for orthogonal unit cells as only the grid-spacing is stored, whereas the vts format additionally stores the coordinates of each grid point, thus making it useful for volume date in more general unit cells. The eps, png, and pov formats are all graphics formats, and accept the additional keywords: rotation: str (default ‘’) The rotation angles, e.g. ‘45x,70y,90z’. show_unit_cell: int (default 0)
Can be 0, 1, 2 to either not show, show, or show all of the unit cell.
radii: array or float (default 1.0) An array of same length as the list of atoms indicating the sphere radii.
A single float specifies a uniform scaling of the default covalent radii. bbox: 4 floats (default None)
Set the bounding box to (xll, yll, xur, yur) (lower left, upper right).
An array of same length as the list of atoms, indicating the rgb color code for each atom. Default is the jmol_colors of ase/data/colors.
colors: array (default None)
scale: int (default 20) Number of pixels per Angstrom.
7.5. File input and output
69
ASE Manual, Release 3.9.0.3484
For the pov graphics format, scale should not be specified. The elements of the color array can additionally be strings, or 4 and 5 vectors for named colors, rgb + filter, and rgb + filter + transmit specification. This format accepts the additional keywords: run_povray , display, pause, transparent, canvas_width , canvas_height , camera_dist , image_plane , camera_type, point_lights , area_light , background, textures , celllinewidth , bondlinewidth , bondatoms
The xyz format accepts a comment string using the comment keyword: comment: str (default ‘’)
Optional comment written on the second line of the file.
The read() function is only designed to retrieve the atomic configuration from a file, but for the CUBE format you can import the function: io.read_cube_data()
which will return a (data, atoms) tuple: from ase.io.cube import read_cube_data
A script showing all of the povray parameters, and generating the image below, can be found here: doc/ase/save_pov.py
7.6. Examples
71
ASE Manual, Release 3.9.0.3484
An other example showing how to change colors and textures in pov can be found here: doc/tutorials/saving_graphics.py
7.7 ASE-GUI The graphical user-interface allows users to visualize, manipulate, and render molecular systems and atoms ob jects. It also allows to setup and run a number of calculations and can be used to transfer between different file formats.
72
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
7.7.1 ase-gui basics and command line options General use
Visualizing a system with ase-gui is straight-forward using a regular mouse. The scroll function allows to change the magnification, the left mouse button selects atoms, the right mouse button allows to rotate, and the middle button allows to translate the system on the screen. Depending on the number of selected atoms, ase-gui automatically measures different quantities: Selection
measurement
single atom two atoms three atoms four atoms, selected sequentially more than four atoms
xyz position and atomic symbol interatomic distance and symbols all three internal angles and symbols Measures the dihedral angle, e.g. the angle between bonds 12 and 34 chemical composition of selection.
ase-gui can save the following file formats: File format
XYZ file ASE trajectory PDB file Gaussian cube file Python script VNL file Portable Network Graphics Persistance of Vision Encapsulated PostScript FHI-aims geometry input VASP geometry input ASE bundle trajectory Crystallographic Information File
Files
The ase-gui program can read all the file formats the ASE’s read() function can understand. $ ase-gui N2Fe110-path.traj
Selecting part of a trajectory
A Python-like syntax for selecting a subset of configurations can be used. Instead of the Python syntax list[start:stop:step] , you use filaname@start:stop:step : $ $ $ $ $ $ $
first 10 images first 10 images first 10 images last 10 images first image last image every second image
If you want to select the same range from many files, the you can use the -n or --image-number option: $ ase-gui -n -1 *.traj $ ase-gui -n 0 *.traj
# last image from all files # first image from all files
Tip: Type ase-gui -h for a description of all command line options.
7.7. ASE-GUI
73
ASE Manual, Release 3.9.0.3484
Writing files $ ase-gui -n -1 a *.traj -o new.traj
Possible formats are: traj, xyz, cube, pdb, eps, png, and pov. For details, see the io module documentation. Interactive use
The ase-gui program can also be launched directly from a Python script or interactive session: >>> from ase import * >>> atoms = ... >>> view(atoms)
or >>> view(atoms, repeat=(3, 3, 2))
or, to keep changes to your atoms: >>> atoms.edit()
NEB calculations
Use Tools → NEB to plot energy barrier. $ ase-gui --interpolate 3 initial.xyz final.xyz -o interpolated_path.traj
Plotting data from the command line
Plot the energy relative to the energy of the first image as a function of the distance between atom 0 and 5: $ ase-gui -g "d(0,5),e-E[0]" x.traj $ ase-gui -t -g "d(0,5),e-E[0]" x.traj > x.dat
# No GUI, write data to stdout
The symbols are the same as used in the plotting data function. Defaults for ase-gui
Using a file ~/.ase/gui.py , certain defaults can be set. If it exists, this file is executed after initializing the variables and colours normally used in ase-gui. One can change the default graphs that are plotted, and the default radii for displaying specific atoms. This example will display the energy evolution and the maximal force in a graph and also display Cu atoms (Z=29) with a radius of 1.6 Angstrom. gui_default_settings[’gui_graphs_string’] = "i, e - min(E), fmax" gui_default_settings[’covalent_radii’] = [[29,1.6]]
High contrast settings for ase-gui
In revision 2600 or later, it is possible to change the foreground and background colors used to draw the atoms, for instance to draw white graphics on a black background. This can be done in ~/.ase/gui.py . gui_default_settings[’gui_foreground_color’] = ’#ffffff’ #white gui_default_settings[’gui_background_color’] = ’#000000’ #black
74
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
To change the color scheme of graphs it is necessary to change the default behaviour of Matplotlib in a similar way by using a file ~/.matplotlib/matplotlibrc . patch.edgecolor text.color axes.facecolor axes.edgecolor axes.labelcolor axes.color_cycle xtick.color ytick.color grid.color figure.facecolor figure.edgecolor
: : : : : : : : : : :
white white black white white b, g, r, c, m, y, w white white white 0.1 black
Finally, the color scheme of the windows themselves (i.e. menus, buttons and text etc.) can be changed by choosing a different desktop theme. In Ubuntu it is possible to get white on a dark background by selecting the theme HighContrastInverse under Appearances in the system settings dialog.
7.7.2 Edit Add atoms
Allows to add single atoms or a group of atoms to an existing atoms object. If the description is an atom or a known molecule from the g1, g2, or g3 set (e.g. CH4), then the structure from the data molecule is used. In addition, a molecule can also be imported from file via the load molecule button. The specified position can either be absolute, or determined automatically via auto+
where auto is the centre of mass of the currently selected atoms, and is the distance toward the viewing plane. The molecule-to-be is rotated into the current viewing plane before addition into the system. Two options exist for choosing the origin within the new atoms, it can be either the centre of mass or the origin of the loaded geometry. Modify
Menu to allow modification of the atomic symbol, an attached tag, or its magnetic moment. Copy/Paste
Allows to copy parts of an existing system to a clipboard, and pastes via the same infrastructure as the Add atoms functionality. Note that the on-screen orientation of the pasted atoms will be the same as at the time of copying. Note also that, by default, the origin of the pasted system is taken to be the atom furthest away from the viewing point.
7.7.3 View Repeat
Menu to allow repetition of periodic unit cells. Use the ‘Set unit cell’ button to set the overall unit cell to the current one.
7.7. ASE-GUI
75
ASE Manual, Release 3.9.0.3484
Rotate
Menu to manually fine tune the viewing angle. Use ‘Update’ button to set the menu to the current angle. Colors
The colors menu allows numerous ways to change the color scheme and to encode additional information into the display colors. This includes automatic coloring by atomic numbers (default), user-specified atomic number scheme, coloring by tags, forces, or completely manually specified colors. In addition, several standard color scales are available. Settings
Basic viewing settings. Also allows to constrain/unconstrain atoms and to mark selected atoms as invisible.
7.7.4 Tools Graphs
Allows to graph different quantities for a given trajectory. A ‘save’ button also gives the opportunity to save the data to file. This example plots the maximal force for each image i and could help in investigating the convergence properties for relaxations: i, e-min(E), fmax
These are the symbols that can be used: Symbol
Interpretation
e epot ekin fmax fave d(n1,n2) R[n,0-2] i E[i] F[n,0-2] M[n] A[0-2,0-2] s a(n1,n2,n3) dih(n1,n2,n3,n4) T
total energy potential energy kinetic energy maximum force average force distance between two atoms position of atom number n current image number energy of image number i force on atom number n magnetic moment of atom number n unit-cell basis vectors path length tangle between atoms n1, n2 and n3, centered on n2 dihedral angle between n1, n2, n3, and n4 temperature (requires velocity)
Movie
Allows to play the current trajectory as a movie using a number of different settings. Default duration is 5 s. Expert mode
Python interface to all ase-gui functions, with numerous extra commands defined that help to modify and visualize a system. The commands come in two flavors, the first is interpreted on an atom-by-atom basis (e.g. operates on 76
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
position, color, etc) and the second is based on the entire frame. The flavor of a given line is determined from the first command. Note that the frame-based commands can be used in atom-based operations, but not vice versa. See below for some examples. Regular python syntax applies to the commands and numpy has been imported as np. Two buttons allow to reduce the operation to a given frame: Only selected atoms (sa) Only current frame (cf)
Restricts operation only to the selected atoms. The text command sa activates or deactivates this button. Restricts operation only to the current frame, useful for long trajectories. The text command cf activates or deactivates this button.
List of atom-based commands with a few examples: Command
Interpretation
x,y,z r,g,b
Cartesian coordinates. Example: x += A[0][0] Color components, invoking the expert mode changes the color mode to manual and allows to address all colors individually. Example: r = (z-min(R[:,2]))/(max(R[:,2])-min(R[:,2]))
rad s
atomic display radius Boolean to control the selection of an atom. Example: s = Z == 6 a nd x > 5 or s = d == False
f Z m d
force on an atom atomic number magnetic moment dynamic, e.g. d = False fixes an atom
List of frame-based and global commands and global objects with examples: Command
Interpretation
e fmax A E F M R S D del S sa,cf frame center cov self gui img
total energy maximal force unit cell total energy array of all frames. Example: e-min(E) all forces in one frame all magnetic moments all atomic positions boolean array of the entire selection boolean array of dynamic atoms (False = atom is fixed) deletes current selection toggles the selected-atoms-only or the current-frame-only buttons provides and edits the frame number in a trajectory centers system in its unit cell array of original covalent radii expert mode window ase-gui GUI object, this controls the entire ase-gui session ase-gui images object, all physical data is stored here
To save data between commands, one has to assign variables to parent objects in the gui, e.g. via self.temp_var = R-img.P[0,:] . DISCLAIMER: Doing so might risk the functionality of the entire ase-gui session if you accidentally overwrite basic functionality of the gui or the image objects stored within. Finally, recurring selections of commands collected as scripts can be executed as exec
If the file in question is saved in the directory ~/.ase/ then just the filename will also do.
7.7. ASE-GUI
77
ASE Manual, Release 3.9.0.3484
Constraints
Allows to set (or remove) constraints based on the currently selected atoms. Render scene
Graphical interface to the ASE povray interface, ideally it requires that povray is installed on your computer to function, but it also can be used just to export the complete set of povray files. The texture of each atom is adjustable: The default texture is applied to all atoms, but then additional textures can be defined based on selections ( Create new texture from current selection ). These can be obtained either from selecting atoms by hand or by defining a selection with a boolean expression, for example Z==6 and x>5 and y<0 will select all carbons with coordinates x>5 and y<0. The available commands are listed in the Help on textures window. A movie-making mode ( render all N frames) is also available. After rendering, the frames can be stitched together using the convert unix program e.g. localhost:doc hanke$ convert -delay 4.17 temp.*.png temp.gif
For this particular application it might be a good idea to use a white background instead of the default transparent option. Move atoms
Allows selected atoms to be moved using the arrow keys. The direction is always parallel to the plane of the screen. Two possible movements are available: Just pressing the arrow keys will move by 0.1 Angstrom, shift + arrow keys will move by 0.01 Angstrom. Rotate atoms
Allows sets of atoms to be rotated using the arrow keys. Different rotation modes are available depending on the number of selected atoms. Again, two modes are available. Just the arrow keys will rotate by 2.5 degrees, and shift + arrow keys will rotate by 0.5 deg. number of atoms labeled
rotation mode
0 atoms, 1, 3, 5 or more atoms 2 atoms 4 atoms, selected sequentially
uses the centre of mass of the atoms to be rotated as the rotation centre. Defines the vector connecting the two atoms as rotation axis. Defines the vector connecting the two atoms as rotation axis. This mode has the advantage that the dihedral angle is measured at the same time, thus allowing one to monitor the degree of rotation.
Orient atoms
stub NEB
stub Bulk Modulus
stub
78
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
7.7.5 Setup The setup menus allow for the intuitive creation of numerous standard surfaces, nanoparticles, graphene and graphene nanoribbons, as well as nanotubes. Along with creating the geometry within ase-gui, a button provides the necessary python code allowing one to recreate the exact same geometry in ASE scripts.
7.7.6 Calculate Set calculator
Allows gui to choose a calculator for internal computations (see below). Different density functional codes and force fields, as well as the EMT calculator are available. For the FHI-aims and VASP calculators, it is also possible to export an entire set of input files. Energy and forces
Invokes the currently set calculator and provides energies and optional forces for all atoms. Energy minimization
Runs an ASE relaxation using the currently selected calculator with a choice of relaxation algorithm and convergence criteria. Great for quickly (pre-)relaxing a molecule before placing it into a bigger system. Scale system
Stub
7.8 Command line tool The ase program can be used to do calculations with ASE supported calculators on the command line without having to write a Python script. The syntax is: $ ase [calculator] [task] [options] system(s)
The name of the calculator must be lower case and will default to EMT. The task must be molecule or bulk. There are several ways to specify the system or systems to perform the calculations on: • Chemical names: H2O or Fe. Default molecule definitions are used. • Range of chemical symbols: Sc-Zn (3d-metals) • Special names: G2 , G2_1 or S22 • File names: benzene.xyz or slab.traj The exact meaning of these names will depend on the task. Simple examples: $ ase emt H2 --relax=0.01 $ ase abinit bulk Si -a 5.5 -p ecut=150 -k 4,4,4
7.8. Command line tool
79
ASE Manual, Release 3.9.0.3484
7.8.1 Command line options General options: -h, --help
Show help message and exit.
-t TAG, --tag=TAG
String tag added to filenames.
-M , --magnetic-moment=
Magnetic moment(s). Use “-M 1” or “-M
2.3,-2.3”. -G, --gui
Pop up ASE’s GUI.
-s, --write-summary Write
summary.
Select subset of calculations using Python slice syntax. Use ”::2” to do every second calculation and ”:-5” to do the last five.
--slice=
-w FILENAME, --write-to-file=FILENAME
Write configuration to file.
Run calculation inside interactive Python session. A possible $PYTHONSTARTUP script will be imported and the “atoms” variable refers to the Atoms object.
-i, --interactive-python-session
-l, --use-lock-files
Skip calculations where the json lock-file or result file already exists.
-R FMAX, --relax=FMAX
Relax internal coordinates using L-BFGS algorithm.
Find optimal bondlength and vibration frequency for dimer molecules or optimal volume and bulk modulus for bulk systems using N points and a variation from -x % to +x % for the bondlength or lattice constants.
-F , --fit=
--constrain-tags=
Constrain atoms with tags T1, T2, ...
Monkhorst-Pack sampling of BZ. Example: “4,4,4”: 4x4x4 k-points, “4,4,4g”: same set of k-points shifted to include the Gamma point.
-k , --monkhorst-pack=
--k-point-density=K_POINT_DENSITY
Density of k-points in Å.
-p , --parameters=
Comma-separated key=value pairs of calcula-
tor specific parameters. Options specific to the molecule task: -v VACUUM, --vacuum=VACUUM Amount
of vacuum to add around isolated systems (in
Angstrom). --unit-cell=CELL
Unit cell. Examples: “10.0” or “9,10,11” (in Angstrom).
--bond-length=BOND_LENGTH --atomize
Bond length of dimer in Angstrom.
Calculate Atomization energies.
Options specific to the bulk task: -x CRYSTAL_STRUCTURE, --crystal-structure=CRYSTAL_STRUCTURE
Crystal
struc-
ture. -a LATTICE_CONSTANT, --lattice-constant=LATTICE_CONSTANT --c-over-a=C_OVER_A
This will calculate the energy of a H 2 molecule using Abinit with a planewave cutoff of 200 eV and the LDA XC-functional. A fit using 5 points and a variation of the bond length from -1 % to +1 % is made and in addition the energy of a single hydrogen atom is also calculated. Results are written to json files and can be analysed with: $ ase abinit H H2 -s name E eV H2 -29.703 H -12.426
E-E0 eV 0.022
d0 Ang 0.770
hnu meV 556.096
Ea eV 4.852
Ea0 eV 4.873
The json files are simple text files that can be more or less’ed or pretty printed with python -m json.tool H2-molecule-abinit.jon . Note:
7.8.3 Bulk systems Example: $ ase bulk Ni Cu Pd Ag Pt Au -F 5,1
Here we used the default EMT potential and the result is: $ ase bulk Ni Cu Pd Ag Pt Au -s name E E-E0 eV eV Ni -0.009 0.005 Ag 0.002 0.002 Pt -0.000 0.000 Au 0.003 0.003 Pd 0.000 0.001 Cu -0.006 0.001
B GPa 175.978 100.151 278.087 173.868 179.105 134.439
More examples
Anti-ferromagnetic bcc iron: $ ase vasp bulk -x bcc Fe -C -M 2.3,-2.3 -p xc=PBE -k 8,8,8
Bulk silicon (128 atoms, Γ point only): $ ase abinit bulk Si -r 4,4,4 -k 1,1,1 -a 5.46
Bulk aluminum in orthorhombic cell with LDA and fixed rmt: $ ase elk bulk --orthorhombic Al -k 4,4,4 -a 4.05 -p "swidth=0.1,rmt={’Al’: 1.9}"
7.8.4 Batch jobs Suppose you want to run a large number of similar calculations like relaxing the structure of all the molecules in the G2-1 database . You could do that by submitting this job to your compute cluster:
7.8. Command line tool
81
ASE Manual, Release 3.9.0.3484
$ ase gpaw G2_1 -v 6.0 -p xc=vdW-DF,h=0.18 -R 0.02
The molecule task will expand G2_1 to a lot of molecules, so it makes sense to use -l option (--use-lock-files) and submit the same job many times. A lock file will be created for each started calculation and calculations with existing lock file skipped. Moreover the calculations can be run in parallel (if parallel version of GPAW is installed): $ mpiexec gpaw-python ‘which ase‘ gpaw G2_1 -v 6.0 -p xc=vdW-DF,h=0.18 -R 0.02 -l
7.8.5 Making your own tasks FCC clusters with 13 atoms
Put this in m13.py: from math import sqrt from ase.cluster.cubic import FaceCenteredCubic from ase.tasks.molecule import MoleculeTask from ase.data import covalent_radii, atomic_numbers class M13Task(MoleculeTask):
taskname = ’m13’ def build_system(self, name): if self.bond_length is None: b = 2 * covalent_radii[atomic_numbers[name]] else: b = self.bond_length return FaceCenteredCubic(name, [(1, 0, 0)], [1],
latticeconstant=b * sqrt(2)) task = M13Task()
Then do this: $ ase m13.py Pt -R 0.01
The relaxed EMT bondlength of 2.62 Å can be extracted from the created trajectory like this: $ ase-gui -tg "e,fmax,d(0,9)" Pt-m13-emt.traj 10.9824302706 2.27575724833 2.72 10.0805658256 1.45353946744 2.68 9.61654400875 0.447140179352 2.64 9.57510700742 0.0656434401881 2.6222281202 9.57424531861 0.00239771758341 2.62450316817
or like this: >>> from ase.io import read >>> pt = read(’Pt-m13-emt.traj’) >>> pt.get_distance(0, 9)
2.6245031681662452
Convergence test
See convergence.py.
7.8.6 To be done • Optimize c/a ratio. 82
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
• Implement different way of cell sampling for eos: [a0 + s for s in [x * np.array(range(- N/2 + 1, N/2 + 1))]] where x is sampling step length, N number of steps. Current way of sampling gives different length of sampling interval depending on the lattice constant guess a0. DONE • Write results to file (pickel, csv, cmr (db), traj, ...) per system, together with json file! • Split off EnergyTask from Task. • Set correct magnetic moments for atoms. DONE • Allow setting charges in ase.tasks.task • Check occupation numbers and requested total magnetic moments for molecules/atoms. DONE • Add –exclude option. • Relax cell. DONE • Optimize first then fit. DONE • Behavior of -w option? • Reaction task? • Rethink analysis and summary stuff: – it
would be nice to calculate for example cohesive energies on the command line, i.e. using species belonging to different tasks
–
analysis should be more modular: one may want for example to calculate zpe energies for adsorption systems including molecules and surfaces and print the zpe correction for a given reaction.
• ase.tasks.main - print complete architecture string in case of error (like in ase/test/__init__.py)
7.9 Creating atomic structures See Also:
• The lattice module • The spacegroup module • The surface module
Crystal structure and lattice constant(s) will be guessed if not provided. name: str Chemical symbol or symbols as in ‘MgO’ or ‘NaCl’. crystalstructure: str Must
be one of sc, fcc, bcc, hcp, diamond, zincblende, rocksalt, cesiumchloride, or
fluorite. a: float Lattice
constant.
c: float Lattice
constant.
covera: float c/a raitio used for hcp. Use sqrt(8/3.0) for ideal ratio. orthorhombic: bool
Construct orthorhombic unit cell instead of primitive cell which is the default.
cubic: bool Construct cubic unit cell if possible.
7.9.4 Special points in the Brillouin zone You can find the special points in the Brillouin zone: >>> from ase.structure import bulk >>> from ase.dft.kpoints import ibz_points, get_bandpath >>> si = bulk(’Si’, ’diamond’, a=5.459) >>> points = ibz_points[’fcc’] >>> G = points[’Gamma’] >>> X = points[’X’] >>> W = points[’W’] >>> K = points[’K’] >>> L = points[’L’] >>> kpts, x, X = get_bandpath([W, L, G, X, W, K], si.cell) >>> print len(kpts), len(x), len(X)
50 50 6
7.9. Creating atomic structures
85
ASE Manual, Release 3.9.0.3484
7.9.5 Surfaces Common surfaces
A number of utility functions are provided to set up the most common surfaces, to add vacuum layers, and to add adsorbates to a surface. In general, all surfaces can be set up with the modules described in the section General crystal structures and surfaces , but these utility functions make common tasks easier. Example
To setup an Al(111) surface with a hydrogen atom adsorbed in an on-top position: from ase.lattice.surface import *
slab = fcc111(’Al’, size=(2,2,3), vacuum=10.0)
This will produce a slab 2x2x3 times the minimal possible size, with a (111) surface in the z direction. A 10 Å vacuum layer is added on each side. To set up the same surface with with a hydrogen atom adsorbed in an on-top position 1.5 Å above the top layer: from ase.lattice.surface import *
Note that in this case is is probably not meaningful to use the vacuum keyword to fcc111, as we want to leave 10 Å of vacuum after the adsorbate has been added. Instead, the center() method of the Atoms is used to add the vacuum and center the system. The atoms in the slab will have tags set to the layer number: First layer atoms will have tag=1, second layer atoms will have tag=2, and so on. Adsorbates get tag=0: >>> print atoms.get_tags()
[3 3 3 3 2 2 2 2 1 1 1 1 0]
This can be useful for setting up constraints (see Diffusion of gold atom on Al(100) surface (NEB) ). Utility functions for setting up surfaces
All the functions setting up surfaces take the same arguments. symbol : The chemical symbol of the element to use. size:
A tuple giving the system size in units of the minimal unit cell.
a: (optional) The lattice constant. If specified, it overrides the expermental lattice constant of the element. Must
be specified if setting up a crystal structure different from the one found in nature. c:
(optional) Extra HCP lattice constant. If specified, it overrides the expermental lattice constant of the element. Can be specified if setting up a crystal structure different from the one found in nature and an ideal c/a ratio is not wanted ( c/a = (8/3)1/2 ).
vacuum: The thickness of the vacuum layer. The specified amount of vacuum appears on both sides of the slab.
Default value is None, meaning not to add any vacuum. In that case a “vacuum” layer equal to the interlayer spacing will be present on the upper surface of the slab. Specify vacuum=0.0 to remove it. (optional, not supported by all functions). If specified and true, forces the creation of a unit cell with orthogonal basis vectors. If the default is such a unit cell, this argument is not supported.
orthogonal :
Each function defines a number of standard adsorption sites that can later be used when adding an adsorbate with lattice.surface.add_adsorbate() .
86
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
The following functions are provided ase.lattice.surface. fcc100(symbol, size, a=None, vacuum=0.0 ) ase.lattice.surface. fcc110(symbol, size, a=None, vacuum=0.0 )
These can give both non-orthorhombic and orthorhombic cells:
fcc111
bcc110
bcc111
hcp0001
diamond111
not implemented
The adsorption sites are marked with:
7.9. Creating atomic structures
89
ASE Manual, Release 3.9.0.3484
ontop
hollow
fcc
hcp
bridge
shortbridge
longbridge
If you need other surfaces than the ones above, the easiest is to look in the source file surface.py, and adapt one of the existing functions. Please contribute any such function that you make either by checking it into SVN or by mailing it to the developers. Adding new utility functions
Adding adsorbates
After a slab has been created, a vacuum layer can be added. It is also possible to add one or more adsorbates. ase.lattice.surface. add_adsorbate(slab, adsorbate, height , position=(0, 0), offset=None, mol_index=0)
Add an adsorbate to a surface.
This function adds an adsorbate to a slab. If the slab is produced by one of the utility functions in ase.lattice.surface, it is possible to specify the position of the adsorbate by a keyword (the supported keywords depend on which function was used to create the slab). If the adsorbate is a molecule, the atom indexed by the mol_index optional argument is positioned on top of the adsorption position on the surface, and it is the responsibility of the user to orient the adsorbate in a sensible way. This function can be called multiple times to add more than one adsorbate. Parameters: slab: The surface onto which the adsorbate should be added. adsorbate: The adsorbate. Must be one of the following three types: A
string containing the chemical symbol for a single atom. An atom object. An atoms object (for a molecular adsorbate).
height: Height above the surface. two numbers or as a keyword (if the surface is produced by one of the functions in ase.lattice.surfaces).
position: The x-y position of the adsorbate, either as a tuple of
offset (default: None): Offsets the adsorbate by a number of unit cells.
Mostly useful when adding
more than one adsorbate. mol_index (default: 0): If the adsorbate is a molecule, index of the atom to be positioned above the lo-
cation specified by the position argument. Note position is given in absolute xy coordinates (or as a keyword), whereas offset is specified in unit cells. This can be used to give the positions in units of the unit cell by using offset instead. Create specific non-common surfaces
New in version 3.5.2. In addition to the most normal surfaces, a function has been constructed to create more uncommon surfaces that one could be interested in. It is constructed upon the Miller Indices defining the surface and can be used for both fcc, bcc and hcp structures. The theory behind the implementation can be found here: general_surface.pdf . ase.lattice.surface. surface(lattice, indices, layers, vacuum=0.0 , tol=1e-10)
Create surface from a given lattice and Miller indices. lattice: Atoms object or str Bulk
lattice structure of alloy or pure metal. One can also give the chemical symbol as a string, in which case the correct bulk lattice will be generated automatically.
indices: sequence of three int Surface normal in Miller indices (h,k,l). layers: int
Number of equivalent layers of the slab.
vacuum: float
90
Amount of vacuum added on both sides of the slab. Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Example
To setup a Au(211) surface with 9 layers and 10 Å of vacuum: from ase.lattice.surface import surface
As the last example, creation of alloy surfaces is also very easily carried out with this module. In this example, two Pt3 Rh fcc(211) surfaces will be created: a = 4.0 from ase import Atoms
7.9.6 General crystal structures and surfaces Modules for creating crystal structures are found in the module lattice . Most Bravais lattices are implemented, as are a few important lattices with a basis. The modules can create lattices with any orientation (see below). These modules can be used to create surfaces with any crystal structure and any orientation by later adding a vacuum layer with lattice.surface.add_vacuum() . Example
To set up a slab of FCC copper with the [1,-1,0] direction along the x-axis, [1,1,-2] along the y-axis and [1,1,1] along the z-axis, use: 7.9. Creating atomic structures
The minimal unit cell is repeated 2*2*3 times. The lattice constant is taken from the database of lattice constants in data module. There are periodic boundary conditions along the x and y axis, but free boundary conditions along the z axis. Since the three directions are perpendicular, a (111) surface is created. To set up a slab of BCC copper with [100] along the first axis, [010] along the second axis, and [111] along the third axis use: from ase.lattice.cubic import BodyCenteredCubic
Since BCC is not the natural crystal structure for Cu, a lattice constant has to be specified. Note that since the repeat directions of the unit cell are not orthogonal, the Miller indices of the surfaces will not be the same as the Miller indices of the axes. The indices of the surfaces in this example will be (1,0,-1), (0,1,-1) and (0,0,1). Available crystal lattices
The following modules are currently available (the * mark lattices with a basis): • lattice.cubic – SimpleCubic – FaceCenteredCubic – BodyCenteredCubic – Diamond (*)
• The rhombohedral (or trigonal) lattices are not implemented. They will be implemented when the need arises (and if somebody can tell me the precise definition of the 4-number Miller indices - I only know that they are “almost the same as in hexagonal lattices”). • lattice.compounds Lattices with more than one element. These are mainly intended as examples allowing you to define new such lattices. Currenly, the following are defined – B1 = NaCl = Rocksalt – B2 = CsCl – B3 = ZnS = Zincblende – L1_2 = AuCu3 – L1_0 = AuCu
Usage
The lattice objects are called with a number of arguments specifying e.g. the size and orientation of the lattice. All arguments should be given as named arguments. At a minimum the symbol argument must be specified. symbol The
element, specified by the atomic number (an integer) or by the atomic symbol (i.e. ‘Au’). For compounds, a tuple or list of elements should be given. This argument is mandatory.
directions and/or miller: Specifies
the orientation of the lattice as the Miller indices of the three basis vectors of the supercell (directions=... ) and/or as the Miller indices of the three surfaces (miller=... ). Normally, one will specify either three directions or three surfaces, but any combination that is both complete and consistent is allowed, e.g. two directions and two surface miller indices (this example is slightly redundant, and consistency will be checked). If only some directions/miller indices are specified, the remaining should be given as None. If you intend to generate a specific surface, and prefer to specify the miller indices of the unit cell basis (directions=... ), it is a good idea to give the desired Miller index of the surface as well to allow the module to test for consistency. Example: >>> atoms = BodyCenteredCubic(directions=[[1,-1,0],[1,1,-1],[0,0,1]], miller=[None, None, [1,1,2]], ...) ...
If neither directions nor miller are specified, the default is directions=[[1,0,0], [0,1,0], [0,0,1]] . size: A
tuple of three numbers, defining how many times the fundamental repeat unit is repeated. Default: (1,1,1). Be aware that if high-index directions are specified, the fundamental repeat unit may be large. The lattice constant. If no lattice constant is specified, one is extracted from ASE.ChemicalElements provided that the element actually has the crystal structure you are creating. Depending on the crystal structure, there will be more than one lattice constant, and they are specified by giving a dictionary or a tuple (a scalar for cubic lattices). Distances are given in Angstrom, angles in degrees.
a (a, c) (a, b, c) (a, b, c, α, β , γ ) (a, b, c, alpha) (a, c)
Dictionary-keys
‘a’ ‘a’, ‘c’ or ‘c/a’ ‘a’, ‘b’ or ‘b/a’, ‘c’ or ‘c/a’ ‘a’, ‘b’ or ‘b/a’, ‘c’ or ‘c/a’, ‘alpha’, ‘beta’, ‘gamma’ ‘a’, ‘b’ or ‘b/a’, ‘c’ or ‘c/a’, ‘alpha’ ‘a’, ‘c’ or ‘c/a’
Controls the amount of information printed. 0: no info is printed. 1 (the default): The indices of surfaces and unit cell vectors are printed. 2: Debugging info is printed.
debug:
7.9. Creating atomic structures
95
ASE Manual, Release 3.9.0.3484
Defining new lattices
Often, there is a need for new lattices - either because an element crystallizes in a lattice that is not a simple Bravais lattice, or because you need to work with a compound or an ordered alloy. All the lattice generating objects are instances of a class, you generate new lattices by deriving a new class and instantiating it. This is best explained by an example. The diamond lattice is two interlacing FCC lattices, so it can be seen as a face-centered cubic lattice with a two-atom basis. The Diamond object could be defined like this: from ase.lattice.cubic import FaceCenteredCubicFactory class DiamondFactory(FaceCenteredCubicFactory): """A factory for creating diamond lattices."""
Lattices with more than one element is made in the same way. A new attribute, element_basis , is added, giving which atoms in the basis are which element. If there are four atoms in the basis, and element_basis is (0,0,1,0), then the first, second and fourth atoms are one element, and the third is the other element. As an example, the AuCu3 structure (also known as L12 ) is defined as: # The L1_2 structure is "based on FCC", but is really simple cubic # with a basis.
Sometimes, more than one crystal structure can be used to define the crystal structure, for example the Rocksalt structure is two interpenetrating FCC lattices, one with one kind of atoms and one with another. It would be tempting to define it as class NaClFactory(FaceCenteredCubicFactory):
"A factory for creating NaCl (B1, Rocksalt) lattices." bravais_basis = [[0, 0, 0], [0.5, 0.5, 0.5]] element_basis = (0, 1)
B1 = NaCl = Rocksalt = NaClFactory()
but if this is used to define a finite system, one surface would be covered with one type of atoms, and the opposite surface with the other. To maintain the stochiometry of the surfaces, it is better to use the simple cubic lattice with a larger basis: # To prevent a layer of element one on one side, and a layer of # element two on the other side, NaCl is based on SimpleCubic instead # of on FaceCenteredCubic
ASE contains a number of modules for setting up atomic structures, mainly molecules, bulk crystals and surfaces. Some of these modules have overlapping functionality, but strike a different balance between flexibility and easeof-use. Common bulk crystals
The ase.structure.bulk() function can be used to create the most common bulk crystal structures. The function creates a single unit cell oriented such that the number of atoms in the cell is minimal. Read more: Common bulk crystals . Common surfaces
The lattice.surface module contains a number of functions for creating the most common surfaces in a minimal unit cell, and for adding adsorbates to these surfaces. Read more: Surfaces. Nanotubes and nanoribbons
The functions ase.structure.nanotube() and ase.structure.graphene_nanoribbon() can be used to create Carbon nanotubes and graphene sheets or nanoribbons. Per default, they create Carbon nanotubes and sheets, but other elements can be used. Read more: Nanotubes and Graphene nanoribbons . Generally oriented bulk crystals and surfaces
The lattice module contains functions for creating most common crystal structures with arbitrary orientation. The user can specify the desired Miller index along the three axes of the simulation, and the smallest periodic structure fulfilling this specification is created. Thirteen of the 14 Bravais lattices are supported by the module, as are a few lattices with a basis, and lattices for some of the most common compounds/alloys. The modules makes it possible to define further lattices based on the supported Bravais lattices. Both bulk crystals and surfaces can be created. Read more: General crystal structures and surfaces . Molecules
Some common molecules are available in the molecules module. Read more: Molecules .
7.10 Structure optimization The optimization algorithms can be roughly divided into local optimization algorithms which find a nearby local minimum and global optimization algorithms that try to find the global minimum (a much harder task).
7.10. Structure optimization
97
ASE Manual, Release 3.9.0.3484
7.10.1 Local optimization The local optimization algorithms available in ASE are: BFGS, LBFGS, BFGSLineSearch , LBFGSLineSearch , MDMin, and FIRE. See Also:
Performance test for all ASE local optimizers. MDMin and FIRE both use Newtonian dynamics with added friction, to converge to an energy minimum, whereas
the others are of the quasi-Newton type, where the forces of consecutive steps are used to dynamically update a Hessian describing the curvature of the potential energy landscape. You can use the QuasiNewton synonym for BFGSLineSearch because this algorithm is in many cases the optimal of the quasi-Newton algorithms. All of the local optimizer classes have the following structure: class Optimizer: def __init__(self, atoms, restart=None, logfile=None): def run(self, fmax=0.05, steps=100000000): def get_number_of_steps():
The convergence criterion is that the force on all individual atoms should be less than fmax: a | < f max max |F a
BFGS
The BFGS object is one of the minimizers in the ASE package. The below script uses BFGS to optimize the structure of a water molecule, starting with the experimental geometry: from ase import Atoms from ase.optimize import BFGS from ase.calculators.emt import EMT import numpy as np
d = 0.9575 t = np.pi / 180 * 104.51 water = Atoms(’H2O’, positions=[(d, 0, 0), (d * np.cos(t), d * np.sin(t), 0), (0, 0, 0)], calculator=EMT()) dyn = BFGS(water) dyn.run(fmax=0.05)
which produces the following output. The columns are the solver name, step number, clock time, potential energy (eV), and maximum force.: BFGS: BFGS: BFGS: BFGS: BFGS:
0 1 2 3 4
19:45:25 19:45:25 19:45:25 19:45:25 19:45:25
2.769633 2.154560 1.906812 1.880255 1.879488
8.6091 4.4644 1.3097 0.2056 0.0205
When doing structure optimization, it is useful to write the trajectory to a file, so that the progress of the optimization run can be followed during or after the run: dyn = BFGS(water, trajectory=’H2O.traj’) dyn.run(fmax=0.05)
Use the command ase-gui H2O.traj to see what is going on (more here: gui ). The trajectory file can also be accessed using the module ase.io.trajectory .
98
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
The attach method takes an optional argument interval=n that can be used to tell the structure optimizer object to write the configuration to the trajectory file only every n steps. During a structure optimization, the BFGS and LBFGS optimizers use two quantities to decide where to move the atoms on each step: • the forces on each atom, as returned by the associated Calculator object • the Hessian matrix, i.e. the matrix of second derivatives coordinates.
∂ 2 E ∂x i ∂x j
of the total energy with respect to nuclear
If the atoms are close to the minimum, such that the potential energy surface is locally quadratic, the Hessian and forces accurately determine the required step to reach the optimal structure. The Hessian is very expensive to calculate a priori, so instead the algorithm estimates it by means of an initial guess which is adjusted along the way depending on the information obtained on each step of the structure optimization. It is frequently practical to restart or continue a structure optimization with a geometry obtained from a previous relaxation. Aside from the geometry, the Hessian of the previous run can and should be retained for the second run. Use the restart keyword to specify a file in which to save the Hessian: dyn = BFGS(atoms=system, trajectory=’qn.traj’, restart=’qn.pckl’)
This will create an optimizer which saves the Hessian to qn.pckl (using the Python pickle module) on each step. If the file already exists, the Hessian will also be initialized from that file. The trajectory file can also be used to restart a structure optimization, since it contains the history of all forces and positions, and thus whichever information about the Hessian was assembled so far: dyn = BFGS(atoms=system, trajectory=’qn.traj’) dyn.replay_trajectory(’history.traj’)
This will read through each iteration stored in history.traj , performing adjustments to the Hessian as appropriate. Note that these steps will not be written to qn.traj. If restarting with more than one previous trajectory file, use ase-gui to concatenate them into a single trajectory file first: $ ase-gui part1.traj part2.traj -o history.traj
The file history.traj will then contain all necessary information. When switching between different types of optimizers, e.g. between BFGS and LBFGS, the pickle-files specified by the restart keyword are not compatible, but the Hessian can still be retained by replaying the trajectory as above. LBFGS
LBFGS is the limited memory version of the BFGS algorithm, where the inverse of Hessian matrix is updated instead of the Hessian itself. Two ways exist for determining the atomic step: Standard LBFGS and LBFGSLineSearch . For the first one, both the directions and lengths of the atomic steps are determined by the approximated Hessian matrix. While for the latter one, the approximated Hessian matrix is only used to find out the directions of the line searches and atomic steps, the step lengths are determined by the forces. To start a structure optimization with LBFGS algorithm is similar to BFGS. A typical optimization should look like: dyn = LBFGS(atoms=system, trajectory=’lbfgs.traj’, restart=’lbfgs.pckl’)
where the trajectory and the restart save the trajectory of the optimization and the vectors needed to generate the Hessian Matrix. FIRE
Read about this algorithm here: Erik Bitzek, Pekka Koskinen, Franz Gähler, Michael Moseler, and Peter Gumbsch 7.10. Structure optimization
The MDmin algorithm is a modification of the usual velocity-Verlet molecular dynamics algorithm. Newtons second law is solved numerically, but after each time step the dot product between the forces and the momenta is checked. If it is zero, the system has just passed through a (local) minimum in the potential energy, the kinetic energy is large and about to decrease again. At this point, the momentum is set to zero. Unlike a “real” molecular dynamics, the masses of the atoms are not used, instead all masses are set to one. The MDmin algorithm exists in two flavors, one where each atom is tested and stopped individually, and one where all coordinates are treated as one long vector, and all momenta are set to zero if the dot product between the momentum vector and force vector (both of length 3N) is zero. This module implements the latter version. Although the algorithm is primitive, it performs very well because it takes advantage of the physics of the problem. Once the system is so near the minimum that the potential energy surface is approximately quadratic it becomes advantageous to switch to a minimization method with quadratic convergence, such as Conjugate Gradient or Quasi Newton. SciPy optimizers
SciPy provides a number of optimizers. An interface module for a couple of these have been written for ASE. Most notable are the optimizers SciPyFminBFGS and SciPyFminCG. These are called with the regular syntax and can be imported as: from ase.optimize.sciopt import SciPyFminBFGS, SciPyFminCG
class ase.optimize.sciopt. SciPyFminBFGS(atoms, logfile=’-‘, trajectory=None , callback_always=False , alpha=70.0 )
Quasi-Newton method (Broydon-Fletcher-Goldfarb-Shanno) Initialize object Parameters: callback_always: book
Should the callback be run after each force call (also in the linesearch)
Initial guess for the Hessian (curvature of energy surface). A conservative value of 70.0 is the default, but number of needed steps to converge might be less if a lower value is used. However, a lower value also means risk of instability.
alpha: float
class ase.optimize.sciopt. SciPyFminCG(atoms, logfile=’-‘, trajectory=None , callback_always=False , alpha=70.0 )
Non-linear (Polak-Ribiere) conjugate gradient algorithm Initialize object Parameters: callback_always: book
Should the callback be run after each force call (also in the linesearch)
Initial guess for the Hessian (curvature of energy surface). A conservative value of 70.0 is the default, but number of needed steps to converge might be less if a lower value is used. However, a lower value also means risk of instability.
alpha: float
See Also:
SciPyFminBFGS, SciPyFminCG
100
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
BFGSLineSearch
BFGSLineSearch is the BFGS algorithm with a line search mechanism that enforces the step taken fulfills the Wolfe conditions, so that the energy and absolute value of the force decrease monotonically. Like the LBFGS algorithm the inverse of the Hessian Matrix is updated. The usage of BFGSLineSearch algorithm is similar to other BFGS type algorithms. A typical optimization should look like: from ase.optimize.bfgslinesearch import BFGSLineSearch
where the trajectory and the restart save the trajectory of the optimization and the information needed to generate the Hessian Matrix. In many of the examples, tests, exercises and tutorials, QuasiNewton is used – it is a synonym for BFGSLineSearch . Note:
The BFGSLineSearch algorithm is not compatible with nudged elastic band calculations.
7.10.2 Global optimization There are currently two global optimisation algorithms available. Basin hopping
The global optimization algorithm can be used quite similar as a local optimization algorithm: from ase import * from ase.optimize.basin import BasinHopping # the system to optimize bh = BasinHopping(atoms=system, temperature=100 * kB, # ’temperature’ to overcome barriers # maximal stepwidth dr=0.5, # optimizer to find local minima optimizer=LBFGS, # maximal force for the optimizer fmax=0.1, )
Read more about this algorithm here: David J. Wales and Jonathan P. K. Doye Global Optimization by Basin-Hopping and the Lowest Energy Structures of Lennard-Jones Clusters Containing up to 110 Atoms J. Phys. Chem. A, Vol. 101 , 5111-5116 (1997) and here: David J. Wales and Harold A. Scheraga Global Optimization of Clusters, Crystals, and Biomolecules Science, Vol. 285 , 1368 (1999) Minima hopping
The minima hopping algorithm was developed and described by Goedecker: Stefan Goedecker Minima hopping: An efficient search method for the global minimum of the potential energy surface of complex molecular systems 7.10. Structure optimization
101
ASE Manual, Release 3.9.0.3484
J. Chem. Phys., Vol. 120 , 9911 (2004) This algorithm utilizes a series of alternating steps of NVE molecular dynamics and local optimizations, and has two parameters that the code dynamically adjusts in response to the progress of the search. The first parameter is the initial temperature of the NVE simulation. Whenever a step finds a new minimum this temperature is decreased; if the step finds a previously found minimum the temperature is increased. The second dynamically adjusted parameter is E diff , which is an energy threshold for accepting a newly found minimum. If the new minimum is no more than E diff eV higher than the previous minimum, it is acccepted and E diff is decreased; if it is more than E diff eV higher it is rejected and E diff is increased. The method is used as: from ase.optimize.minimahopping import MinimaHopping
This will run the algorithm until 10 steps are taken; alternatively, if totalsteps is not specified the algorithm will run indefinitely (or until stopped by a batch system). A number of optional arguments can be fed when initializing the algorithm as keyword pairs. The keywords and default values are: T0: 1000., # K, initial MD ‘temperature’ beta1: 1.1, # temperature adjustment parameter beta2: 1.1, # temperature adjustment parameter beta3: 1. / 1.1, # temperature adjustment parameter Ediff0: 0.5, # eV, initial energy acceptance threshold alpha1 : 0.98, # energy threshold adjustment parameter alpha2 : 1. / 0.98, # energy threshold adjustment parameter mdmin : 2, # criteria to stop MD simulation (no. of minima) logfile : ‘hop.log’, # text log minima_threshold : 0.5, # A, threshold for identical configs timestep : 1.0, # fs, timestep for MD simulations optimizer : QuasiNewton, # local optimizer to use minima_traj : ‘minima.traj’, # storage file for minima list
Specific definitions of the alpha, beta, and mdmin parameters can be found in the publication by Goedecker. minima_threshold is used to determine if two atomic configurations are identical; if any atom has moved by more than this amount it is considered a new configuration. Note that the code tries to do this in an intelligent manner: atoms are considered to be indistinguishable, and translations are allowed in the directions of the periodic boundary conditions. Therefore, if a CO is adsorbed in an ontop site on a (211) surface it will be considered identical no matter which ontop site it occupies. The trajectory file minima_traj will be populated with the accepted minima as they are found. A log of the progress is kept in logfile. The code is written such that a stopped simulation (e.g., killed by the batching system when the maximum wall time was exceeded) can usually be restarted without too much effort by the user. In most cases, the script can be resubmitted without any modification – if the logfile and minima_traj are found, the script will attempt to use these to resume. (Note that you may need to clean up files left in the directory by the calculator, however, such as the .nc file produced by Jacapo.) Note that these searches can be quite slow, so it can pay to have multiple searches running at a time. Multiple searches can run in parallel and share one list of minima. (Run each script from a separate directory but specify the location to the same absolute location for minima_traj ). Each search will use the global information of the list of minima, but will keep its own local information of the initial temperature and E diff . For an example of use, see the Constrained minima hopping (global optimization) tutorial.
In read mode, the file is opened opened on all nodes. In write and append mode, mode, the file is opened on the master only, and /dev/null is opened on all other nodes. ase.parallel. parprint(*args, **kwargs)
MPI-safe print - prints only from master. Tries to adopt python 3 behaviour. behaviour.
7.12 Visu Visualiza alization tion visualize. view(atoms, data=None, viewer=None, repeat=None)
This provides an interface to various visualization tools, such as ase.gui, ase.visualize.vtk , RasMol RasMol,, VMD,, VTK VMD VTK,, gOpenMol gOpenMol,, or Avogadro or Avogadro.. The default viewer is the ase.gui, described in the gui modul module. e. The simplest invocation is: >>> from ase import view >>> view(atoms)
where atoms is any Atoms object. object. Alternati Alternative ve viewers viewers can be used by specifying specifying the optional keyword keyword ‘ase.gui’, ‘gopenmol’, ‘gopenmol’, ‘vmd’, or ‘rasmol’. The VMD and Avogadr Avogadroo viewers viewers can viewer=... - use one of ‘ase.gui’, take an optional data argument to show 3D data, such as charge density: >>> view(atoms, view(atoms, viewer viewer =’VMD’ ’VMD’, , data data= =array)
If you do not wish to open an interactive gui, but rather visualize your structure by dumping directly to a graphics file; you can use the write command of the io module, which can write ‘eps’, ‘png’, and ‘pov’ files directly, like this: >>> write(’image.png’ write(’image.png’, , atoms) atoms)
7.12.1 7.12 .1 VTK The Visualization Toolkit (VTK (VTK)) is a powerful platform-independent graphics engine, which comes as an open source graphics toolkit licensed under the BSD the BSD license. license. It is available for a wide range of programming languages, including easily scriptable interfaces in Python and Tcl and Tcl.. In the scientific community, VTK is used by thousands of researchers and developers for 3D computer graphics, image processing, processing, and visualization. visualization. VTK includes includes a suite of 3D interactio interactionn widgets within the developm development ent framework for information visualization, integrating GUI toolkits such as Qt as Qt and and Tk Tk into into a highly flexible design platform. For visualization purposes within ASE, two different VTK-approaches are supported, namely: Scripted on-the-fly rendering ASE
includes VTK-scripting for easy data visualization using the
the latest development development vtk module. Development is in progress, so you might want to check out the release from SVN (see Latest development release ). Interactive rendering MayaVi is MayaVi is an easy-to-use GUI for VTK.
With Enthought’s Enthought’s traits-based VTKwrapper (TVTK (TVTK)), constructing VTK pipelines has been simplified greatly by introducing three basic concepts: data sources, filters and visualization modules. MayaVi also supports the VTK file formats, including the flexible VTK XML, which in ASE can be used to export atomic positions, forces and volume data using the write command in the io module.
A key feature of VTK is the inherent ability to use MPI use MPI for parallel rending, which is provided with built-in parallel composite rendering objects to handle domain decomposition and subsequent recombination of the raster information information.. This is particular particularly ly useful for non-interacti non-interactive ve ray tracing, tracing, batch batch isosurface isosurface generation generation and in-situ in-situ visualization of simulation data in cluster computing. See Also:
7.12. Visualization
103
ASE Manual, Release 3.9.0.3484
ParaView is a VTK-based open-source, multi-platform data analysis and visualization application for extremely ParaView is large data-sets using distributed memory computing resources and parallel rendering through MPI through MPI..
7.12.2 7.12 .2 PrimiP PrimiPlotte lotterr The PrimiPlotter is intended to do on-the-fly plotting of the positions of the atoms during long molecular dynamics simulations. The module ase.visualize.primiplotter contains the PrimiPlotter and the various output modules, see below. class ase.visualize.primiplotter. PrimiPlotter(atoms, verbose=0, timing=0, interval=1, initframe=0)
Primitive PostScript-based plots during a simulation.
The PrimiPlotter plots atoms during simulations, extracting the relevant information from the list of atoms. It is created using the list of atoms as an argument to the constructor. Then one or more output devices must be attached using set_output(device). The list of supported output devices is at the end. The atoms are plotted as circles. The system is first rotated using the angles specified by set_rotation([vx, vy, vy, vz]). The rotation is vx degrees around the x axis (positive from the y toward the z axis), then vy degrees around around the y axis (from x toward z), then vz degrees degrees around the z axis (from x toward y). The rotation rotation matrix is the same as the one used by RasMol. Per default, the system is scaled so it fits within the canvas (autoscale mode). Autoscale mode is enabled and disables using autoscale(“on”) or autoscale(“off”). A manual scale factor can be set with set_scale(scale), this implies implies autoscale(“of autoscale(“off”). f”). The scale factor factor (from the last autoscale autoscale event or from set_scale) set_scale) can be obtained with get_scale(). Finally, Finally, an explicit autoscaling can be triggered with autoscale(“now”), autoscale(“now”), this is mainly useful before calling get_scale or before disabling further autoscaling. Finally, Finally, a relative scaling factor can be set with SetRelativeScaling(), it is multiplied to the usual scale factor (from autoscale or from set_scale). This is probably only useful in connection with autoscaling. The radii of the atoms are obtained from the first of the following methods which work: 1.If the radii are specified specified using PrimiPlotter PrimiPlotter.set_ .set_radii( radii(r), r), they are used. Must be an array, array, or a single single number. 2.If the atoms has a get_atomic_radii() method, it is used. This is unlikely. 3.If the atoms has a get_atomic_numbers() method, the corresponding covalent radii are extracted from the ASE.ChemicalElements module. 4.If all else fails, the radius is set to 1.0 Angstrom. The atoms are colored using the first of the following methods which work. 1.If colors are explicitly set using PrimiPlotter.set_colors(), they are used. 2.If these colors are specified as a dictionary, the tags (from atoms.get_tags()) are used as an index into the dictionary to get the actual colors of the atoms. 3.If a color function has been set using PrimiPlotter.set_color_function(), it is called with the atoms as an argument, and is expected to return an array of colors. 4.If the atoms have a get_colors() method, it is used to get the colors. 5.If these colors are specified as a dictionary, the tags (from atoms.get_tags()) are used as an index into the dictionary to get the actual colors of the atoms. 6.If all else fails, the atoms will be white. The colors are specified as an array of colors, one color per atom. Each color is either a real number from 0.0 to 1.0, specifying a grayscale (0.0 = black, 1.0 = white), or an array of three numbers from 0.0 to 1.0, specifying RGB values. The colors of all atoms are thus a Numerical Python N-vector or a 3xN matrix. In cases 1a and 3a above, the keys of the dictionary are integers, and the values are either numbers (grayscales) or 3-vectors (RGB values), or strings with X11 color names, which are then translated to RGB values. Only in case 1a and 3a are strings recognized as colors.
104
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Some Some atoms atoms may be invis invisibl ible, e, and thus thus left left out of the plot. plot. Invisi Invisible ble atoms atoms are determ determine inedd from from the follo followin wingg algorithm. algorithm. Unlike Unlike the radius radius or the coloring, coloring, all points below are tried and if an atom is invisible invisible by any criterion, it is left out of the plot. 1.All atoms are visible. 2.If PrimiPlotter.set_invisible() has be used to specify invisible atoms, any atoms for which the value is non-zero becomes invisible. 3.If an invisiblility function has been set with PrimiPlotter.set_invisibility_function(), it is called with the atoms as argument. argument. It is expected expected to return an integer per atom, any non-zero value value makes that atom invisible. 4.If a cut has been specified using set_cut, any atom outside the cut is made invisible. Note that invisible atoms are still included in the algorithm for positioning and scaling the plot. The following output devices are implemented. PostScriptFile(prefix): Create PS files names prefix0000.ps etc. PnmFile(prefix): Similar, but makes PNM files. GifFile(prefix): Similar, but makes GIF files. JpegFile(prefix): Similar, but makes JPEG files. X11Window(): Show the plot in an X11 window using ghostscript. Output devices writing to files take an extra optional argument to the constructor, compress, specifying if the output file should be gzipped. This is not allowed for some (already compressed) file formats. Instead of a filename prefix, a filename containing a % can be used. In that case the filename is expected to expand to a real filename when used with the Python string formatting operator (%) with the frame number as argument. Avoid generating spaces in the file names: use e.g. %03d instead of %3d. Parameters to the constructor: atoms: The atoms to be plottet. verbose = 0: Write progress information to stderr. timing = 0: Collect timing information. interval = 1: If specified, a plot is only made every interval’th time update() is called. Deprecated, normally you should use the interval argument when attaching the plotter to e.g. the dynamics. initframe = 0: Initial frame number, i.e. the number of the first plot. log(message)
logs a message to the file set by set_log. plot()
Create a plot now. Does not respect the interval timer. This method makes makes a plot unconditio unconditionally nally.. It does not look at the interval interval variable, variable, nor is this plot taken into account in the counting done by the update() method if an interval variable was specified. set_color_function(colors)
Set a color function, to be used to color the atoms. set_colors(colors)
Explicitly set the colors of the atoms. The colors can either be a dictionary mapping tags to colors or an array of colors, one per atom. Each color is specified as a greyscale value from 0.0 to 1.0 or as three RGB values from 0.0 to 1.0. set_dimensions(dims)
Set the size of the canvas (a 2-tuple).
7.12. Visualization
105
ASE Manual, Release 3.9.0.3484
set_invisibility_function(invfunc )
Set an invisibility function. set_invisible(inv)
Choose invisible atoms. set_log(log)
Sets a file for logging. log may be an open file or a filename. set_output(device )
Attach an output device to the plotter. set_radii(radii)
Set the atomic radii. Give an array or a single number. set_rotation(rotation)
Set the rotation angles (in degrees). update(newatoms=None)
Cause a plot (respecting the interval setting). update causes a plot to be made. If the interval variable was specified when the plotter was create, it will only produce a plot with that interval. update takes an optional argument, newatoms, which can be used to replace the list of atoms with a new one.
7.12.3 7.12 .3 Field FieldPlotte Plotterr The FieldPlotter is intended to plot fields defined on the atoms in large-scale simulations. The fields could be e.g. pressure, stress or temperature (kinetic energy), i.e. any quantity that in a given simulation is best defined on a per-atom basis, but is best interpreted as a continuum field. The current version of FieldPlotter only works if the number of atoms is at least 5-10 times larger than the number of pixels in the plot. class ase.visualize.fieldplotter. FieldPlotter(atoms, datasource=None, verbose=0, timing=0, interval=1 , initframe=0) log(message)
logs a message to the file set by set_log. plot(data=None)
Create a plot now. Does not respect the interval timer. This method makes makes a plot unconditio unconditionally nally.. It does not look at the interval interval variable, variable, nor is this plot taken into account in the counting done by the update() method if an interval variable was specified. If data is specified, it must be an array of numbers with the same length as the atoms. That data will then be plotted. If no data is given, the data source specified when creating the plotter is used. set_background (value)
Set the data value of the background. See also set_background_color Set the value of the background (parts of the plot without atoms) to a specific value, or to ‘min’ or ‘max’ representing the minimal or maximal data values on the atoms. Calling set_background cancels previous calls to set_background_color. set_background_color. set_background_color(color )
Set the background color. See also set_background. Set the background color. color. Use a single value in the range [0, 1[ for gray values, or a tuple of three such values as an RGB color. color. Calling set_background_color cancels previous calls to set_background. s et_background.
106
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
set_black_white_colors(reverse=False )
Set the color to Black-White (greyscale) set_color_function(colors)
Set a color function, to be used to color the atoms. set_data_range(range1 , range2=None )
Set the range of the data used when coloring. This function sets the range of data values mapped unto colors in the final plot. Three possibilities: ‘data’: Autoscale using the data on visible atoms. The
range goes from the lowest to the highest value present on the atoms. If only a few atoms have extreme values, the entire color range may not be used on the plot, as many values may be averaged on each point in the plot.
this ‘plot’: Autoscale using the data on the plot. Unlike ‘data’ this
guaran guarantee teess that that the entire entire color color
range is used. min, max: Use the range [min, max] set_dimensions(dims)
Set the size of the canvas (a 2-tuple). set_invisibility_function(invfunc )
Set an invisibility function. set_invisible(inv)
Choose invisible atoms. set_log(log)
Sets a file for logging. log may be an open file or a filename. set_output(device )
Attach an output device to the plotter. set_plot_plane( plane)
Set the plotting plane to xy, xz or yz (default: xy) set_radii(radii)
Set the atomic radii. Give an array or a single number. set_red_yellow_colors(reverse=False)
Set colors to Black-Red-Yellow-White Black-Red-Yellow-White (a.k.a. STM colors) set_rotation(rotation)
Set the rotation angles (in degrees). update(newatoms=None)
Cause a plot (respecting the interval setting). update causes a plot to be made. If the interval variable was specified when the plotter was create, it will only produce a plot with that interval. update takes an optional argument, newatoms, which can be used to replace the list of atoms with a new one.
7.13 ASE-V ASE-VTK TK For ASE, the vtk interface consists of Python modules for automatic visualization of positions, bonds, forces and volume data (e.g. wave functions) from an Atoms object, provided such data is made available by the calculator. calculator. The Python modules in ASE are intended to wrap lower-leve lower-levell functionality of the VTK object models in small and easy-to-co easy-to-compreh mprehend end classes. classes. To be able to distinguish distinguish between build-in build-in VTK objects and their wrappers, and because VTK uses the CamelCase naming convention whereas ASE uses lower-case lower-case cf. our coding Note:
7.13. ASE-VTK
107
ASE Manual, Release 3.9.0.3484
conventions , all variables referring to VTK built-in types
are prefixed by vtk_ . However, However, both VTK and wrapper classes are named according to the standard vtkFooBar.
7.13.1 Representing atoms class ase.visualize.vtk.atoms. vtkAtoms(atoms, scale=1)
Bases: ase.visualize.vtk.module.vtkModuleAnchor , ase.visualize.vtk.grid.vtkAtomicPositi Provides fundamental representation for Atoms-specific data in VTK. The vtkAtoms class plots atoms during simulations, extracting the relevant information from the list of atoms. It is created using the list of atoms as an argument to the constructor. Then one or more visualization modules can be attached using us ing add_module(name, module). Example: >>> va = vtkAtoms(atoms) >>> va. va.add_forces() va.add_axes() >>> va. XXX va. va.add_to_renderer(vtk_ren) >>> XXX
Construct a fundamental VTK-representation of atoms. atoms: Atoms object or list of Atoms objects The atoms to be plotted. scale scale = 1: float or int
Relative scaling of all Atoms-specific visualization. visualization.
add_axes()
Add an orientation indicator for the cartesian axes. An appropriate vtkAxesModule is added to the module anchor under axes. add_cell()
Add a box outline of the cell using atoms.get_cell(). The existing vtkUnitCellModule is added to the module anchor under cell. add_forces()
Add force vectors vectors for the atoms using atoms.get_for atoms.get_forces(). ces(). A vtkGlyphModule is added to the module anchor under force. add_velocities()
Add velocity vectors for the atoms using atoms.get_velocities(). A vtkGlyphModule is added to the module anchor under velocity. Atom-centered data
The superclass vtkAtomicPositions implements the basic concepts for representing atomic-centered data in VTK. class ase.visualize.vtk.grid. vtkAtomicPositions( pos, cell)
Provides an interface for adding Atoms-centered -centered data to VTK modules. Atomic Atomic positions, positions, e.g. obtained obtained using atoms.get_p atoms.get_positio ositions(), ns(), constitute constitute an unstructure unstructuredd grid in VTK, to which scalar scalar and and vector vector can be added added as point data sets. Just like Atoms, instances of vtkAtomicPositions can be divided into subsets, which makes it easy to select atoms and add properties. Example: >>> cell = vtkUnitCellModule(atoms) >>> apos = vtkAtomicPositions(atoms. vtkAtomicPositions(atoms.get_positions(), cell) >>> apos. apos.add_scalar_property(atoms add_scalar_property(atoms. .get_charges(), ’charges’) ’charges’) >>> apos. apos.add_vector_property(atoms add_vector_property(atoms. .get_forces(), ’forces’) ’forces’)
108
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Construct basic VTK-representation of a set of atomic positions. pos: NumPy array of dtype float and shape (n,3) Cartesian positions of the atoms. cell: Instance of vtkUnitCellModule of subclass thereof
Add VTK-representation of vector data at the atomic positions. data: NumPy array of dtype float and shape (n,3) Vector
components corresponding to the
atomic positions. name=None: str Unique identifier for the vector data. active=True: bool
Flag indicating whether to use as active vector data.
get_points(subset=None)
Return (subset of) vtkPoints containing atomic positions. subset=None: list of int
A list of indices into the atomic positions; ignored if None.
get_unstructured_grid (subset=None)
Return (subset of) an unstructured grid of the atomic positions. subset=None: list of int
A list of indices into the atomic positions; ignored if None.
Predefined shapes
The class vtkGlyphModule implements the lower-level objects for representing predefined shapes (glyphs) in VTK. class ase.visualize.vtk.module. vtkGlyphModule(vtk_pointset , glyph_source, scalemode=None, colormode=None )
Modules represent a unified collection of VTK objects needed for introducing basic visualization concepts such as surfaces or shapes. A common trait of all modules is the need for an actor representation and corresponding generic properties such as lighting, color and transparency. Poly data modules are based on polygonal data sets, which can be mapped into graphics primitives suitable for rendering within the VTK framework. Glyph modules construct these polygonal data sets by replicating a glyph source across a specific set of points, using available scalar or vector point data to scale and orientate the glyph source if desired. Example: >>> atoms = molecule(’C60’) >>> cell = vtkUnitCellModule(atoms) >>> apos = vtkAtomicPositions(atoms.get_positions(), cell) >>> vtk_ugd = apos.get_unstructured_grid() >>> glyph_source = vtkAtomSource(’C’) >>> glyph_module = vtkGlyphModule(vtk_ugd, glyph_source)
Construct VTK-representation of a module containing glyphs. These glyphs share a common source, defining their geometrical shape, which is cloned and oriented according to the input data.
7.13. ASE-VTK
109
ASE Manual, Release 3.9.0.3484
vtk_pointset: Instance of vtkPointSet or subclass thereof A
vtkPointSet defines a set of positions, which may then be assigned specific scalar of vector data across the entire set.
glyph_source: Instance of ~vtk.vtkCustomGlyphSource or subclass thereof Provides
the basic shape
to distribute over the point set. get_actor()
Return the actor representing this module in a rendering scene. set_actor(vtk_act )
Set the actor representing this module in a rendering scene. set_property(vtk_property)
Set the property of the actor representing this module.
7.14 Calculators For ASE, a calculator is a black box that can take atomic numbers and atomic positions from an Atoms object and calculate the energy and forces and sometimes also stresses. In order to calculate forces and energies, you need to attach a calculator object to your atoms object: >>> a = read(’molecule.xyz’) >>> e = a.get_potential_energy()
Traceback (most recent call last): File "", line 1, in File "/home/jjmo/ase/ase/atoms.py", line 399, in get_potential_energy raise RuntimeError(’Atoms object has no calculator.’) RuntimeError: Atoms object has no calculator. >>> from ase.calculators.abinit import Abinit >>> calc = Abinit(...) >>> a.set_calculator(calc) >>> e = a.get_potential_energy() >>> print e -42.0
Here, we used the set_calculator() method to attach an instance of the Abinit class and then we asked for the energy. Alternatively, a calculator can be attached like this: atoms = Atoms(..., calculator=Abinit(...))
or this: atoms.calc = Abinit(...)
7.14.1 Supported calculators The calculators can be divided in three groups: 1. Asap, GPAW and Hotbit have their own native ASE interfaces. 2. ABINIT, CASTEP, DFTB+, ELK, EXCITING, FHI-aims, FLEUR, GAUSSIAN, Gromacs, Jacapo, LAMMPS, MOPAC, NWChem, SIESTA, TURBOMOLE and VASP, have Python wrappers in the ASE package, but the actual FORTRAN/C/C++ codes are not part of ASE. 3. Pure python implementations included in the ASE package: EMT, EAM, Lennard-Jones and Morse.
110
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
name
description
Asap GPAW Hotbit
Highly efficient EMT code Real-space/plane-wave/LCAO PAW code DFT based tight binding Plane-wave pseudopotential code Plane-wave pseudopotential code DFT based tight binding Embedded Atom Method Full Potential LAPW code Full Potential LAPW code Numeric atomic orbital, full potential code Full Potential LAPW code Gaussian based electronic structure code Classical molecular dynamics code Plane-wave ultra-soft pseudopotential code Classical molecular dynamics code ... Gaussian based electronic structure code LCAO pseudopotential code Fast atom orbital code Plane-wave PAW code Effective Medium Theory calculator Lennard-Jones potential Morse potential
abinit castep dftb eam
elk exciting FHI-aims fleur
gaussian gromacs jacapo lammps
mopac nwchem siesta turbomole vasp emt
lj morse
The calculators included in ASE are used like this: >>> from ase.calculators.abc import ABC >>> calc = ABC(...)
where abc is the module name and ABC is the class name.
7.14.2 Calculator keywords Example for a hypothetical ABC calculator: ABC(restart=None, ignore_bad_restart_file=False, label=None, atoms=None, parameters=None, command=’abc > PREFIX.abc’, xc=None, kpts=[1, 1, 1], smearing=None, charge=0.0, nbands=None, **kwargs)
Create ABC calculator
restart: str Prefix for restart file. May contain a directory. Default is None: don’t restart. ignore_bad_restart_file: bool Ignore broken or missing restart file. By default, it is an error if the restart
file is missing or broken. label: str
Name used for all files. May contain a directory.
Optional Atoms object to which the calculator will be attached. When restarting, atoms will get its positions and unit-cell updated from file.
• (n1,n2,n3): Monkhorst-Pack grid • (n1,n2,n3,’gamma’) : Shifted Monkhorst-Pack grid that includes Γ • [(k11,k12,k13),(k21,k22,k23),...] : Explicit Explicit list in units of the reciproca reciprocall lattice vectors k-point density as in 3.5 k-points per Å−1 . • kpts=3.5: smearing: tuple The smearing of occupation numbers. Must be a tuple:
• (’Fermi-Dirac’ (’Fermi-Dirac’, , width) • (’Gaussian’, (’Gaussian’, width) • (’Methfessel-Paxt (’Methfessel-Paxton’, on’, width, n) , where n is the order ( n = 0 is the same as ’Gaussian’ ) Lower-case names are also allowed. The width parameter is given in eV units. charge: float Charge
of the system in units of |e| ( charge=1 means one electron has been removed). Default is charge=0.
nbands: int
Number of bands. Each band can be occupied by two electrons.
Not all of the above arguments make sense for all of ASE’s calculators. As an example, Gromacs will not accept DFT related keywords such as xc and smearing . In addition to the keywords mentioned above, each calculator may have native keywords keywords that are specific to only that calculator. Keyword arguments can also be set or changed at a later stage using the set() method: calculators. set(key1=value1 , key2=value2 , ... ) EAM Introduction
The Embedded Atom Method (EAM) 1 is a classical potential which is good for modelling metals, particularly fcc materials. Because it is an equiaxial potential the EAM does not model directional bonds well. However, the Angular Dependent Potential (ADP) 2 which is an extended version of EAM is able to model directional bonds and is also included in the EAM calculator. Generally all that is required to use this calculator is to supply a potential file or as a set of functions that describe the potential. The files containing the potentials for this calculator are not included but many suitable potentials can be downloaded from The Interatomic Potentials Repository Project at http://www http://www.ctcms.nist.gov/potentials/ .ctcms.nist.gov/potentials/ Theory
A single element EAM potential is defined by three functions: the embedded energy, energy, electron density and the pair potential. A two element alloy contains the individual three functions for each element plus cross pair interactions. The ADP potential has two additional sets of data to define the dipole and quadrupole directional terms for each alloy and their cross interactions. The total energy E tot tot of an arbitrary arrangement of atoms is given by the EAM potential as E tot tot =
i
1 2
F ( F (ρ¯i ) +
1 2
φ(rij )
i=j
M.S. Daw and M.I. Baskes, Phys. Rev. Letters 50 (1983) 1285. Y. Mishin, M.J. Mehl, and D.A. Papaconstantopoulos, Acta Materialia 53 2005 4029–4041.
112
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
and ρ¯i =
ρ(rij )
j
where F is an embedding function, namely the energy to embed an atom i in the combined electron density ρ¯i which is contributed from each of its neighbouring atoms j by an amount ρ( ρ (rij ), φ( φ (rij ) is the pair potential function representing the energy in bond ij which is due to the short-range electro-static interaction between atoms, and rij is the distance between an atom and its neighbour for that bond. The ADP potential is defined as E tot tot =
F ( F (ρ¯i ) +
i
1 2
φ(rij ) +
i=j
1 2
(µiα ) 2 +
i,α
1 2
2 (λαβ i ) −
i,α,β
1 6
ν i2
i
λαβ where µiα is the dipole vector, λαβ i is the quadrupole tensor and ν i is the trace of λ i . Running the Calculator
EAM calculates calculates the cohesive cohesive atom energy energy and forces. Internally Internally the potential functions functions are defined defined by splines splines which may be directly supplied or created by reading the spline points from a data file from which a spline function is created. The LAMMPS compatible .alloy and .adp formats are supported. The LAMMPS .eam format is slightly different from the .alloy format and is currently not supported. For example: from ase.calculators.eam from ase.calculators.eam import EAM
The breakdown of energy contribution from the indvidual components are stored in the calculator instance .results[’energy_components’]
7.14. Calculators
113
ASE Manual, Release 3.9.0.3484
Arguments
Keyword
Description
potential file of potential in .alloy or .adp format (This is generally all you need to supply) elements[N] array of N element abbreviations arrays of embedded energy functions embedded_energy[N] arrays of electron density functions electron_density[N] arrays of pair potential functions phi[N,N] d_embedded_energy[N] arrays of derivative derivative embedded energy functions arrays of derivative electron density functions d_electron_density[N] arrays of derivative derivative pair potentials functions d_phi[N,N] ADP dipole and quadrupole function d[N,N], q[N,N] d_d[N,N], ADP dipole and quadrupole derivative derivative functions d_q[N,N] skin distance passed to NeighborList(). If no atom has moved more than the skin-distance skin since the last call to the update() method then the neighbor list can be reused. Defaults form
to 1.0. the form of the potential alloy or adp. This will be determined from the file suffix or must be set if using equations
Additional parameters for writing potential files
The following parameters are only required for writing a potential in .alloy or .adp format file. Keyword
Description
header Z[N] mass[N] a[N] lattice[N] nrho drho nr dr
Three line text header. header. Default is standard message. Array of atomic number of each element Atomic mass of each element Array of lattice parameters for each element Lattice type No. of rho samples along embedded energy curve Increment for sampling density No. of radial points along density and pair potential curves Increment for sampling radius
Special features
Plots the individual functions. This may be called from multiple EAM potentials to compare the shape of the individual curves. This function requires the installation of the Matplotlib libraries.
.plot()
Notes/Issues
• Although Although currently currently not fast, this calculator calculator can be good for trying small calculatio calculations ns or for creating creating new potentials by matching baseline data such as from DFT results. The format for these potentials is compatible with LAMMPS with LAMMPS and and so can be used either directly by LAMMPS or with the ASE LAMMPS calculator interface. • Supported formats are the LAMMPS .alloy and .adp. The .eam format is currently not supported. The form of the potential will be determined from the file suffix. • Any supplied values will override values read from the file. • The derivative derivative functions, if supplied, are only used to calculate forces. • There is a bug in early versions of scipy that that will cause eam.py to crash when trying to evaluate evaluate splines of a potential with one neighbor such as caused by evaluating a dimer. 114
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Example: import numpy as np from ase.calculators.eam from ase.calculators.eam import EAM from ase.lattice import bulk from # test test to ge gene nera rate te an EA EAM M po pote tent ntia ial l fi file le us usin ing g a si simp mpli lifi fied ed # app approx roxima imatio tion n to the Mis Mishin hin pot potent ential ial Al9 Al99.e 9.eam. am.all alloy oy dat data a
from scipy.interpolate import InterpolatedUnivariateSpline as spline from
cutoff = 6.28721 n = 21 rs = np. np.arange(0 arange(0, n) * (cutoff / n) rhos = np. np.arange(0 arange(0, 2, 2. / n) # # # # #
m_density = np. np.array([2.78589606e-01 array([2.78589606e-01, , 2.02694937e-01, 2.02694937e-01, 1.45334053e-01, 1.45334053e-01, 1.06069912e-01, 1.06069912e-01 , 8.42517168e-02, 8.42517168e-02, 7.65140344e-02, 7.65140344e-02, 7.76263116e-02, 7.76263116e-02 , 8.23214224e-02, 8.23214224e-02, 8.53322309e-02, 8.53322309e-02, 8.13915861e-02, 8.13915861e-02 , 6.59095390e-02, 6.59095390e-02, 4.28915711e-02, 4.28915711e-02, 2.27910928e-02, 2.27910928e-02 , 1.13713167e-02, 1.13713167e-02, 6.05020311e-03, 6.05020311e-03, 3.65836583e-03, 3.65836583e-03 , 2.60587564e-03, 2.60587564e-03, 2.06750708e-03, 2.06750708e-03, 1.48749693e-03, 1.48749693e-03 , 7.40019174e-04, 7.40019174e-04, 6.21225205e-05]) 6.21225205e-05]) m_embedded = np. np.array([1.04222211e-10 array([1.04222211e-10, , -1.04142633e+00 1.04142633e+00, , -1.60359806e+00 1.60359806e+00, , -1.89287637e+00 1.89287637e+00, , -2.09490167e+00 2.09490167e+00, , -2.26456628e+00 2.26456628e+00, , -2.40590322e+00 2.40590322e+00, , -2.52245359e+00 2.52245359e+00, , -2.61385603e+00 2.61385603e+00, , -2.67744693e+00 2.67744693e+00, , -2.71053295e+00 2.71053295e+00, , -2.71110418e+00 2.71110418e+00, , -2.69287013e+00 2.69287013e+00, , -2.68464527e+00 2.68464527e+00, , -2.69204083e+00 2.69204083e+00, , -2.68976209e+00 2.68976209e+00, , -2.66001244e+00 2.66001244e+00, , -2.60122024e+00 2.60122024e+00, , -2.51338548e+00 2.51338548e+00, , -2.39650817e+00 2.39650817e+00, , -2.25058831e+00 2.25058831e+00]) ]) m_phi = np. np.array([6.27032242e+01 array([6.27032242e+01, , 3.49638589e+01, 3.49638589e+01, 1.79007014e+01, 1.79007014e+01, 8.69001383e+00, 8.69001383e+00 , 4.51545250e+00, 4.51545250e+00, 2.83260884e+00, 2.83260884e+00, 1.93216616e+00, 1.93216616e+00 , 1.06795515e+00, 1.06795515e+00, 3.37740836e-01, 3.37740836e-01, 1.61087890e-02, 1.61087890e-02 , -6.20816372e-02 6.20816372e-02, , -6.51314297e-02 6.51314297e-02, , -5.35210341e-02 5.35210341e-02, , -5.20950200e-02 5.20950200e-02, , -5.51709524e-02 5.51709524e-02, , -4.89093894e-02 4.89093894e-02, , -3.28051688e-02 3.28051688e-02, , -1.13738785e-02 1.13738785e-02, , 2.33833655e-03, 2.33833655e-03 , 4.19132033e-03, 4.19132033e-03, 1.68600692e-04]) 1.68600692e-04]) m_densityf = spline(rs, spline(rs, m_density) m_embeddedf = spline(rhos, spline(rhos, m_embedded) m_phif = spline(rs, spline(rs, m_phi) m_phi) a = 4.05 # Ang Angstr strom om lat lattic tice e spa spacin cing g al = bulk(’Al’ bulk(’Al’, , ’fcc’, ’fcc’, a=a) mishin_approx = EAM(elements= EAM(elements=[’Al’ ’Al’], ], embedded_e embedded_energy nergy= =np. np.array([m_embeddedf]), electron_density= electron_density=np. np.array([m_densityf]), phi= phi=np. np.array([[m_phif]]), cutoff= cutoff =cutoff, cutoff, form= form=’alloy’ ’alloy’, , # th the e fo foll llow owin ing g te term rms s ar are e on only ly re requ quir ired ed to wr writ ite e ou out t a fi file le
Z=[13 13], ], nr= nr=n, nrho nrho=n, dr= dr=cutoff / n, drho drho= =2. / n, lattice= lattice=[’fcc’ ’fcc’], ], mass mass=[26.982 26.982], ], a=[a])
7.14. Calculators
115
ASE Manual, Release 3.9.0.3484
al. al.set_calculator(mishin_approx) mishin_approx_energy = al. al.get_potential_energy() mishin_approx. mishin_approx.write_potential(’Al99-test.eam.alloy’ write_potential(’Al99-test.eam.alloy’) ) mishin_check = EAM(potential= EAM(potential=’Al99-test.eam.alloy’ ’Al99-test.eam.alloy’) ) al. al.set_calculator(mishin_check) mishin_check_energy = al. al.get_potential_energy() ’Cohes esiv ive e En Ener ergy gy fo for r Al = ’ , mishin_approx_energy, ’ eV eV’ ’ print ’Coh error = (mishin_approx_energy - mishin_check_energy) / mishin_approx_energy print ’read/ ’read/wri write te che check ck err error or = ’ , error error assert abs abs(error) (error) < 1e-4
Pure Python EMT calculator
The EMT potential is included in the ASE package in order to have a simple calculator that can be used for quick demonstrations and tests. Warning: If you want to do a real application using EMT, EMT, you should used the much more efficient implementation in the ASAP the ASAP calculator. calculator. class emt.EMT
Right now, the only supported elements are: H, C, N, O, Al, Ni, Cu, Pd, Ag, Pt and Au. The EMT parameters for the metals are quite realistic for many purposes, whereas the H, C, N and O parameters are just for fun! ABINIT Introduction
ABINIT is ABINIT is a density-functional theory code based on pseudopotentials and a planewave basis. Environment variables
The environment variable ASE_ABINIT_COMMAND must be set to something like this: abinis abinis < PREFIX PREFIX.fi .files les > PREFIX PREFIX.lo .log g
where abinis is the executable. A directory containing the pseudopotential files (at least of .fhi type) is also needed, and it is to be put in the environment variable ABINIT_PP_PATH . Abinit does not provide tarballs of pseudopotentials so the easiest way is to download and unpack http://wiki.fysik.dtu.dk/abinit-files/abinit-pseud http://wiki.fysik.dtu.dk/abinit-files/abinit-pseudopotentials-2.tar opotentials-2.tar.gz .gz Set the environment variables in your in your shell configuration file: export ASE_ABINIT_COMMAND= ASE_ABINIT_COMMAND ="ab "abini inis s < PRE PREFIX FIX.fi .files les > PRE PREFIX FIX.lo .log" g" PP= PP =${HOME}/abinit-pseudopotentials-2 export ABINIT_PP_PATH= ABINIT_PP_PATH=$PP $PP/LDA_FHI /LDA_FHI export ABINIT_PP_PATH= ABINIT_PP_PATH=$PP $PP/GGA_FHI: /GGA_FHI:$ABINIT_PP_PATH $ABINIT_PP_PATH export ABINIT_PP_PATH= ABINIT_PP_PATH=$PP $PP/LDA_HGH: /LDA_HGH:$ABINIT_PP_PATH $ABINIT_PP_PATH export ABINIT_PP_PATH= ABINIT_PP_PATH=$PP $PP/LDA_PAW: /LDA_PAW:$ABINIT_PP_PATH $ABINIT_PP_PATH export ABINIT_PP_PATH= ABINIT_PP_PATH=$PP $PP/LDA_TM: /LDA_TM:$ABINIT_PP_PATH $ABINIT_PP_PATH export ABINIT_PP_PATH= ABINIT_PP_PATH=$PP $PP/GGA_FHI: /GGA_FHI:$ABINIT_PP_PATH $ABINIT_PP_PATH export ABINIT_PP_PATH= ABINIT_PP_PATH=$PP $PP/GGA_HGHK: /GGA_HGHK:$ABINIT_PP_PATH $ABINIT_PP_PATH export ABINIT_PP_PATH= ABINIT_PP_PATH=$PP $PP/GGA_PAW: /GGA_PAW:$ABINIT_PP_PATH $ABINIT_PP_PATH
116
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
ABINIT Calculator
Abinit does not specify a default value for the plane-wave cutoff energy. You need to set them as in the example at the bottom of the page, otherwise calculations will fail. Calculations wihout k-points are not parallelized by default and will fail! To enable band paralellization specify Number of BanDs in a BLOCK (nbdblock ) — see http://www.abinit.org/Infos_v5.2/tutorial/lesson_parallelism.html. Pseudopotentials
Pseudopotentials in the ABINIT format are available on the pseudopotentials website. A database of user contributed pseudopotentials is also available there. Example 1
Here is an example of how to calculate the total energy for bulk Silicon: from ase import * from ase.calculators.abinit import Abinit
CASTEP 3 W is a software package which uses density functional theory to provide a good atomic-level description of all manner of materials and molecules. CASTEP can give information about total energies, forces and stresses on an atomic system, as well as calculating optimum geometries, band structures, optical spectra, phonon spectra and much more. It can also perform molecular dynamics simulations. The CASTEP calculator interface class offers intuitive access to all CASTEP settings and most results. All CASTEP specific settings are accessible via attribute access (i.e. calc.param.keyword = ... or calc.cell.keyword = ...) Getting Started:
Set the environment variables appropriately for your system. 3
S. J. Clark, M. D. Segall, C. J. Pickard, P. J. Hasnip, M. J. Probert, K. Refson, M. C. Payne Zeitschrift für Kristallographie 220(5-6) pp.567- 570 (2005) PDF.
Note: alternatively to CASTEP_PP_PATH one can set PSPOT_DIR as CASTEP consults this by default, i.e. >>> export PSPOT_DIR=’ . . . ’
Running the Calculator
The default initialization command for the CASTEP calculator is class castep.Castep(directory=’CASTEP’, label=’castep’ )
To do a minimal run one only needs to set atoms, this will use all default settings of CASTEP, meaning LDA, singlepoint, etc.. With a generated castep_keywords.py in place all options are accessible by inspection, i.e. tab-completion. This works best when using ipython. All options can be accessed via calc.param. or calc.cell. and documentation is printed with calc.param. ? or calc.cell. ? . All options can also be set directly using calc.keyword = ... or calc.KEYWORD = ... or even calc.KeYwOrD or directly as named arguments in the call to the constructor (e.g. Castep(task=’GeometryOptimization’) ). All options that go into the .param file are held in an CastepParam instance, while all options that go into the .cell file and don’t belong to the atoms object are held in an CastepCell instance. Each instance can be created individually and can be added to calculators by attribute assignment, i.e. calc.param = param or calc.cell = cell . All internal variables of the calculator start with an underscore (_). All cell attributes that clearly belong into the atoms object are blocked. Setting calc.atoms_attribute (e.g. = positions) is sent directly to the atoms object. Arguments:
Keyword
Description
The relative path where all input and output files will be placed. If this does not exist, it will be directory label
118
created. Existing directories will be moved to directory-TIMESTAMP unless self._rename_existing_dir is set to false. The prefix of .param, .cell, .castep, etc. files.
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Additional Settings
Internal Setting
Description
(=castep ): the actual shell command used to call CASTEP. _castep_command (=True): this makes write_param() only write a continue or reuse statement if the _check_checkfile addressed .check or .castep_bin file exists in the directory. _copy_pspots (=False ): if set to True the calculator will actually copy the needed pseudo-potential (*.usp) file, usually it will only create symlinks. (=True): if this is set to True, all calculator internal settings shown here will be included _export_settings in the .param in a comment line (#) and can be read again by merge_param. merge_param can be forced to ignore this directive using the optional argument ignore_internal_keys=True . _force_write (=True ): this controls wether the *cell and *param will be overwritten. (=False ): If set to True, the calculator will create *cell und *param file but not start the _prepare_input_only calculation itself. If this is used to prepare jobs locally and run on a remote cluster it is recommended to set _copy_pspots = True. (=’.’) : the place where the calculator will look for pseudo-potential files. _castep_pp_path (=True) : when using a new instance of the calculator, this will move directories out of _rename_existing_dir the way that would be overwritten otherwise, appending a date string. _set_atoms (=False ) : setting this to True will overwrite any atoms object previously attached to the calculator when reading a .castep file. By de- fault, the read() function will only create a new atoms object if none has been attached and other- wise try to assign forces etc. based on the atom’s positions. _set_atoms=True could be necessary if one uses CASTEP’s internal geometry optimization (calc.param.task=’GeometryOptimization’ ) because then the positions get out of sync. Warning: this option is generally not recommended unless one knows one really needs it. There should never be any need, if CASTEP is used as a single-point calculator. _track_output(=False ) : if set to true, the interface will append a number to the label on all input and output files, where n is the number of calls to this instance. Warning: this setting may consume a lot more disk space because of the additio- nal *check files. (=_track_output ) : when setting this, the in- terface will try to fetch the reuse file _try_reuse from the previous run even if _track_output is True. By de- fault it is equal to _track_output, but may be overridden. Since this behavior may not always be desirable for single-point calculations. Regular reuse for e.g. a geometry-optimization can be achieved by setting calc.param.reuse = True. Special features:
.dryrun_ok() Runs castep_command seed -dryrun in a temporary directory return True if all vari-
ables initialized ok. This is a fast way to catch errors in the input. Afterwards _kpoints_used is set. .merge_param() Takes a filename or filehandler of a .param file or CastepParam instance and merges it into
the current calculator instance, overwriting current settings Can be used on any option like calc.param.keyword.clear() or calc.cell.keyword.clear() to return to the CASTEP default.
.keyword.clear()
.initialize() Creates
all needed input in the _directory . This can then copied to and run in a place without ASE or even python.
.set_pspot(’’) This automatically sets the pseudo-potential for _.usp. Make sure that _castep_pp_path is set correctly.
all present species to
print(calc) Prints a short summary of the calculator settings and atoms.
Given you have a combination of seed.{param,cell,castep} this will return an atoms object with the last ionic positions in the .castep
ase.io.castep.read_seed(’path-to/seed’)
7.14. Calculators
119
ASE Manual, Release 3.9.0.3484
file and all other settings parsed from the .cell and .param file. If no .castep file is found the positions are taken from the .cell file. The output directory will be set to the same directory, only the label is preceded by ‘copy_of_’ to avoid overwriting. Notes/Issues:
• Currently only the FixAtoms constraint is fully supported for reading and writing. • There is no support for the CASTEP unit system . Units of eV and Angstrom are used throughout. In particular when converting total energies from different calculators, one should check that the same CODATA version is used for constants and conversion factors, respectively. Example: """This simple demo calculates the total energy of CO molecules using once LDA and once PBE as xc-functional. Obviously some parts in this scripts are longer than necessary, but are shown to demonstrate some more features."""
import ase import ase.calculators.castep , ase.io.castep
calc = ase.calculators.castep.Castep() directory = ’CASTEP_ASE_DEMO’ # include interface settings in .param file
calc. _export_settings = True # reuse the same directory
calc. _directory = directory calc. _rename_existing_dir = False calc. _label = ’CO_LDA’ # necessary for tasks with changing positions # such as GeometryOptimization or MolecularDynamics
if calc.dryrun_ok(): print(’%s : %s ’ % (mol.calc. _label, mol.get_potential_energy())) else: print("Found error in input") print(calc. _error)
# Read all settings from previous calculation mol = ase.io.castep.read_seed(’%s/CO_LDA’ % directory) # Use the OTF pseudo-potential we have just generated
mol.calc.set_pspot(’OTF’) # Change some settings
mol.calc.param.xc_functional = ’PBE’ # don’t forget to set an appropriate label
mol.calc. _label = ’CO_PBE’ # Recalculate the potential energy print(’%s : %s ’ % (mol.calc. _label, mol.get_potential_energy()))
DftbPlus Introduction
DftbPlus is a density-functional based tight-binding code using atom centered orbitals. This interface makes it possible to use DftbPlus as a calculator in ASE. You need to register at DftbPlus site to download the code. Additionally you need Slater-Koster files for the combination of atom types of your system. These can be obtained at dftb.org. Environment variables
Set environment variables in your configuration file (what is the directory for the Slater-Koster files and what is the name of the executable): • bash: $ DFTB_PREFIX=/my_disk/my_name/lib/Dftb+sk/mio-0-1/ $ DFTB_COMMAND=~/bin/DFTB+/dftb+_s081217.i686-linux
The file ‘geom.out.gen’ contains the input and output geometry and it will be updated during the dftb calculations. it is assumed that a new input file ‘dftb_hsd.in’ will be written by ase using default keywords and the ones given by the user.
If restart == None
If restart != None it is assumed that keywords are in file restart
All Keywords to the dftb calculator can be set by ase. 7.14. Calculators
121
ASE Manual, Release 3.9.0.3484
Parameters
If restart == None it is assumed that a new input file ‘dftb_hsd.in’ will be written by ase using default keywords and the ones given by the user.
restart: str
If restart != None it is assumed that keywords are in file ‘restart’ ignore_bad_restart_file: bool Ignore
broken or missing restart file. By defauls, it is an error if the
restart file is missing or broken. label: str
Name used for all files. May contain a directory.
Optional Atoms object to which the calculator will be attached. When restarting, atoms will get its positions and unit-cell updated from file.
atoms: Atoms object
kpts: Brillouin zone sampling:
• (1,1,1): Gamma-point • (n1,n2,n3) : Monkhorst-Pack grid • (n1,n2,n3,’gamma’) : Shifted Monkhorst-Pack grid that includes Γ • [(k11,k12,k13),(k21,k22,k23),...] : Explicit list in units of the reciprocal lattice vectors k-point density as in 3.5 k -points per Å−1 . • kpts=3.5: Example: Geometry Optimization import os from ase import Atoms from ase.calculators.dftb import Dftb from ase.optimize import QuasiNewton from ase.io import write from ase.data.molecules import molecule
exciting is a full-potential all-electron density-functional-theory ( DFT ) package based on the linearized aug-
mented planewave ( LAPW ) method. It can be applied to all kinds of materials, irrespective of the atomic species involved, and also allows for the investigation of the core region. The website is http://exciting-code.org/ The module depends on lxml http://lxml.de 122
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
There are two ways to construct the exciting calculator. 1. Using keyword arguments to specify groundstate attributes 2. Use paramdict to specify an input file structure with a data structure of dictionaries. One is by giving parameters of the ground state in the constructor. The possible attributes can be found at http://exciting-code.org/ref:groundstate Constructor with Groundstate Keywords
class exciting.Exciting(bin=’excitingser’, kpts=(4, 4 , 4) , xctype=’LDA_PW’ )
When the paramdict keyword is used, the calculator translates the dictionary given into the exciting XML file format. Note $EXCITINGROOT environmental variable should be set: details at http://exciting-code.org/tutorials Parameter Dictionary
import os from ase import Atoms from ase.calculators.exciting import Exciting # test structure, not real
The translation follows the following rules: String values are translated to attributes. Nested dictionaries are translated to sub elements. A list of dictionaries is translated to a list of sub elements named after the key of which the list is the value. The special key “text()” results in text content of the enclosing tag. Muffin Tin Radius
Sometimes it is necessary to specify a fixed muffin tin radius different from the default. The muffin tin radii can be set by adding a custom array to the atoms object with the name “rmt”: atoms.new_array(’rmt’, np.array([-1.0, -1.0, 2.3, 2.0] * Bohr))
Each entry corresponds to one atom. If the rmt value is negative, the default value is used. This array is correctly updated if the atoms are added or removed. Exciting Calculator Class
paramdict: dict Dictionary containing XML parameters. String values are translated to attributes, nested
dictionaries are translated to sub elements. A list of dictionaries is translated to a list of sub elements named after the key of which the list is the value. default: None speciespath: string Directory or URL to look up species files bin: string
Path or executable name of exciting
default: excitingser kpts: integer list length 3 Number kwargs: dictionary like
of k-points
list of key value pairs to be converted into groundstate attributes
FHI-aims Introduction
FHI-aims is a all-electron full-potential density functional theory code using a numeric local orbital basis set. This 124
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
interface provides all that should be required to run FHI-aims from within ASE. Running the Calculator
The default initialization command for the FHI-aims calculator is class FHI-aims. Aims(output_template = ‘aims’ , track_output = False )
In order to run a calculation, you have to ensure that at least the following str variables are specified, either in the initialization or as shell variables: keyword
description
The full command required to run FHI-aims from a shell, including anything to do with an MPI run_command wrapper script and the number of tasks. An alternative way to set this command is via the shell variable AIMS_COMMAND , which is checked upon initialization and when starting a run. Directory where the species defaults are located that should be used. Can also be specified with species_dir the system variable AIMS_SPECIES_DIR . The minimal physical specification: what kind of calculation should be done. xc In addition, you might want to specify at least one of self-consistency accuracy commands (see below) in order to avoid an excessively long calculation. Two general options might come in useful to post process the output: keyword
description
Base name for the output, in case the calculator is called multiple times within a single output_template script. track_output True/False - if True all the output files will be kept, while the number of calls to the
calculator is encoded in the output file name. List of keywords
This is a non-exclusive list of keywords for the control.in file that can be addresses from within ASE. The meaning for these keywords is exactly the same as in FHI-aims, please refer to its manual for help on their use. One thing that should be mentioned is that keywords with more than one option have been implemented as lists, eg. k_grid=(12,12,12) or relativistic=(’atomic_zora’,’scalar’) . In those cases, specifying a single string containing all the options is also possible. None of the keywords have any default within ASE,but do check the defaults set by FHI-aims. If there is a keyword that you would like to set and that is not yet implemented here, it is trivial to add to the first few lines of the aims calculator in the file ASE/ase/calculators/aims.py . Describing the basic physics of the system: keyword
list relax_geometry max_relaxation_steps int int n_max_pulay int sc_iter_limit restart_relaxations bool list MD_run MD_schedule list list MD_segment Output options: keyword
type
output_level output cubes
str list AimsCube
See below for a description of the volumetric cube file output interface AimsCube Keywords for accuracy settings: keyword
float float float str str str srt list str int int list list
Note: Any argument can be changed after the initial construction of the calculator, simply by setting it with the method >>> calc.set( keyword=value )
Volumetric Data Output
The class class FHI-aims. AimsCube(origin=(0,0,0),edges=[(0.1,0.0,0.0),(0.0,0.1,0.0),(0.0,0.0,0.1)],points=(50,50,50),plots=None)
describes an object that takes care of the volumetric output requests within FHI-aims. An object of this type can be attached to the main Aims() object as an option. The possible arguments for AimsCube are: 126
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
keyword
origin edges points plots
type
list 3x3-array list list
The possible values for the entry of plots are discussed in detail in the FHI-aims manual, see below for an example. Example
As an example, here is a possible setup to obtain the geometry of a water molecule: from ase import Atoms from ase.calculators.aims import Aims, AimsCube from ase.optimize import QuasiNewton
FLEUR is a density-functional theory code which uses the full potential linearized augmented plane-wave (FLAPW) method. FLEUR can be applied to any element in the periodic table, and the code is well suited especially to surfaces and magnetic materials. Environment variables
In order to use FLEUR through ASE, two environment variables have to be set. FLEUR_INPGEN should point to the simple input generator of FLEUR, and FLEUR to the actual executable. Note that FLEUR has different executables e.g. for cases with and without inversion symmetry, so the environment variable has to be set accordingly. As an example, the variables could be set like: $ export FLEUR_INPGEN=$HOME/fleur/v25/inpgen.x $ export FLEUR=$HOME/fleur/v25/fleur.x
Currently, limited number of FLEUR parameters can be set via the ASE interface Below follows a list of supported parameters keyword
type
xc str seq kpts convergence dict width float kmax float dict mixer maxiter int maxrelax int workdir str
default value
’LDA’ Γ-point {’energy’:
description
0.0001}
40 20 Current dir
XC-functional. Must be one of ‘LDA’, ‘PBE’, ‘RPBE’ k-point sampling Convergence criteria (meV) Width of Fermi smearing (eV) Plane-wave cut-off (a.u.) Mixing parameters ‘imix’, ‘alpha’, and ‘spinf’ Maximum number of SCF steps Maximum number of relaxation steps Working directory for the calculation
seq: A sequence of three int‘s. dict : A dictionary Spin-polarized calculation
If the atoms object has non-zero magnetic moments, a spin-polarized calculation will be performed by default. Utility functions
As only a subset of FLEUR parameters can currently be specified through ASE interface, the interface defines some utility functions for cases where manual editing of the FLEUR input file inp is necessary. FLEUR. write_inp(atoms)
Write the inp input file of FLEUR. First, the information from Atoms is written to the simple input file and the actual input file inp is then generated with the FLEUR input generator. The location of input generator is specified in the environment variable FLEUR_INPGEN. Finally, the inp file is modified according to the arguments of the FLEUR calculator object. FLEUR. initialize_density(atoms)
Creates a new starting density. FLEUR. calculate(atoms)
Converge a FLEUR calculation to self-consistency. Input files should be generated before calling this function FLEUR performs always fixed number of SCF steps. This function reduces the number of iterations gradually, however, a minimum of five SCF steps is always performed. FLEUR. relax(atoms)
Currently, user has to manually define relaxation parameters (atoms to relax, relaxation directions, etc.) in inp file before calling this function. Examples
Lattice constant of fcc Ni from numpy import linspace from ase.calculators.fleur import FLEUR from ase.lattice import bulk from ase.io.trajectory import PickleTrajectory
128
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
atoms = bulk(’Ni’, a=3.52) calc = FLEUR(xc=’PBE’, kmax=3.6, kpts=(10, 10, 10), workdir=’lat_const’) atoms.set_calculator(calc) traj = PickleTrajectory(’Ni.traj’,’w’, atoms) cell0 = atoms.get_cell() for s in linspace(0.95, 1.05, 7): cell = cell0 * s atoms.set_cell((cell)) ene = atoms.get_potential_energy() traj.write()
See the equation of states tutorial for analysis of the results. Gromacs Introduction
Gromacs is a free classical molecular dynamics package. It is mainly used in modeling of biological systems. It is part of the ubuntu-linux distribution. http://www.gromacs.org/ Warning:
1. Ase-Gromacs calculator works properly only with gromacs version 4.5.6 or a newer one. (fixed bug related to .g96 format) Warning:
2. It only makes sense to use ase-gromacs for qm/mm or for testing. For pure MM production runs the native gromacs is much much faster (at the moment ase-gromacs has formatted io using .g96 format which is slow).
Gromacs Calculator
This ASE-interface is a preliminary one and it is VERY SLOW so do not use it for production runs. It is here because of we’ll have a QM/MM calculator which is using gromacs as the MM part. For example: (setting for the MM part of a QM/MM run, parameter ‘-nt 1’ for serial run): CALC_MM = Gromacs( init_structure_file = infile_name, structure_file = ’gromacs_qm.g96’, \ force_field=’oplsaa’, water_model=’tip3p’, base_filename = ’gromacs_qm’, doing_qmmm = True, freeze_qm = False, index_filename = ’index.ndx’, extra_mdrun_parameters = ’ - n t 1 ’, define = ’-DFLEXIBLE’, integrator = ’md’, nsteps = ’0’, nstfout = ’1’, nstlog = ’1’, nstenergy = ’1’, nstlist = ’1’, ns_type = ’grid’, pbc = ’xyz’, rlist = ’1.15’, coulombtype = ’PME-Switch’, rcoulomb = ’0.8’, vdwtype = ’shift’,
For example: (setting for a MM calculation, useful when keeping QM fixed and relaxing MM only, parameter ‘-nt 1’ for serial run): CALC_MM_RELAX = Gromacs( init_structure_file = infile_name, structure_file = ’gromacs_mm-relax.g96’, force_field=’oplsaa’, water_model=’tip3p’, base_filename = ’gromacs_mm-relax’, doing_qmmm = False, freeze_qm = True, index_filename = ’index.ndx’, extra_mdrun_parameters = ’ - n t 1 ’, define = ’-DFLEXIBLE’, integrator = ’cg’, nsteps = ’10000’, nstfout = ’10’, nstlog = ’10’, nstenergy = ’10’, nstlist = ’10’, ns_type = ’grid’, pbc = ’xyz’, rlist = ’1.15’, coulombtype = ’PME-Switch’, rcoulomb = ’0.8’, vdwtype = ’shift’, rvdw = ’0.8’, rvdw_switch = ’0.75’, DispCorr = ’Ener’)
Parameters
The description of the parameters http://www.gromacs.org/Documentation/Manual
can
be
found
in
the
Gromacs
manual:
and extra (ie. non-gromacs) parameter: init_structure_file: str structure_file: str
Name of the input structure file for gromacs (only pdb2gmx uses this)
Name of the structure file for gromacs (in all other context that the initial input file)
force_field: str Name of the force field for gromacs water_model: str Name of the water model for gromacs
The generated Gromacs file names have this string as the common part in their names (except structure files).
base_filename: str
doing_qmmm: logical
If true we run only single step of gromacs (to get MM forces and energies in QM/MM)
freeze_qm: logical If
true, the qm atoms will be kept fixed (The list of qm atoms is taken from file ‘index_filename’, below)
index_filename: string Name of the index file for gromacs extra_pdb2gmx_parameters: str extra_grompp_parameters: str extra_mdrun_parameters: str
130
extra parameter(s) to be passed to gromacs programm ‘pdb2gmx’
extra parameter(s) to be passed to gromacs program ‘grompp’ extra parameter(s) to be passed to gromacs program ‘mdrun’
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Environmental variables:
• GMXCMD the name of the main gromacs executable (usually ‘mdrun’). If GMXCMD is not set gromacs test is not run, but in the calculator works using ‘mdrun’. • GMXCMD_PREF prefix for all gromacs commands (default ‘’) • GMXCMD_POST postfix (ie suffix) for all gromacs commands (default ‘’) Example: MM-only geometry optimization of a histidine molecule
THIS IS NOT A PROPER WAY TO SETUP YOUR MD SIMULATION. THIS IS JUST A DEMO THAT DOES NOT CRASH. (the box size should be iterated by md-NTP, total charge should be 0). Initial pdb coordinates (file his.pdb): COMPND REMARK REMARK HETATM HETATM HETATM HETATM HETATM HETATM HETATM HETATM HETATM HETATM HETATM REMARK
HIS HISTIDINE HIS Part of HIC-Up: http://xray.bmc.uu.se/hicup HIS Extracted from PDB file pdb1wpu.ent 1 N HIS 4234 0.999 -1.683 -0.097 2 CA HIS 4234 1.191 -0.222 -0.309 3 C HIS 4234 2.641 0.213 -0.105 4 O HIS 4234 3.529 -0.651 -0.222 5 CB HIS 4234 0.245 0.546 0.619 6 CG HIS 4234 -1.200 0.349 0.280 7 ND1 HIS 4234 -1.854 -0.849 0.470 8 CD2 HIS 4234 -2.095 1.176 -0.310 9 CE1 HIS 4234 -3.087 -0.752 0.006 10 NE2 HIS 4234 -3.258 0.467 -0.474 11 OXT HIS 4234 2.889 1.404 0.141 HIS ENDHET
First generate the initial structure in gromacs format (.gro) >>> pdb2gmx -f his.pdb -o hish.gro -ff oplsaa -water tip3p
(pdb2gmx seems strangely to give the molecule hish.gro a total charge of -0.110 but this is not a problem for us now, this is just an example) Then setup a periodic simulation box >>> editconf -f hish.gro -o hish_box.gro -box 3 3 3
Solvate histidine in a water box >>> genbox -cp hish_box.gro -cs spc216.gro -o hish_waterbox.gro
Generate index file for gromacs groups >>> make_ndx -f hish_waterbox.gro >>> q
Finally, relax the structure. The sample file for relaxation: """ An example for using gromacs calculator in ase. Atom positions are relaxed. A sample call: ./gromacs_example_mm_relax.py hish_waterbox.gro """
from ase.calculators.gromacs import Gromacs import sys
Jacapo - ASE python interface for Dacapo Introduction
Jacapo is an ASE interface for Dacapo that is fully compatible with ASE. It replaces the old Dacapo interface using Numeric python and ASE2. The code was originally developed by John Kitchin and detailed documentation as well as many examples are available online: http://gilgamesh.cheme.cmu.edu/doc/software/jacapo/index.html Jacapo is included as an optional calculator in ASE and small differences to the above documentation may occur, and the documentation is no longer maintained. Jacapo calculator
The Jacapo interface is automatically installed with ase and can be imported using: from ase.calculators.jacapo import Jacapo
(You will need to have a working installation of Dacapo, however.) class jacapo.Jacapo
Here is a list of available keywords to initialize the calculator:
int float list boolean str boolean boolean boolean dict boolean int boolean
description
Output NetCDF file, or input file if nc already exists. Output file. By default equal to nc. ase atoms object Planewave cutoff in eV Density cutoff in eV Exchange-correlation functional. One of [’PZ’,’VWN’,’PW91’,’PBE’,’RPBE’,’revPBE’] Number of bands Fermi temperature K-point grid, e.g. kpts = (2,2,1) Turn on/off spin-polarization Magnetic moment of the unit cell Turn on/off symmetry reduction Turn on/off stress calculation Turn on/off dipole correction Atom-projected density of states Turn on/off stay alive Set debug level (0=off, 10=extreme) If the nc file exists, delete it (to ensure a fresh run). Default is False.
Example
Here is an example of how to calculate the total energy of a H atom. Warning:
This is an example only - the parameters are not physically meaningful!
from ase import Atoms, Atom from ase.io import write from ase.calculators.jacapo import Jacapo
Note that all calculator parameters should be set in the calculator definition itself. Do not attempt to use the calc.set_* commands as they are intended to be internal to the calculator. Note also that Dacapo can only operate with periodic boundary conditions, so be sure that pbc is set to True. Restarting from an old calculation
If the file you specify to Jacapo with the nc keyword exists, Jacapo will assume you are attempting to restart an existing calculation. If you do not want this behavior, turn the flag deletenc to True in your calculator 7.14. Calculators
133
ASE Manual, Release 3.9.0.3484
definition. For example, it is possible to continue a geometry optimization with something like this: calc = Jacapo(’old.nc’, stay_alive=True) atoms = calc.get_atoms() dyn = QuasiNewton(atoms, logfile=’qn.log’) dyn.run(fmax=0.05)
Note, that the stay_alive flag is not stored in the .nc file and must be set when the calculator instance is created. Atom-projected density of states
To find the atom-projected density of states with Jacapo, first specify the ados dictionary in your calculator definition, as in: calc = Jacapo( ... , ados={’energywindow’: (-10., 5.), ’energywidth’: 0.2, ’npoints’: 250, ’cutoff’: 1.0})
After this is established, you can use the get_ados command to get the desired ADOS data. For example: energies, dos = calc.get_ados(atoms=[0], orbitals=[’d’], cutoff=’short’, spin=[0])
LAMMPS Calculators
LAMMPS (Large-scale Atomic/Molecular Massively Parallel Simulator) is a classical molecular dynamics code. There are two calculators that interface to the LAMMPS molecular dynamics code that can be used to solve an atoms model for energy, atom forces and cell stresses. They are: 1. LAMMPSrun which interfaces to LAMMPS via writing a controlling input file that is then run automatically through LAMMPS and the results read back in. These results are currently limited to total energy, atomic forces and cell stress. 2. LAMMPSlib which uses the python interface that comes with LAMMPS, loads the LAMMPS program as a python library. The LAMMPSlib calculator then creates a ‘.lmp’ object which is a running LAMMPS subroutine, so further commands can be sent to this object and executed until it is explicitly closed. Any additional variables calculated by LAMMPS can also be extracted. Note however, any mistakes in the code sent to the LAMMPS routine will cause python to terminate. ASE is licensed as LGPL and LAMMPS is GPL which ‘prohibits’ them from being linked together in a distribution such as ASE. As a result, LAMMPSlib is not distributed with the ASE project but is available separately at lammpslib . Further explanation of the licensing is constained in License. It should not matter which code you use, but if you want access to more of LAMMPS internal variables or to perform a more complicated simulation then use LAMMPSlib. It is important to know which code you are using because when you make an error in the LAMMPS code, debugging the is difficult and different for both calculators. Both of these interfaces are still experimental code and any problems should be reported to the ASE developers mailing list.
134
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
LAMMPSrun Introduction
LAMMPS (Large-scale Atomic/Molecular Massively Parallel Simulator) is a classical molecular dynamics code. “LAMMPS has potentials for soft materials (biomolecules, polymers) and solid-state materials (metals, semiconductors) and coarse-grained or mesoscopic systems. It can be used to model atoms or, more generically, as a parallel particle simulator at the atomic, meso, or continuum scale.” This is LAMMPSrun ASE implementation of the interface to LAMMPS. Environment variables
The environment variable LAMMPS_COMMAND should contain the path to the lammps binary, or more generally, a command line possibly also including an MPI-launcher command. For example (in a Bourne-shell compatible environment): $ export LAMMPS_COMMAND=/path/to/lmp_binary
or possibly something similar to $ export LAMMPS_COMMAND="/path/to/mpirun --np 4 lmp_binary"
LAMMPS Calculator
The LAMMPS calculator first appeared in ASE version 3.5.0. At the time of the release of ASE 3.5.0, the LAMMPS calculator is still in a fairly early stage of development (if you are missing some feature, consider checking out the source code development tree or some more recent version of ASE). class LAMMPSrun. LAMMPS(..., parameters={}, files=
[], ...)
Below follows a list with a selection of parameters keyword
type default value
files list[] parameters dict{}
description
List of files needed by LAMMPS. Typically a list of potential files. Dictionary with key-value pairs corresponding to commands and arguments. Command-argument pairs provided here will be used for overriding the the calculator defaults.
Example
A simple example. from ase import Atoms, Atom from ase.calculators.lammpsrun import LAMMPS
There are some modules to facilitate the setup of an OPLS force field calculation, see opls. NWChem
NWChem is a computational chemistry code based on gaussian basis functions or plane-waves. Environment variable
The default command to start NWChem is nwchem PREFIX.nw > PREFIX.out. You can change that by setting the environment variable ASE_NWCHEM_COMMAND . Example
Here is an example of how to calculate optimize the geometry of a water molecule using PBE: $ asec H2O optimize -c nwchem -p xc=PBE LBFGS: 0 16:17:29 -2064.914841 1.9673 LBFGS: 1 16:17:31 -2064.963074 0.9482 LBFGS: 2 16:17:32 -2064.976603 0.1425 LBFGS: 3 16:17:33 -2064.977216 0.0823 LBFGS: 4 16:17:35 -2064.977460 0.0010 $ ase-gui H2O.traj@-1 -tg "a(1,0,2),d(0,1)" 102.577881445 1.00806894632
SIESTA Introduction
SIESTA is a density-functional theory code for very large systems based on atomic orbital (LCAO) basis sets. Environment variables
You need to write a script called run_siesta.py containing something like this: import os
The environment variable SIESTA_SCRIPT must point to that file. A directory containing the pseudopotential files .vps is also needed, and it is to be put in the environment variable SIESTA_PP_PATH . Set both environment variables in your shell configuration file: $ export SIESTA_SCRIPT=$HOME/siesta/run_siesta.py $ export SIESTA_PP_PATH=$HOME/mypps
SIESTA Calculator
The default parameters are very close to those that the SIESTA Fortran code uses. These are the exceptions: class siesta.Siesta(label=’siesta’, xc=’LDA’, pulay=5, mix=0.1)
136
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Here is a detailed list of all the keywords for the calculator: keyword
Monkhorst-Pack k-point sampling Number of bands Mesh cut-off energy in eV Type of basis set (‘sz’, ‘dz’, ‘szp’, ‘dzp’) Exchange-correlation functional. Number of old densities to use for Pulay mixing Pulay mixing weight Fermi-distribution width in eV Total charge of the system Name of the output file
A value of None means that SIESTA’s default value is used. Extra FDF parameters
The SIESTA code reads the input parameters for any calculation from a .fdf file. This means that you can set parameters by manually setting entries in this input .fdf file. This is done by the syntax: >>> calc.set_fdf(’name_of_the_entry’, value)
For example, the EnergyShift can be set using >>> calc.set_fdf(’PAO.EnergyShift’, 0.01 * Rydberg)
The complete list of the FDF entries can be found in the official SIESTA manual. Customized basis-set
Standard basis sets can be set by the keyword basis directly in the Siesta calculator object. If a customized basis is needed, it can be set as an FDF entry, as explained in the previous section. As an example, we generate a triple-zeta triple-polarized (TZTP) basis for Au. Since the valence states are 6s and 5d, we will have 3 zeta orbitals for l=0 and 3 for l=2 plus 3 polarization orbitals for l=1. The basis can be defined by >>> value = ["""Au 2 >>> 0 3 P >>> 0.00 0.00 >>> >>> 2 3 >>> 0.00 0.00
split 3 0.00
0.00
0.00"""]
#label, num. of l-shells,type,charge #l,nzeta,’P’(opt):pol.functions,npolzeta #rc of basis functions for each zeta function #0.00 => rc determined by PAO.EnergyShift #l,nzeta #rc
>>> calc.set_fdf(’PAO.Basis’,value=value)
The default basis set generation fails for Pt for some versions of Siesta. If this happens, you should specify the basis set manually. This is exemplified below. For Pt, using calc.set_fdf(’PAO.EnergyShift’, 0.1 * eV) is usually reasonable, and a single-zeta polarized basis set can be specified by writing: # Define SZP basis set for Pt
calc.set_fdf(’PAO.Basis’, ["""\ Pt 2 # Species label, number of l-shells n=6 0 1 P # n, l, Nzeta, Polarization, NzetaPol 0. # 0.0 => default [6.982 \n 1.000] n=5 2 1 # n, l, zeta # 0.0 => default [5.172 \n 1.000] 0."""])
7.14. Calculators
137
ASE Manual, Release 3.9.0.3484
A double-zeta polarized basis set for Pt may be specified by: # Define DZP basis set for Pt
calc.set_fdf(’PAO.Basis’, ["""\ Pt 2 split 0.00 # Species label, number of l-shells n=6 0 2 P 1 # n, l, Nzeta, Polarization, NzetaPol 0.00 0.00 # 0.0 => default [6.982 5.935 \n 1.000 n=5 2 2 # n, l, zeta # 0.0 => default [5.172 3.060 \n 1.000 0.00 0.00"""])
1.000] 1.000]
You can also reuse the basis set of a previous calculation, by copying the .ion files to the new location, and set the User.Basis tag to True: # Load basis from previous calc (*.ion files)
calc.set_fdf(’User.Basis’, True)
Warning: Specifying a basis set manually in any way will, for some obscure reason, make Siesta crash if you have ghost atoms! Pseudopotentials
Pseudopotential files in the .psf or .vps formats are needed. Pseudopotentials generated from the ABINIT code and converted to the SIESTA format are available in the SIESTA website . A database of user contributed pseudopotentials is also available there. You can also find an on-line pseudopotential generator from the OCTOPUS code. Example
Here is an example of how to calculate the total energy for bulk Silicon, using a double-zeta basis generated by specifying a given energy-shift: #!/usr/bin/env python
Here, the only input information on the basis set is, that it should be double-zeta ( basis=’dz’ ) and that the confinement potential should result in an energy shift of 0.01 Rydberg (the PAO.EnergyShift fdf tag). Sometimes it can be necessary to specify more information on the basis set. For example, the default basis set generation fails for Pt for some versions of Siesta. To fix this, you must specify the basis set manually. Manual basis set specifications are described in Customized basis-set. 138
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Restarting from an old Calculation
If you want to rerun an old SIESTA calculation, made using the ASE interface or not, you can set the fdf tag UseSaveData to True. This is equivalent to setting both DM.UseSaveDM and MD.UseSaveXV to True, i.e. it will reuse the the density matrix, and the atomic coordinates (and unit cell) of the previous calculation. Note that the Siesta jobname (the label keyword in the ASE interface) must be identical to the jobname of the old calculation. TURBOMOLE Introduction
TURBOMOLE is a density-functional or Hartree Fock code using atom centered orbitals. This interface makes it possible to use TURBOMOLE as a calculator in ASE. Environment variables
Set environment variables in your configuration file: • bash: $ TURBODIR=/my_disk/my_name/TURBOMOLE $ PATH=$PATH:$TURBODIR/scripts $ PATH=$PATH:$TURBODIR/bin/‘sysname‘
• csh/tcsh: $ setenv TURBODIR /my_disk/my_name/TURBOMOLE $ set path=($path ${TURBODIR}/scripts) $ set path=($path ${TURBODIR}/bin/‘sysname‘)
Turbomole Calculator
All usual turbomole input files generated by Turbomole’s define [coord, control, basis, (auxbasis), mos/alpha+beta] must be present in the current working directory. Turbomole files are updated during the ASE-run. Do not use internal coordinates, only cartesians are allowed. In the coord file one can fix atoms the turbomole way (writing a ‘f’ in the end of the line in the coord file). Ase-Turbomole uses turbomole programs ‘ridft’ and ‘rdgrad’ if keyword ‘$ricore’ is present in the Turbomole’s control file. Otherwise programs ‘dscf’ and ‘grad’ are used. Example1: Geometry Optimization import os from ase.io import read,write from ase.optimize import QuasiNewton # Turbomole input coordinates must be in the file ’coord’. # The coordinates are updated to the file ’coord’ during the minimization.
test = read(’coord’) test.set_calculator(Turbomole())
Example2: Diffusion run using NEB import os from ase.io import read from ase.neb import NEB from ase.calculators.turbomole import Turbomole from ase.optimize import BFGS
initial = read(’initial.coord’) final = read(’final.coord’) os.system(’rm -f coord; cp initial.coord coord’) # Make a band consisting of 5 configs:
configs = [initial] configs += [initial.copy() for i in range(3)] configs += [final] band = NEB(configs, climb=True) # Interpolate linearly the positions of the not-endpoint-configs:
band.interpolate() #Set calculators
for config in configs:
config.set_calculator(Turbomole()) # Optimize the Path:
Example3: Diffusion run using NEB, Restart old calculation import os from ase.io import read from ase.neb import NEB from ase.calculators.turbomole import Turbomole from ase.optimize import BFGS
For developers: python files affected by the turbomole interface
ase: __init__.py new lines 17from ase.calculators import LennardJones, \ EMT, ASAP, Siesta, Dacapo, Vasp, Turbomole ase/io: __init__.py new line 44 TURBOMOLE coord file (filename===’coord’) new lines 145if format == ’turbomole’: from ase.io.turbomole import read_turbomole return read_turbomole(filename) new line 184 TURBOMOLE coord file turbomole new lines 267elif format == ’tmol’: from ase.io.turbomole import write_turbomole write_turbomole(filename, images) return new lines 349if lines[0].startswith(’$coord’): return ’turbomole’ NEW FILE: ase/io/turbomole.py ase/calculators: __init__.py new line 10 from ase.calculators.turbomole import Turbomole NEW FILE: ase/calculators/turbomole.py
VASP Introduction
VASP is a density-functional theory code using pseudopotentials or the projector-augmented wave method and a plane wave basis set. This interface makes it possible to use VASP as a calculator in ASE, and also to use ASE as a post-processor for an already performed VASP calculation. Environment variables
You need to write a script called run_vasp.py containing something like this: import os
exitcode = os.system(’vasp’)
The environment variable VASP_SCRIPT must point to that file.
7.14. Calculators
141
ASE Manual, Release 3.9.0.3484
A directory containing the pseudopotential directories potpaw (LDA XC) potpaw_GGA (PW91 XC) and potpaw_PBE (PBE XC) is also needed, and it is to be put in the environment variable VASP_PP_PATH . Set both environment variables in your shell configuration file: $ export VASP_SCRIPT=$HOME/vasp/run_vasp.py $ export VASP_PP_PATH=$HOME/vasp/mypps
VASP Calculator
The default setting used by the VASP interface is class vasp. Vasp(restart=None, xc=’PW91’, setups=None, kpts=(1, 1 , 1) , gamma=None)
Below follows a list with a selection of parameters keyword
None seq Γ-point bool None bool None str float float int str int float int
description
Restart old calculation or use ASE for post-processing XC-functional Additional setup option k-point sampling Γ-point centered k -point sampling Use reciprocal units if k-points are specified explicitly Accuracy of calculation Kinetic energy cutoff Convergence break condition for SC-loop. Number of bands Electronic minimization algorithm Type of smearing Width of smearing Maximum number of SC-iterations
seq: A sequence of three int‘s.
For parameters in the list without default value given, VASP will set the default value. Most of the parameters used in the VASP INCAR file are allowed keywords. See the official VASP manual for more details. Note:
Parameters can be changed after the calculator has been constructed by using the set() method:
>>> calc.set(prec=’Accurate’, ediff=1E-5)
This would set the precision to Accurate and the break condition for the electronic SC-loop to 1E-5 eV.
Spin-polarized calculation
If the atoms object has non-zero magnetic moments, a spin-polarized calculation will be performed by default. Here follows an example how to calculate the total magnetic moment of a sodium chloride molecule. from ase import Atoms, Atom from ase.calculators.vasp import Vasp
In this example the initial magnetic moments are assigned to the atoms when defining the Atoms object. The calculator will detect that at least one of the atoms has a non-zero magnetic moment and a spin-polarized calculation will automatically be performed. The ASE generated INCAR file will look like: INCAR created by Atomic Simulation Environment PREC = Accurate LREAL = .FALSE. ISPIN = 2 MAGMOM = 1*1.9280 1*0.7500
Note:
It is also possible to manually tell the calculator to perform a spin-polarized calculation:
>>> calc.set(ispin=2)
This can be useful for continuation jobs, where the initial magnetic moment is read from the WAVECAR file.
Restart old calculation
To continue an old calculation which has been performed without the interface use the restart parameter when constructing the calculator >>> calc = Vasp(restart=True)
Then the calculator will read atomic positions from the CONTCAR file, physical quantities from the OUTCAR file, k-points from the KPOINTS file and parameters from the INCAR file. Only Monkhorst-Pack and Gamma-centered k-point sampling are supported for restart at the moment. Some INCAR parameters may not be implemented for restart yet. Please report any problems to the ASE mailing list. Note:
The restart parameter can be used , as the name suggest to continue a job from where a previous calculation finished. Furthermore, it can be used to extract data from an already performed calculation. For example, to get the total potential energy of the sodium chloride molecule in the previous section, without performing any additional calculations, in the directory of the previous calculation do: >>> calc = Vasp(restart=True) >>> atoms = calc.get_atoms() >>> atoms.get_potential_energy()
-4.7386889999999999
ase_qmmm_manyqm Introduction
This an general interface to run QM/MM calculations with a ase-QM and ase-MM calculator. Currently QM can be FHI-aims and MM can be Gromacs. QM and MM region can be covalently bonded. In principle you can cut wherever you like, but other cutting schemes are probably better than others. The standard recommendation is to cut only the C-C bonds. There can be many QM regions embedded in the MM system.
7.14. Calculators
143
ASE Manual, Release 3.9.0.3484
Ase_qmmm_manyqm Calculator
QM/MM interface with QM=FHI-aims, MM=gromacs QM could be any QM calculator, but you need to read in QM-atom charges from the QM program (in method ‘get_qm_charges’). One can have many QM regions, each with a different calculator. There can be only one MM calculator, which is calculating the whole system. Non-bonded interactions: Generally energies and forces are treated by:
• Within the same QM-QM: by QM calculator • MM-MM: by MM calculator • QM-MM: by MM using MM vdw parameters and QM charges. • Different QM-different QM: by MM using QM and MM charges and MM-vdw parameters The Hirschfeld charges (or other atomic charges) on QM atoms are calculated by QM in a H terminated cluster in vacuum. The charge of QM atom next to MM atom (edge-QM-atom) and its H neighbors are set as in the classical force field. The extra(missing) charge results from:
• linkH atoms • The edge-QM atoms, and their singly bonded neighbors (typically -H or =O). These have their original MM charges. • From the fact that the charge of the QM fraction is not usually an integer when using the original MM charges. • The extra/missing charge is added equally to all QM atoms (not being linkH and not being edge-QMatom or its singly bonded neighbor) so that the total charge of the MM-fragment involving QM atoms will be the same as in the original MM-description. Vdw interactions are calculated by MM-gromacs for MM and MM-QM interactions. The QM-QM vdw interaction s could be done by the FHI-aims if desired (by modifying the input for QM-FHI-aims input accordingly. Bonded interactions: E = E_qm(QM-H) + E_mm(ALL ATOMS), where
• E_qm(QM-H): qm energy of H terminated QM cluster(s) • E_mm(ALL ATOMS): MM energy of all atoms, except for terms in which all MM-interacting atoms are in the same QM region. Forces do not act on link atoms but they are positioned by scaling. Forces on link atoms are given to their QM and MM neighbors by chain rule. (see Top Curr Chem (2007) 268: 173–290, especially pages 192194). At the beginning of a run, the optimal edge-qm-atom-linkH bond length(s) is (are) calculated by QM in ‘get_eq_qm_atom_link_h_distances’ or they are read from a file (this is determined by the argument ‘link_info’). The covalent bonds between QM and MM are found automatically based on ase-covalent radii in neighbor search. Link atoms are positioned automatically (according to . Questions & Comments markus.kaukonen@iki.fi Interesting applications could be cases when we need two or more QM regions. For instance two redox centers in a protein, cathode and anode of a fuel cell ... you name it!
144
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Arguments
keyword
type default value
nqm_regions int qm_calculators list mm_calculator Calc link_infostr ’byQM’
description
The number of QM regions List of members of a Class defining a ase-QM calculator for each QM region A member of a Class defining a ase-MM calculator Can be either ‘byQM’: the edge_qm_atom-link_h_atom distances are calculated by QM or ‘byFile’:the edge_qm_atom-link_h_atom distances are read from a file
Example
1. Prepare classical input with Gromacs • Get THE INDEPENDENT STRUCTURE OF THE ANTITRYPTIC REACTIVE SITE LOOP OF BOWMAN-BIRK INHIBITOR AND SUNFLOWER TRYPSIN INHIBITOR-1 (pdb code 1GM2) from pdb data bank http://www.rcsb.org/pdb/home/home.do, name it to 1GM2.pdb • In file 1GM2.pdb take only MODEL1 replace ‘CYS ‘ by ‘CYS2’ in order to get deprotonated CYS-CYS bridge. • Generate gromacs coordinates and topology >>> pdb2gmx -ff oplsaa -f 1GM2.pdb -o 1GM2.gro -p 1GM2.top -water tip3p -ignh
• Generate the simulation box (cubic is not the most efficient one...) >>> editconf -bt cubic -f 1GM2.gro -o 1GM2_box.gro -c -d 0.2
• Solvate the protein in water box >>> genbox -cp 1GM2_box.gro -cs spc216.gro -o 1GM2_sol.gro -p 1GM2.top
• Generate index file (needed later also for defining QM atoms) >>> make_ndx -f 1GM2_sol.gro -o index.ndx >>> select ’q’
• add to first lines to index.ndx (we define here 3 QM regions, indexing from 1): [qm_ss] 18 19 20 21 139 140 141 142 [qm_thr] 28 29 30 31 32 33 34 35 [qm_ser] 64 65 66 67 68
2. Relax MM system by fixing QM atoms in their (crystallographic?) positions (see documentation for Gromacs MM calculator). """ An example for using gromacs calculator in ase. Atom positions are relaxed. If qm atoms are found in index file, they are kept fixed in the relaxation. QM atoms are defined in index file (numbering from 1) in sets containing QM or Qm or qm in their name. A sample call:
7.14. Calculators
145
ASE Manual, Release 3.9.0.3484
./gromacs_example_mm_relax.py 1GM2_sol.gro """
from ase.calculators.gromacs import Gromacs import sys from ase.io import read
3. QM/MM relaxation (all atoms are free) """ demo run for ase_qmmm_manyqm calculator """ #
./test_ase_qmmm_manyqm.py gromacs_mm-relax.g96
from ase.calculators.gromacs import Gromacs from ase.calculators.aims import Aims from ase.calculators.ase_qmmm_manyqm import AseQmmmManyqm from ase.optimize import BFGS import sys from ase.io.gromos import read_gromos
7.14.3 QMMM For QMMM caculations, see ase_qmmm_manyqm .
7.14.4 Calculator interface All calculators must have the following interface: class ase.calculators.interface. Calculator
ASE calculator. A calculator should store a copy of the atoms object used for the last calculation. When one of the get_potential_energy, get_forces , or get_stress methods is called, the calculator should check if anything has changed since the last calculation and only do the calculation if it’s really needed. Two sets of atoms are considered identical if they have the same positions, atomic numbers, unit cell and periodic boundary conditions. calculation_required (atoms, quantities )
Check if a calculation is required. Check if the quantities in the quantities list have already been calculated for the atomic configuration atoms. The quantities can be one or more of: ‘energy’, ‘forces’, ‘stress’, ‘charges’ and ‘magmoms’. This method is used to check if a quantity is available without further calculations. For this reason, calculators should react to unknown/unsupported quantities by returning True, indicating that the quantity is not available. get_forces(atoms)
Return the forces. get_potential_energy(atoms=None, force_consistent=False )
Return total energy. Both the energy extrapolated to zero Kelvin and the energy consistent with the forces (the free energy) can be returned. get_stress(atoms)
Return the stress.
7.14.5 Electronic structure calculators These calculators have wave functions, electron densities, eigenvalues and many other quantities. Therefore, it makes sense to have a set of standard methods for accessing those quantities: class ase.calculators.interface. DFTCalculator
Class for demonstrating the ASE interface to DFT-calculators. get_bz_k_points()
Return all the k-points in the 1. Brillouin zone. The coordinates are relative to reciprocal latice vectors. get_effective_potential(spin=0, pad=True)
Return pseudo-effective-potential array.
148
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
get_eigenvalues(kpt=0, spin=0)
Return eigenvalue array. get_fermi_level()
Return the Fermi level. get_ibz_k_points()
Return k-points in the irreducible part of the Brillouin zone. The coordinates are relative to reciprocal latice vectors. get_k_point_weights()
Weights of the k-points. The sum of all weights is one. get_magnetic_moment(atoms=None)
Return the total magnetic moment. get_number_of_bands()
Return the number of bands. get_number_of_grid_points()
Return the shape of arrays. get_number_of_spins()
Return the number of spins in the calculation. Spin-paired calculations: 1, spin-polarized calculation: 2. get_occupation_numbers(kpt=0, spin=0)
Return occupation number array. get_pseudo_density(spin=None, pad=True)
Return pseudo-density array. If spin is not given, then the total density is returned. Otherwise, the spin up or down density is returned (spin=0 or 1). get_pseudo_wave_function(band=0, kpt=0, spin=0, broadcast=True, pad=True)
Initial guess for the shape of wannier functions. Use initial guess for wannier orbitals to determine rotation matrices U and C.
7.15 Constraints When performing minimizations or dynamics one may wish to keep some degrees of freedom in the system fixed. One way of doing this is by attaching constraint object(s) directly to the atoms object. Important: setting constraints will freeze the corresponding atom positions. Changing such atom positions can be achieved: • by directly setting the positions attribute (see example of setting Special attributes ),
7.15. Constraints
149
ASE Manual, Release 3.9.0.3484
• alternatively, by removing the constraints first: del atoms.constraints
or: atoms.set_constraint()
and using the set_positions() method.
7.15.1 The FixAtoms class This class is used for fixing some of the atoms. class constraints. FixAtoms(indices=None, mask=None)
You must supply either the indices of the atoms that should be fixed or a mask. The mask is a list of booleans, one for each atom, being true if the atoms should be kept fixed. For example, to fix the positions of all the Cu atoms in a simulation with the indices keyword: >>> c = FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == ’Cu’]) >>> atoms.set_constraint(c)
or with the mask keyword: >>> c = FixAtoms(mask=[atom.symbol == ’Cu’ for atom in atoms]) >>> atoms.set_constraint(c)
7.15.2 The FixBondLength class This class is used to fix the distance between two atoms specified by their indices ( a1 and a2 ) class constraints. FixBondLength(a1, a2 )
Example of use: >>> c = FixBondLength(0, 1) >>> atoms.set_constraint(c)
In this example the distance between the atoms with indices 0 and 1 will be fixed in all following dynamics and/or minimizations performed on the atoms object. This constraint is useful for finding minimum energy barriers for reactions where the path can be described well by a single bond length (see the Dissociation tutorial tutorial). Important: If fixing multiple bond lengths, use the FixBondLengths class below, particularly if the same atom is fixed to multiple partners.
7.15.3 The FixBondLengths class More than one bond length can be fixed by using this class. Especially for cases in which more than one bond length constraint is applied on the same atom. It is done by specifying the indices of the two atoms forming the bond in pairs. class constraints. FixBondLengths( pairs)
Example of use: >>> c = FixBondLengths([[0, 1], [0, 2]]) >>> atoms.set_constraint(c)
Here the distances between atoms with indices 0 and 1 and atoms with indices 0 and 2 will be fixed. The constraint is for the same purpose as the FixBondLength class. 150
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
7.15.4 The FixedLine class class ase.constraints. FixedLine(a, direction) Constrain an atom a to move on a given line only.
The line is defined by its direction.
7.15.5 The FixedPlane class class ase.constraints. FixedPlane(a, direction) Constrain an atom a to move in a given plane only.
The plane is defined by its normal: direction. Example of use: Diffusion of gold atom on Al(100) surface (constraint) .
7.15.6 The FixedMode class class ase.constraints. FixedMode(mode)
Constrain atoms to move along directions orthogonal to a given mode only. A mode is a list of vectors specifying a direction for each atom. ase.vibrations.Vibrations.get_mode() .
It often comes from
7.15.7 The Hookean class This class of constraints, based on Hooke’s Law, is generally used to conserve molecular identity in optimization schemes and can be used in three different ways. In the first, it applies a Hookean restorative force between two atoms if the distance between them exceeds a threshold. This is useful to maintain the identity of molecules in quenched molecular dynamics, without changing the degrees of freedom or violating conservation of energy. When the distance between the two atoms is less than the threshold length, this constraint is completely inactive. The below example tethers atoms at indices 3 and 4 together: >>> c = Hookean(a1=3, a2=4, rt=1.79, k=5.) >>> atoms.set_constraint(c)
Alternatively, this constraint can tether a single atom to a point in space, for example to prevent the top layer of a slab from subliming during a high-temperature MD simulation. An example of tethering atom at index 3 to its original position: >>> c = Hookean(a1=3, a2=atoms[3].position, rt=0.94, k=2.) >>> atoms.set_constraint(c)
Reasonable values of the threshold (rt) and spring constant (k) for some common bonds are below. Bond O-H C-O C-H C=O Pt sublimation Cu sublimation
rt (Angstroms) 1.40 1.79 1.59 1.58 0.94 0.97
k (eV Angstrom^-2) 5 5 7 10 2 2
A third way this constraint can be applied is to apply a restorative force if an atom crosses a plane in space. For example: >>> c = Hookean(a1=3, a2=(0, 0, 1, -7), k=10.) >>> atoms.set_constraint(c)
7.15. Constraints
151
ASE Manual, Release 3.9.0.3484
This will apply a restorative force on atom 3 in the downward direction of magnitude k * (atom.z - 7) if the atom’s vertical position exceeds 7 Angstroms. In other words, if the atom crosses to the (positive) normal side of the plane, the force is applied and directed towards the plane. (The same plane with the normal direction pointing in the -z direction would be given by (0, 0, -1, 7).) For an example of use, see the Constrained minima hopping (global optimization) tutorial. Note:
In previous versions of ASE, this was known as the BondSpring constraint.
7.15.8 The FixInternals class This class allows to fix an arbitrary number of bond lengths, angles and dihedral angles. The defined constraints are satisfied self consistently. To define the constraints one needs to specify the atoms object on which the constraint works (needed for atomic masses), a list of bond, angle and dihedral constraints. Those constraint definitions are always list objects containing the value to be set and a list of atomic indices. The epsilon value specifies the accuracy to which the constraints are fulfilled. class constraints. FixInternals(atoms, bonds=[bond1, bond2], angles=[angle1], drals=[dihedral1, dihedral2], epsilon=1.e-7 )
This example defines a bond an angle and a dihedral angle constraint to be fixed at the same time.
7.15.9 Combining constraints It is possible to supply several constraints on an atoms object. For example one may wish to keep the distance between two nitrogen atoms fixed while relaxing it on a fixed ruthenium surface: >>> pos = [[0.00000, 0.00000, 9.17625], [0.00000, 0.00000, 10.27625], ... [1.37715, 0.79510, 5.00000], ... ... [0.00000, 3.18039, 5.00000], ... [0.00000, 0.00000, 7.17625], ... [1.37715, 2.38529, 7.17625]] >>> unitcell = [5.5086, 4.7706, 15.27625] >>> atoms = Atoms(positions=pos, ... symbols=’N2Ru4’, ... cell=unitcell, ... pbc=[True,True,False]) >>> fa = FixAtoms(mask=[a.symbol == ’Ru’ for a in atoms]) >>> fb = FixBondLength(0, 1) >>> atoms.set_constraint([fa, fb])
When applying more than one constraint they are passed as a list in the set_constraint() method, and they will be applied one after the other. Important: If wanting to fix the length of more than one bond in the simulation, do not supply a list of FixBondLength instances; instead, use a single instance of FixBondLengths . 152
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
7.15.10 Making your own constraint class A constraint class must have these two methods: constraints. adjust_positions(oldpositions, newpositions)
Adjust the newpositions array inplace. constraints. adjust_forces( positions, forces)
Adjust the forces array inplace. A simple example: import numpy as np class MyConstraint: """Constrain an atom to move along a given direction only.""" def __init__ (self, a, direction):
self.a = a self.dir = direction / sqrt(np.dot(direction, direction)) def adjust_positions(self, oldpositions, newpositions):
7.15.11 The Filter class Constraints can also be applied via filters, which acts as a wrapper around an atoms object. A typical use case will look like this: ----------------------| | | | | | | Atoms |<----| Filter |<----| Dynamics | | | | | | | -----------------------
and in Python this would be: >>> atoms = Atoms(...) >>> filter = Filter(atoms, ...) >>> dyn = Dynamics(filter, ...)
This class hides some of the atoms in an Atoms object. class constraints. Filter(atoms, indices=None, mask=None)
You must supply either the indices of the atoms that should be kept visible or a mask. The mask is a list of booleans, one for each atom, being true if the atom should be kept visible. Example of use: >>> from ase import Atoms, Filter >>> atoms=Atoms(positions=[[ 0 , 0 , 0], ... [ 0.773, 0.600, 0], ... [-0.773, 0.600, 0]], ... symbols=’OH2’) >>> f1 = Filter(atoms, indices=[1, 2]) >>> f2 = Filter(atoms, mask=[0, 1, 1]) >>> f3 = Filter(atoms, mask=[a.Z == 1 for a in atoms]) >>> f1.get_positions()
[[ 0.773 [-0.773
0.6 0.6
7.15. Constraints
0. 0.
] ]]
153
ASE Manual, Release 3.9.0.3484
In all three filters only the hydrogen atoms are made visible. When asking for the positions only the positions of the hydrogen atoms are returned.
7.15.12 The UnitCellFilter class class ase.constraints. UnitCellFilter(atoms, mask=None)
Modify the supercell and the atom positions. Create a filter that returns the atomic forces and unit cell stresses together, so they can simultaneously be minimized. The first argument, atoms, is the atoms object. The optional second argument, mask, is a list of booleans, indicating which of the six independent components of the strain are relaxed. •True = relax to zero •False = fixed, ignore this component You can still use constraints on the atoms, e.g. FixAtoms, to control the relaxation of the atoms. >>> # this should be equivalent to the StrainFilter >>> atoms = Atoms(...) >>> atoms.set_constraint(FixAtoms(mask=[True for atom in atoms])) >>> ucf = UnitCellFilter(atoms)
You should not attach this UnitCellFilter object to a trajectory. Instead, create a trajectory for the atoms, and attach it to an optimizer like this: >>> atoms = Atoms(...) >>> ucf = UnitCellFilter(atoms) >>> qn = QuasiNewton(ucf) >>> traj = PickleTrajectory(’TiO2.traj’, ’w’, atoms) >>> qn.attach(traj) >>> qn.run(fmax=0.05)
7.15.13 The StrainFilter class class ase.constraints. StrainFilter(atoms, mask=None)
Modify the supercell while keeping the scaled positions fixed. Presents the strain of the supercell as the generalized positions, and the global stress tensor (times the volume) as the generalized force. This filter can be used to relax the unit cell until the stress is zero. If MDMin is used for this, the timestep (dt) to be used depends on the system size. 0.01/x where x is a typical dimension seems like a good choice. The stress and strain are presented as 6-vectors, the order of the components follow the standard engingeering practice: xx, yy, zz, yz, xz, xy. Create a filter applying a homogeneous strain to a list of atoms. The first argument, atoms, is the atoms object.
154
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
The optional second argument, mask, is a list of six booleans, indicating which of the six independent components of the strain that are allowed to become non-zero. It defaults to [1,1,1,1,1,1].
7.16 Nudged elastic band The Nudged Elastic Band method is a technique for finding transition paths (and corresponding energy barriers) between given initial and final states. The method involves constructing a “chain” of “replicas” or “images” of the system and relaxing them in a certain way. Relevant literature References: 1. H. Jonsson, G. Mills, and K. W. Jacobsen, in ‘Classical and Quantum Dynamics in Condensed Phase Systems’, edited by B. J. Berne, G. Cicotti, and D. F. Coker, World Scientific, 1998 [standard formulation] 2. ‘Improved Tangent Estimate in the NEB method for Finding Minimum Energy Paths and Saddle Points’, Graeme Henkelman and Hannes Jonsson, J. Chem. Phys. 113, 9978 (2000) [improved tangent estimates] 3. ‘A Climbing-Image NEB Method for Finding Saddle Points and Minimum Energy Paths’, Graeme Henkelman, Blas P. Uberuaga and Hannes Jonsson, J. Chem. Phys. 113, 9901 (2000)
7.16.1 The NEB class This module defines one class: class ase.neb. NEB(images , k=0.1, climb=False, parallel=False, world=None)
Nudged elastic band. images: list of Atoms objects Images defining path from initial to final state. k: float or list of floats Spring constant(s) in eV/Ang. One number or one for each spring. climb: bool
Use a climbing image (default is no climbing image).
parallel: bool Distribute images over processors.
Example of use, between initial and final state which have been previously saved in A.traj and B.traj: from ase import io from ase.neb import NEB from ase.optimize import MDMin # Read initial and final states:
initial = io.read(’A.traj’) final = io.read(’B.traj’) # Make a band consisting of 5 images:
images = [initial] images += [initial.copy() for i in range(3)] images += [final] neb = NEB(images) # Interpolate linearly the potisions of the three middle images:
Be sure to use the copy method (or similar) to create new instances of atoms within the list of images fed to the NEB. Do not use something like [initial for i in range(3)], as it will only create references to the original atoms object. Notice the use of the interpolate() method to get a good initial guess for the path from A to B.
7.16. Nudged elastic band
155
ASE Manual, Release 3.9.0.3484
NEB.interpolate()
Interpolate path linearly from initial to final state. Only the internal images (not the endpoints) need have calculators attached. See Also: optimize: Information
about energy minimization (optimization). Note that you cannot use the default optimizer, BFGSLineSearch, with NEBs. (This is the optimizer imported when you import QuasiNewton.) If you would like a quasi-newton optimizer, use BFGS instead.
calculators: How to use calculators. Tutorials :
• Diffusion of gold atom on Al(100) surface (NEB) • Dissociation tutorial If there are M images and each image has N atoms, then the NEB object behaves like one big Atoms object with M N atoms, so its get_positions() method will return a M N × 3 array. Note:
7.16.2 Trajectories The code: from ase.optimize import BFGS
optimizer = BFGS(neb, trajectory=’A2B.traj’)
will write all images to one file. The Trajectory object knows about NEB calculations, so it will write M images with N atoms at every iteration and not one big configuration containing M N atoms. The result of the latest iteration can now be analysed with this command: ase-gui A2B.traj@-5:. For the example above, you can write the images to individual trajectory files like this: for i in range(1, 4):
qn.attach(io.PickleTrajectory(’A2B-%d .traj’ % i, ’w’, images[i]))
The result of the latest iteration can be analysed like this: $ ase-gui A.traj A2B-?.traj B.traj -n -1
7.16.3 Restarting Restart the calculation like this: images = io.read(’A2B.traj@-5:’)
7.16.4 Climbing image The “climbing image” variation involves designating a specific image to behave differently to the rest of the chain: it feels no spring forces, and the component of the potential force parallel to the chain is reversed, such that it moves towards the saddle point. This depends on the adjacent images providing a reasonably good approximation of the correct tangent at the location of the climbing image; thus in general the climbing image is not turned on until some iterations have been run without it (generally 20% to 50% of the total number of iterations). To use the climbing image NEB method, instantiate the NEB object like this: neb = NEB(images, climb=True)
156
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
Quasi-Newton methods, methods, such as BFGS, are not well suited for climbing image NEB calculations. calculations. FIRE have been known to give good results, although convergence convergence is slow. slow. Note:
7.16.5 Paralleliza Parallelization tion over over images Some calculator calculatorss can parallelize parallelize over over the images images of a NEB calculation calculation.. The script will have to be run with an MPI-enabled Python interpreter like GPAW like GPAW‘s ‘s gpaw-python gpaw-python.. All images exist on all processors, but only some of them have a calculator attached: from ase.parallel import rank, from rank, size from ase.calculators.emt import EMT from # Num Number ber of int intern ernal al ima images ges: :
n = len len(images) (images) - 2 j = rank * n // size for i, image image in enumerate(images[ enumerate(images[1 1:-1]): if i == j: image. image.set_calculator(EMT())
Create the NEB object with NEB(images, NEB(images, parallel=True) parallel=True) and let the master processes write the images: if rank % (size // n) == 0:
For a complete example using GPAW using GPAW,, see here see here..
7.17 Vibr Vibration ation analy analysis sis You can calculate the vibrational modes of a an Atoms object in the harmonic approximation using the Vibrations . class ase.vibrations. Vibrations(atoms, indices=None, name=’vib’ , delta=0.01 , nfree=2)
Class for calculating vibrational modes using finite difference. The vibrational modes are calculated from a finite difference approximation of the Hessian matrix. The summary(), get_energies() get_energies() and get_frequencies() get_frequencies() methods all take an optional method keyword. keyword. Use method=’Frederiksen’ to use the method described in: T. Frederiksen, M. Paulsson, M. Brandbyge, A. P. Jauho: “Inelastic transport theory from firstprinciples principles:: methodolog methodologyy and applications applications for nanoscale nanoscale devices” devices”,, Phys. Rev. Rev. B 75, 205413 205413 (2007) atoms: Atoms object The atoms to work on. indices: list of int
List of indices of atoms to vibrate. Default behavior is to vibrate all atoms.
name: str Name to use for files. delta: float Magnitude of displacements.
Number of displacements per atom and cartesian coordinate, coordinate, 2 and 4 are supported. Default is 2 which will displace each atom +delta and -delta for each cartesian coordinate.
nfree: int
Example:
7.17. Vibration analysis
157
ASE Manual, Release 3.9.0.3484
>>> from ase import Atoms >>> from from ase.calculators import EMT >>> from from ase.optimize import BFGS >>> from from ase.vibrations import Vibrations Atoms(’N2’, , [(0 [(0, 0, 0), (0, 0, 1.1 1.1)], )], >>> n2 = Atoms(’N2’ calculator= calculator=EMT()) ... BFGS(n2).run(fmax= run(fmax=0.01 0.01) ) >>> BFGS(n2).
BFGS: 0 16:01:21 0.440339 BFGS: 1 16:01:21 0.271928 BFGS: 2 16:01:21 0.263278 BFGS: 3 16:01:21 0.262777 >>> vib = Vibrations(n2) vib.run() >>> vib. Writing Writi ng vib.e vib.eq.pck q.pckl l Writing Writi ng vib.0 vib.0x-.pc x-.pckl kl Writing Writi ng vib.0 vib.0x+.pc x+.pckl kl Writing Writi ng vib.0 vib.0y-.pc y-.pckl kl Writing Writi ng vib.0 vib.0y+.pc y+.pckl kl Writing Writi ng vib.0 vib.0z-.pc z-.pckl kl Writing Writi ng vib.0 vib.0z+.pc z+.pckl kl Writing Writi ng vib.1 vib.1x-.pc x-.pckl kl Writing Writi ng vib.1 vib.1x+.pc x+.pckl kl Writing Writi ng vib.1 vib.1y-.pc y-.pckl kl Writing Writi ng vib.1 vib.1y+.pc y+.pckl kl Writing Writi ng vib.1 vib.1z-.pc z-.pckl kl Writing Writi ng vib.1 vib.1z+.pc z+.pckl kl >>> vib. vib.summary() --------------------# meV cm^-1 --------------------0 0.0 0.0 1 0.0 0.0 2 0.0 0.0 3 2.5 20.4 4 2.5 20.4 5 1 52 52.6 1230.8 --------------------Zero-p Zer o-poin oint t ene energy rgy: : 0.0 0.079 79 eV vib.write_mode(write_mode(-1) # wr >>> vib. writ ite e la last st mo mode de
Get vibration energies in eV. get_frequencies(method=’standard’, direction=’central’ direction=’central’ )
Get vibration frequencies in cm^-1. run()
Run the vibration calculations. This will calculate the forces for 6 displacements per atom +/-x, +/-y, +/-z. Only those calculations that are not already done will be started. started. Be aware that an interrupted interrupted calculation calculation may produce an empty file (ending with .pckl), which must be deleted before restarting the job. Otherwise the forces will not be calculated for that displacement. Note that the calculations for the different displacements can be done simultaneously by several independent processes. This feature relies on the existence of files and the subsequent creation of the file in case it is not found. summary(method=’standard’, direction=’central’ , freq=None, log=’ , mode ‘w’ at 0x7f2f79bbc150> )
Print a summary of the vibrational frequencies.
Parameters: method [string] Can be ‘standard’(default) or ‘Frederiksen’.
158
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
direction: string Direction for finite differences. Can be one of ‘central’ (default), ‘forward’, ‘back-
ward’. freq
[numpy array] Optional. Can be used to create a summary on a set of known frequencies.
log [if
specified, specified, write output to a different different location location than] stdout. Can be an object with a write() method or the name of a file to create.
write_jmol()
Writes file for viewing of the modes with jmol. write_mode(n=None, kT=0.02585215707677002 kT=0.025852157076770025 5 , nimages=30 )
Write mode number n to trajectory file. If n is not specified, writes all non-zero modes. name is a string that is prefixed to the names of all the files created. atoms is an Atoms object that is either at a fully relaxed ground state or at a saddle point. freeatoms is a list of atom indices for which the vibrational modes will be calculated, the rest of the atoms are considered frozen. displacements is a list of displacements, one for each free atom that are used in the finite difference method to calculate the Hessian matrix. method is -1 for backward differences, 0 for centered differences, and 1 for forward differences. Warning: Using
the dacapo calculator you must make sure that the symmetry program in dacapo finds the same number of symmetries for the displaced dis placed configurations in the vibrational modules as found in the ground state used as input. This is because the wavefunction is reused from one displacement to the next. One way to ensure this is to tell dacapo not to use symmetries. This will show op as a python error ‘Frames are not aligned’. This could be the case for other calculators as well.
7.18 Phon Phonon on calculatio calculations ns Module for calculating vibrational normal modes for periodic systems using the so-called small displacement method (see e.g. [Alfe]). [Alfe]). So far, space-group space-group symmetries symmetries are not exploited exploited to reduce the number of atomic displacements that must be calculated and subsequent symmetrization of the force constants. For polar materials the dynamical matrix at the zone center acquires a non-analytical contribution that accounts for the LO-TO splitting. This contribution requires additional functionality to evaluate and is not included in the present implementation. Its implementation in conjunction with the small displacement method is described in [Wang].. [Wang]
7.19 Exam Example ple Simple example showing how to calculate the phonon dispersion for bulk aluminum using a 7x7x7 supercell within effective medium theory: from ase.structure import bulk from from ase.calculators.emt import EMT from from ase.dft.kpoints import ibz_points, from ibz_points, get_bandpath from ase.phonons import Phonons from # Set Setup up cry crysta stal l and EMT cal calcul culato ator r
atoms = bulk(’Al’ bulk(’Al’, , ’fcc’, ’fcc’, a=4.05 4.05) ) calc = EMT() # Pho Phonon non cal calcul culato ator r
N = 7 ph = Phonons(ato Phonons(atoms, ms, calc, supercell supercell= =(N, (N, N, N), N), delt delta a=0.05 0.05) ) ph. ph.run() # Rea Read d for forces ces and ass assemb emble le the dyn dynami amical cal mat matrix rix
ph. ph.read(acoustic= read(acoustic=True True) )
7.18. Phonon calculations
159
ASE Manual, Release 3.9.0.3484
# Hig High-s h-symm ymmetr etry y poi points nts in the Bri Brillo llouin uin zon zone e
points = ibz_points[’fcc’ ibz_points[’fcc’] ] G = points[’Gamma’ points[’Gamma’] ] X = points[’X’ points[’X’] ] W = points[’W’ points[’W’] ] K = points[’K’ points[’K’] ] L = points[’L’ points[’L’] ] U = points[’U’ points[’U’] ] point_names = [’$\Gamma$’ ’$\Gamma$’, , ’X’ ’X’, , ’U’ ’U’, , ’L’ ’L’, , ’$\Gamma$’, ’$\Gamma$’, ’K’ ’K’] ] path = [G, [G, X, U, L, G, K] # Ba Band nd st stru ruct ctur ure e in me meV V
path path_k _kc, c, q, Q = get_bandpath(path, get_bandpath(path, atoms. atoms.cell, 100 100) ) omega_kn = 1000 * ph. ph.band_structure(path_kc) # Cal Calcul culate ate pho phonon non DOS
omega_e, omega_e, dos_e = ph. ph.dos(kpts= dos(kpts=(50 50, , 50 50, , 50 50), ), npts npts=5000 5000, , delt delta a=5e-4 5e-4) ) omega_e *= 1000 # Pl Plot ot th the e ba band nd st stru ruct ctur ure e an and d DO DOS S
Mode inspection using ase-gui: # Wri Write te mod modes es for spe specif cific ic q-v q-vect ector or to tra trajec jector tory y fil files es
ph. ph.write_modes([l/ write_modes([l/2 for l in L], branches branches= =[2], repeat repeat= =(8, 8, 8), kT= kT=3e-4 3e-4) )
7.19. Example
161
ASE Manual, Release 3.9.0.3484
7.20 Infrared intensities InfraRed is an extension of Vibrations , in addition to the vibrational modes, also the infrared intensities of the modes are calculated for an Atoms object. class ase.infrared. InfraRed (atoms, indices=None, name=’ir’ , delta=0.01 , nfree=2, directions=None)
Class for calculating vibrational modes and infrared intensities using finite difference.
The vibrational modes are calculated from a finite difference approximation of the Dynamical matrix and the IR intensities from a finite difference approximation of the gradient of the dipole moment. The method is described in: D. Porezag, M. R. Pederson: “Infrared intensities and Raman-scattering activities within densityfunctional theory”, Phys. Rev. B 54, 7830 (1996) The calculator object (calc) linked to the Atoms object (atoms) must have the attribute: >>> calc.get_dipole_moment(atoms)
In addition to the methods included in the Vibrations class the InfraRed class introduces two new methods; get_spectrum() and write_spectra(). The summary(), get_energies(), get_frequencies(), get_spectrum() and write_spectra() methods all take an optional method keyword. Use method=’Frederiksen’ to use the method described in: T. Frederiksen, M. Paulsson, M. Brandbyge, A. P. Jauho: “Inelastic transport theory from firstprinciples: methodology and applications for nanoscale devices”, Phys. Rev. B 75, 205413 (2007) atoms: Atoms object The atoms to work on. indices: list of int
List of indices of atoms to vibrate. Default behavior is to vibrate all atoms.
name: str Name to use for files. delta: float Magnitude of displacements. nfree: int Number
of displacements per degree of freedom, 2 or 4 are supported. Default is 2 which will displace each atom +delta and -delta in each cartesian direction. Cartesian coordinates to calculate the gradient of the dipole moment in. For example directions = 2 only dipole moment in the z-direction will be considered, whereas for directions = [0, 1] only the dipole moment in the xy-plane will be considered. Default behavior is to use the dipole moment in all directions.
directions: list of int
Example: >>> from ase.io import read >>> from ase.calculators.vasp import Vasp >>> from ase.infrared import InfraRed >>> water = read(’water.traj’) # read pre-relaxed structure of water molecule >>> calc = Vasp(prec=’Accurate’, ... ediff=1E-8, ... isym=0, ... # calculate the total dipole moment idipol=4, ... dipol=water.get_center_of_mass(scaled=True), ... ldipol=True) >>> water.set_calculator(calc) >>> ir = InfraRed(water) >>> ir.run() >>> ir.summary()
------------------------------------Mode Frequency Intensity # meV cm^-1 (D/Å)^2 amu^-1 -------------------------------------
162
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
0 16.9i 136.2i 1.6108 1 10.5i 84.9i 2.1682 2 5.1i 41.1i 1.7327 3 0.3i 2.2i 0.0080 4 2.4 19.0 0.1186 5 15.3 123.5 1.4956 6 195.5 1576.7 1.6437 7 458.9 3701.3 0.0284 8 473.0 3814.6 1.1812 ------------------------------------Zero-point energy: 0.573 eV Static dipole moment: 1.833 D Maximum force on atom in ‘equilibrium‘: 0.0026 eV/Å
This interface now also works for calculator ‘siesta’, (added get_dipole_moment for siesta). Example: >>> #!/usr/bin/env python >>> from ase.io import read >>> from ase.calculators.siesta import Siesta >>> from ase.infrared import InfraRed >>> bud = read(’bud1.xyz’) >>> calc = Siesta(label=’bud’, ... meshcutoff=250 * Ry, ... basis=’DZP’, ... kpts=[1, 1, 1]) >>> calc.set_fdf(’DM.MixingWeight’, 0.08) >>> calc.set_fdf(’DM.NumberPulay’, 3) >>> calc.set_fdf(’DM.NumberKick’, 20) >>> calc.set_fdf(’DM.KickMixingWeight’, 0.15) >>> calc.set_fdf(’SolutionMethod’, ’Diagon’) >>> calc.set_fdf(’MaxSCFIterations’, 500) >>> calc.set_fdf(’PAO.BasisType’, ’split’) >>> #50 meV = 0.003674931 * Ry >>> calc.set_fdf(’PAO.EnergyShift’, 0.003674931 * Ry ) >>> calc.set_fdf(’LatticeConstant’, 1.000000 * Ang) >>> calc.set_fdf(’WriteCoorXmol’, ’T’) >>> bud.set_calculator(calc) >>> ir = InfraRed(bud) >>> ir.run() >>> ir.summary()
The method returns wavenumbers in cm^-1 with corresponding absolute infrared intensity. Start and end point, and width of the Gaussian/Lorentzian should be given in cm^-1. normalize=True ensures the integral over the peaks to give the intensity. write_spectra(out=’ir-spectra.dat’, start=800, end=4000 , npts=None, width=10, type=’Gaussian’, method=’standard’ , direction=’central’ , intensity_unit=’(D/A)2/amu’, normalize=False)
Write out infrared spectrum to file.
First column is the wavenumber in cm^-1, the second column the absolute infrared intensities, and the 7.20. Infrared intensities
163
ASE Manual, Release 3.9.0.3484
third column the absorbance scaled so that data runs from 1 to 0. Start and end point, and width of the Gaussian/Lorentzian should be given in cm^-1.
7.21 Molecular dynamics Typical computer simulations involve moving the atoms around, either to optimize a structure (energy minimization) or to do molecular dynamics. This chapter discusses molecular dynamics, energy minimization algorithms will be discussed in the optimize section. A molecular dynamics object will operate on the atoms by moving them according to their forces - it integrates Newton’s second law numerically. A typical molecular dynamics simulation will use the Velocity Verlet dynamics. You create the VelocityVerlet object, giving it the atoms and a time step, and then you perform dynamics by calling its run() method: dyn = VelocityVerlet(atoms, 5.0 * units.fs) dyn.run(1000) # take 1000 steps
A number of different algorithms can be used to perform molecular dynamics, with slightly different results.
7.21.1 Choosing the time step All the dynamics objects need a time step. Choosing it too small will waste computer time, choosing it too large will make the dynamics unstable, typically the energy increases dramatically (the system “blows up”). If the time step is only a little to large, the lack of energy conservation is most obvious in Velocity Verlet dynamics, where energy should otherwise be conserved. Experience has shown that 5 femtoseconds is a good choice for most metallic systems. Systems with light atoms (e.g. hydrogen) and/or with strong bonds (carbon) will need a smaller time step. All the dynamics objects documented here are sufficiently related to have the same optimal time step.
7.21.2 File output The time evolution of the system can be saved in a trajectory file, by creating a trajectory object, and attaching it to the dynamics object. This is documented in the module ase.io.trajectory . Unlike the geometry optimization classes, the molecular dynamics classes do not support giving a trajectory file name in the constructor. Instead the trajectory must be attached explicitly to the dynamics, and it is strongly recommended to use the optional interval argument, so every time step is not written to the file.
7.21.3 Logging A logging mechanism is provided, printing time; total, potential and kinetic energy; and temperature (calculated from the kinetic energy). It is enabled by giving the logfile argument when the dynamics object is created, logfile may be an open file, a filename or the string ‘-‘ meaning standard output. Per default, a line is printed for each timestep, specifying the loginterval argument will chance this to a more reasonable frequency. The logging can be customized by explicitly attaching a ase.md.MDLogger object to the dynamics: from ase.md import MDLogger
This example will skip the header line and write energies per atom instead of total energies. The parameters are
164
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
header: Print a header line defining the columns. stress: Print the six components of the stress tensor. peratom : Print energy per atom instead of total energy. mode: If ‘a’, append to existing file, if ‘w’ overwrite existing file.
Despite appearances, attaching a logger like this does not create a cyclic reference to the dynamics. If building your own logging class, be sure not to attach the dynamics object directly to the logging object. Instead, create a weak reference using the proxy method of the weakref package. See the ase.md.MDLogger source code for an example. (If this is not done, a cyclic reference may be created which can cause certain calculators, such as Jacapo, to not terminate correctly.) Note:
7.21.4 Constant NVE simulations (the microcanonical ensemble) Newton’s second law preserves the total energy of the system, and a straightforward integration of Newton’s second law therefore leads to simulations preserving the total energy of the system (E), the number of atoms (N) and the volume of the system (V). The most appropriate algorithm for doing this is velocity Verlet dynamics, since it gives very good long-term stability of the total energy even with quite large time steps. Fancier algorithms such as Runge-Kutta may give very good short-term energy preservation, but at the price of a slow drift in energy over longer timescales, causing trouble for long simulations. In a typical NVE simulation, the temperature will remain approximately constant, but if significant structural changes occurs they may result in temperature changes. If external work is done on the system, the temperature is likely to rise significantly. Velocity Verlet dynamics class md.verlet. VelocityVerlet(atoms, timestep)
VelocityVerlet is the only dynamics implementing the NVE ensemble. It requires two arguments, the atoms
and the time step. Choosing a too large time step will immediately be obvious, as the energy will increase with time, often very rapidly. Example: See the tutorial Molecular dynamics .
7.21.5 Constant NVT simulations (the canonical ensemble) Since Newton’s second law conserves energy and not temperature, simulations at constant temperature will somehow involve coupling the system to a heat bath. This cannot help being somewhat artificial. Two different approaches are possible within ASE. In Langevin dynamics, each atom is coupled to a heat bath through a fluctuating force and a friction term. In Nosé-Hoover dynamics, a term representing the heat bath through a single degree of freedom is introduced into the Hamiltonian. Langevin dynamics class md.langevin. Langevin(atoms, timestep, temperature, friction)
The Langevin class implements Langevin dynamics, where a (small) friction term and a fluctuating force are added to Newton’s second law which is then integrated numerically. The temperature of the heat bath and magnitude of the friction is specified by the user, the amplitude of the fluctuating force is then calculated to give that temperature. This procedure has some physical justification: in a real metal the atoms are (weakly) coupled to the electron gas, and the electron gas therefore acts like a heat bath for the atoms. If heat is produced locally, the atoms locally get a temperature that is higher than the temperature of the electrons, heat is transferred to the electrons and then rapidly transported away by them. A Langevin equation is probably a reasonable model for this process.
7.21. Molecular dynamics
165
ASE Manual, Release 3.9.0.3484
A disadvantage of using Langevin dynamics is that if significant heat is produced in the simulation, then the temperature will stabilize at a value higher than the specified temperature of the heat bath, since a temperature difference between the system and the heat bath is necessary to get a finite heat flow. Another disadvantage is that the fluctuating force is stochastic in nature, so repeating the simulation will not give exactly the same trajectory. When the Langevin object is created, you must specify a time step, a temperature (in energy units) and a friction. Typical values for the friction are 0.01-0.02 atomic units. # Room temperature simulation
Both the friction and the temperature can be replaced with arrays giving per-atom values. This is mostly useful for the friction, where one can choose a rather high friction near the boundaries, and set it to zero in the part of the system where the phenomenon being studied is located. Nosé-Hoover dynamics
In Nosé-Hoover dynamics, an extra term is added to the Hamiltonian representing the coupling to the heat bath. From a pragmatic point of view one can regard Nosé-Hoover dynamics as adding a friction term to Newton’s second law, but dynamically changing the friction coefficient to move the system towards the desired temperature. Typically the “friction coefficient” will fluctuate around zero. Nosé-Hoover dynamics is not implemented as a separate class, but is a special case of NPT dynamics. Berendsen NVT dynamics class md.nvtberendsen. NVTBerendsen(atoms, timestep, temperature , taut , fixcm)
In Berendsen NVT simulations the velocities are scaled to achieve the desired temperature. The speed of the scaling is determined by the parameter taut. This method does not result proper NVT sampling but it usually is sufficiently good in practise (with large taut). For discussion see the gromacs manual at www.gromacs.org. atoms: The list of atoms. timestep: The
time step.
temperature: The desired temperature, in Kelvin. taut:
Time constant for Berendsen temperature coupling.
fixcm:
If True, the position and momentum of the center of mass is kept unperturbed. Default: True.
# Room temperature simulation (300K, 0.1 fs time step)
7.21.6 Constant NPT simulations (the isothermal-isobaric ensemble) class md.npt. NPT(atoms, timestep, temperature, externalstress, ttime, pfactor , mask=None)
Dynamics with constant pressure (or optionally, constant stress) and constant temperature (NPT or N,stress,T ensemble). It uses the combination of Nosé-Hoover and Parrinello-Rahman dynamics proposed by Melchionna et al. [1] and later modified by Melchionna [2]. The differential equations are integrated using a centered difference method [3]. Details of the implementation are available in the document XXX NPTdynamics.tex, distributed with the module. The dynamics object is called with the following parameters: atoms: The atoms object. timestep:
The timestep in units matching eV, Å, u. Use the units.fs constant.
temperature:
166
The desired temperature in eV. Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
The external stress in eV/Å^3. Either a symmetric 3x3 tensor, a 6-vector representing the same, or a scalar representing the pressure. Note that the stress is positive in tension whereas the pressure is positive in compression: giving a scalar p is equivalent to giving the tensor (-p. -p, -p, 0, 0, 0).
externalstress:
ttime:
Characteristic timescale of the thermostat. Set to None to disable the thermostat. A constant in the barostat differential equation. If a characteristic barostat timescale of ptime is desired, set pfactor to ptime^2 * B (where B is the Bulk Modulus). Set to None to disable the barostat. Typical metallic bulk moduli are of the order of 100 GPa or 0.6 eV/Å^3.
pfactor:
Optional argument. A tuple of three integers (0 or 1), indicating if the system can change size along the three Cartesian axes. Set to (1,1,1) or None to allow a fully flexible computational box. Set to (1,1,0) to disallow elongations along the z-axis etc.
mask=None:
Useful parameter values: • The same timestep can be used as in Verlet dynamics, i.e. 5 fs is fine for bulk copper. • The ttime and pfactor are quite critical[4], too small values may cause instabilites and/or wrong fluctuations in T / p. Too large values cause an oscillation which is slow to die. Good values for the characteristic times seem to be 25 fs for ttime, and 75 fs for ptime (used to calculate pfactor), at least for bulk copper with 15000-200000 atoms. But this is not well tested, it is IMPORTANT to monitor the temperature and stress/pressure fluctuations. It has the following methods: NPT.run(n):
Perform n timesteps. NPT.initialize():
Estimates the dynamic variables for time=-1 to start the algorithm. This is automatically called before the first timestep. NPT.set_stress():
Set the external stress. Use with care. It is preferable to set the right value when creating the object. NPT.set_mask():
Change the mask. Use with care, as you may “freeze” a fluctuation in the strain rate. NPT.set_strainrate(eps):
Set the strain rate. eps must be an upper-triangular matrix. If you set a strain rate along a direction that is “masked out” (see set_mask), the strain rate along that direction will be maintained constantly. NPT.get_gibbs_free_energy():
Gibbs free energy is supposed to be preserved by this dynamics. This is mainly intended as a diagnostic tool. References: [1] S. Melchionna, G. Ciccotti and B. L. Holian, Molecular Physics 78, p. 533 (1993). [2] S. Melchionna, Physical Review E 61, p. 6165 (2000). [3] B. L. Holian, A. J. De Groot, W. G. Hoover, and C. G. Hoover, Physical Review A 41, p. 4552 (1990). [4] F. D. Di Tolla and M. Ronchetti, Physical Review E 48, p. 1726 (1993). See Also:
The API documentation: md Berendsen NPT dynamics class md.nptberendsen. NPTBerendsen(atoms, timestep, temperature , taut , fixcm, pressure, taup, compressibility)
7.21. Molecular dynamics
167
ASE Manual, Release 3.9.0.3484
In Berendsen NPT simulations the velocities are scaled to achieve the desired temperature. The speed of the scaling is determined by the parameter taut. The atom positions and the simulation cell are scaled in order to achieve the desired pressure. This method does not result proper NPT sampling but it usually is sufficiently good in practise (with large taut and taup). For discussion see the gromacs manual at www.gromacs.org. or amber at ambermd.org atoms: The list of atoms. timestep: The
time step.
temperature: The desired temperature, in Kelvin. taut:
Time constant for Berendsen temperature coupling.
fixcm:
If True, the position and momentum of the center of mass is kept unperturbed. Default: True.
pressure: The desired pressure, in bar (1 bar = 1e5 Pa). taup:
Time constant for Berendsen pressure coupling.
compressibility:
The compressibility of the material, water 4.57E-5 bar-1, in bar-1
# Room temperature simulation (300K, 0.1 fs time step, atmospheric pressure)
7.22 Density Functional Theory 7.22.1 Brillouin zone sampling The k-points are always given relative to the basis vectors of the reciprocal unit cell. Monkhorst-Pack
ase.dft.kpoints. monkhorst_pack(size)
Construct a uniform sampling of k-space of given size. The k-points are given as [MonkhorstPack]: 2ni − N i − 1 bi , 2N i i=1,2,3
where ni = 1, 2,...,N i , size = (N 1 , N 2 , N 3 ) and the bi ‘s are reciprocal lattice vectors. ase.dft.kpoints. get_monkhorst_pack_size_and_offset(kpts)
Naming convention: cc18_sq3xsq3 is 18 k -points for a sq(3)xsq(3) cell. Try this: >>> import numpy as np >>> import pylab as plt >>> from ase.dft.kpoints import cc162_1x1 >>> B = [(1, 0, 0), (-0.5, 3**0.5 / 2, 0), (0, 0, 1)] >>> k = np.dot(cc162_1x1, B) >>> plt.plot(k[:, 0], k[:, 1], ’o’)
[] >>> p.show()
7.22. Density Functional Theory
169
ASE Manual, Release 3.9.0.3484
7.22.2 Maximally localized Wannier functions This page describes how to construct the Wannier orbitals using the class Wannier. The page is organized as follows: • Introduction: A short summary of the basic theory. • The Wannier class : A description of how the Wannier class is used, and the methods defined within. Introduction
The point of Wannier functions is the transform the extended Bloch eigenstates of a DFT calculation, into a smaller set of states designed to facilitate the analysis of e.g. chemical bonding. This is achieved by designing the Wannier functions to be localized in real space instead of energy (which would be the eigen states). The standard Wannier transformation is a unitary rotation of the Bloch states. This implies that the Wannier functions (WF) span the same Hilbert space as the Bloch states, i.e. they have the same eigenvalue spectrum, and the original Bloch states can all be exactly reproduced from a linear combination of the WF. For maximally localized Wannier functions (MLWF), the unitary transformation is chosen such that the spread of the resulting WF is minimized. The standard choice is to make a unitary transformation of the occupied bands only, thus resulting in as many WF as there are occupied bands. If you make a rotation using more bands, the localization will be improved, but the number of wannier functions increase, thus making orbital based analysis harder. The class defined here allows for construction of partly occupied MLWF. In this scheme the transformation is still a unitary rotation for the lowest states (the fixed space ), but it uses a dynamically optimized linear combination of the remaining orbitals (the active space ) to improve localization. This implies that e.g. the eigenvalues of the Bloch states contained in the fixed space can be exactly reproduced by the resulting WF, whereas the largest eigenvalues of the WF will not necessarily correspond to any “real” eigenvalues (this is irrelevant, as the fixed space is usually chosen large enough, i.e. high enough above the fermilevel, that the remaining DFT eigenvalues are meaningless anyway). For the theory behind this method see the paper “Partly Occupied Wannier Functions” Thygesen, Hansen and Jacobsen, Phys. Rev. Lett , Vol. 94 , 26405 (2005). The Wannier class
Usual invocation: from ase.dft import Wannier
wan = Wannier(nwannier=18, calc=GPAW(’save.gpw’), fixedstates=15) wan.localize() # Optimize rotation to give maximal localization wan.save(’file.pickle’) # Save localization and rotation matrix # Re-load using saved wannier data
wan = Wannier(nwannier=18, calc=calc, fixedstates=15, file=’file.pickle’) # Write a cube file
For examples of how to use the Wannier class, see the Wannier tutorial. class ase.dft.wannier. Wannier(nwannier , calc, file=None, nbands=None, fixedenergy=None , fixedstates=None, spin=0, initialwannier=’random’ , seed=None, verbose=False )
Maximally localized Wannier Functions
Find the set of maximally localized Wannier functions using the spread functional of Marzari and Vanderbilt (PRB 56, 1997 page 12847). Required arguments:
170
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
nwannier: The number of Wannier functions you wish to construct. This
must be at least half the number of electrons in the system and at most equal to the number of bands in the calculation. If file arg. is not provided, the calculator must provide the method get_wannier_localization_matrix , and contain the wavefunctions (save files with only the density is not enough). If the localization matrix is read from file, this is not needed, unless get_function or write_cube is called.
calc: A converged DFT calculator class.
Optional arguments: nbands: Bands to include in localization. The
number of bands considered by Wannier can be smaller than the number of bands in the calculator. This is useful if the highest bands of the DFT calculation are not well converged.
spin: The spin channel to be considered. The
Wannier code treats each spin channel inde-
pendently. fixedenergy / fixedstates: Fixed part of Heilbert space. Determine the fixed part of Hilbert space by either a maximal energy or a number of bands (possibly a list for multiple
k-points). Default is None meaning that the number of fixed states is equated to nwannier . file: Read localization and rotation matrices from this file. initialwannier: Initial guess for Wannier rotation matrix. Can be ‘bloch’ to start from
the Bloch states, ‘random’ to be randomized, or a list passed to calc.get_initial_wannier. seed: Seed for random initialwannier . verbose : True / False level of verbosity. get_centers(scaled=False )
Calculate the Wannier centers pos =
L / 2pi * phase(diag(Z))
get_function(index, repeat=None )
Get Wannier function on grid. Returns an array with the funcion values of the indicated Wannier function on a grid with the size of the repeated unit cell. For a calculation using k -points the relevant unit cell for eg. visualization of the Wannier orbitals is not the original unit cell, but rather a larger unit cell defined by repeating the original unit cell by the number of k -points in each direction. Note that for a Γ-point calculation the large unit cell coinsides with the original unit cell. The large unitcell also defines the periodicity of the Wannier orbitals. index can be either a single WF or a coordinate vector in terms of the WFs. get_functional_value()
Calculate the value of the spread functional. Tr[|ZI|^2]=sum(I)sum(n) w_i|Z_(i)_nn|^2,
where w_i are weights. get_hamiltonian(k=0)
Get Hamiltonian at existing k-vector of index k dag H(k) = V k
diag(eps ) k
V k
get_hamiltonian_kpoint(kpt_c)
Get Hamiltonian at some new arbitrary k-vector
7.22. Density Functional Theory
171
ASE Manual, Release 3.9.0.3484
_ H(k) = >_ R
ik.R e
H(R)
Warning: This method moves all Wannier functions to cell (0, 0, 0) get_hopping( R)
Returns the matrix H(R)_nm=<0,n|H|R,m>. 1 _ H(R) = <0,n|H|R,m> = --- >_ Nk k
-ik.R e
H(k)
where R is the cell-distance (in units of the basis vectors of the small cell) and n,m are indices of the Wannier functions. get_pdos(w, energies, width)
Projected density of states (PDOS). Returns the (PDOS) for Wannier function w. The calculation is performed over the energy grid specified in energies. The PDOS is produced as a sum of Gaussians centered at the points of the energy grid and with the specified width. get_radii()
Calculate the spread of the Wannier functions. -- / L \ 2 2 radius**2 = - > | --- | ln |Z| --d \ 2pi /
Re-initialize current rotation matrix. Keywords are identical to those of the constructor. localize(step=0.25, tolerance=1e-08 , updaterot=True , updatecoeff=True )
Optimize rotation to give maximal localization max_spread (directions=[0, 1, 2] )
Returns the index of the most delocalized Wannier function together with the value of the spread functional save( file)
Save information on localization and rotation matrices to file. translate(w, R )
Translate the w’th Wannier function The distance vector R = [n1, n2, n3], is in units of the basis vectors of the small cell. translate_all_to_cell(cell=[0, 0, 0] )
Translate all Wannier functions to specified cell. Move all Wannier orbitals to a specific unit cell. There exists an arbitrariness in the positions of the Wannier orbitals relative to the unit cell. This method can move all orbitals to the unit cell specified by cell. For a Γ -point calculation, this has no effect. For a k -point calculation the periodicity of the orbitals are given by the large unit cell defined by repeating the original unitcell by the number of k -points in each direction. In this case it is usefull to move the orbitals away from the boundaries of the large cell before plotting them. For a bulk calculation with, say 10x10x10 k points, one could move the orbitals to the cell [2,2,2]. In this way the pbc boundary conditions will not be noticed. translate_to_cell(w, cell)
Translate the w’th Wannier function to specified cell write_cube(index , fname, repeat=None, real=True)
Dump specified Wannier function to a cube file
172
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
In Dacapo, the inialwannier keyword can be a list as described below: Setup an initial set of Wannier orbitals. initialwannier can set up a starting guess for the Wannier functions. This is important to speed up convergence in particular for large systems For transition elements with d electrons you will always find 5 highly localized d-orbitals centered at the atom. Placing 5 d-like orbitals with a radius of 0.4 Angstroms and center at atom no. 7, and 3 p-like orbitals with a radius of 0.4 Angstroms and center at atom no. 27 looks like this: initialwannier = [[[7],2,0.4],[[27],1,0.4]]
Placing only the l=2, m=-2 and m=-1 orbitals at atom no. 7 looks like this: initialwannier = [[[7],2,-2,0.4],[[7],2,-1,0.4]]
I.e. if you do not specify the m quantum number all allowed values are used. Instead of placing an orbital at an atom, you can place it at a specified position. For example the following: initialwannier = [[[0.5,0.5,0.5],0,0.5]]
places an s orbital with radius 0.5 Angstroms at the position (0.5, 0.5, 0.5) in scaled coordinates of the unit cell. For calculations using k -points, make sure that the Γ-point is included in the k -point grid. The Wannier module does not support k-point reduction by symmetry, so you must use the usesymm=False keyword in the calc, and shift all k -points by a small amount (but not less than 2e-5 in) in e.g. the x direction, before performing the calculation. If this is not done the symmetry program will still use time-reversal symmetry to reduce the number of k-points by a factor 2. The shift can be performed like this: Note:
from ase import *
kpts = monkhorst_pack((15, 9, 9)) + [2e-5, 0, 0]
7.22.3 Density of states Example: calc = ... dos = DOS(calc, width=0.2) d = dos.get_dos() e = dos.get_energies()
You can plot the result like this: import pylab as plt
Calculations involving moments of a DOS distribution may be facilitated by the use of get_distribution_moment() method, as in the following example: from ase.dft import get_distribution_moment
volume = get_distribution_moment(e,d) center, width = get_distribution_moment(e,d,(1,2))
More details class ase.dft.dos. DOS(calc, width=0.1, window=None, npts=201)
Electronic Density Of States object. calc: calculator object
Any ASE compliant calculator object.
width: float Width of guassian smearing.
Use window=(emin, emax). If not specified, a window big enough to hold all the eigenvalues will be used.
window: tuple of two float npts: int Number
of points.
get_energies()
Return the array of energies used to sample the DOS. The energies are reported relative to the Fermi level. get_dos(spin=None)
Get array of DOS values. The spin argument can be 0 or 1 (spin up or down) - if not specified, the total DOS is returned. ase.dft. get_distribution_moment( x, y , order=0)
Return the moment of nth order of distribution. 1st and 2nd order moments of a band correspond to the band’s center and width respectively. For integration, the trapezoid rule is used.
174
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
7.22.4 STM images The STM is a revolutionary experimental surface probe that has provided direct local insight into the surface electronic structure. Sometimes the interpretation of STM topographs are not straightforward and therefore theoretically modeled STM images may resolve conflicting possibilities and point to an underlying atomistic model. ASE includes python modules for generating Tersoff-Hamann STM topographs. See Also:
• Tutorial using GPAW • Execise using GPAW More details: class ase.dft.stm. STM (atoms, symmetries=None)
Scanning tunneling microscope. atoms: Atoms object or filename Atoms to scan or name of file to read LDOS from. symmetries: list of int List of integers 0, 1, and/or 2 indicating which surface symmetries have been used
to reduce the number of k-points for the DFT calculation. The three integers correspond to the following three symmetry operations: [-1 [ 0
0] 1]
[ 1 0] [ 0 -1]
[ 0 [ 1
1] 0]
calculate_ldos(bias)
Calculate local density of states for given bias. get_averaged_current(bias, z )
Calculate avarage current at height z. Use this to get an idea of what current to use when scanning. linescan(bias, current , p1, p2 , npoints=50, z0=None)
Constant current line scan. Example: stm = STM(...) z = ... # tip position c = stm.get_averaged_current(-1.0, z) stm.linescan(-1.0, c , (1.2, 0.0), (1.2, 3.0))
scan(bias, current , z0=None, repeat=(1, 1) )
Constant current 2-d scan. Returns three 2-d arrays (x, y, z) containing x-coordinates, y-coordinates and heights. These three arrays can be passed to matplotlibs contourf() function like this: >>> import matplotlib.pyplot as plt >>> plt.gca(aspect=’equal’) >>> plt.contourf(x, y, z) >>> plt.show()
write( filename=’stm.pckl’ )
Write local density of states to pickle file.
7.22.5 Bader Analysis Henkelman et. al have implemented a fast and robust algorithm for calculating the electronic charges on individual atoms in molecules or crystals, based on the Bader partitioning scheme [Bader]. In that method, the analysis is based purely on the electron density. The partitioning of the density is determined according to its zero-flux surfaces. Details of their implementation can be found in [Tang]. The program is freely available at http://theory.cm.utexas.edu/henkelman/research/bader/ where you will also find a description of the method. 7.22. Density Functional Theory
175
ASE Manual, Release 3.9.0.3484
The algorithm is very well suited for large solid state physical systems, as well as large biomolecular systems. The computational time depends only on the size of the 3D grid used to represent the electron density, and scales linearly with the total number of grid points. As the accuracy of the method depends on the grid spacing, it is recommended to check for convergence in this parameter (which should usually by smaller than the default value). The program takes cube input files. It does not support units, and assumes atomic units for the density (Bohr^-3). All ase dft calculators have a get_pseudo_density method, which can be used to get the density. A simple python script for making a cube file, ready for the Bader program, could be: >>> from ase import * >>> density = calc.get_pseudo_density() * Bohr**3 >>> write(’filename.cube’, atoms, data=density)
Some calculators (e.g. gpaw) also have a method called get_all_electron_density , in which case this is preferable to get_pseudo_density . Note that it is strongly recommended to use version 0.26b or higher of the program, and the examples below refer to this version. Example: The water molecule
The following example shows how to do Bader analysis for a water molecule. First do a ground state calculation, and save the density as a cube file: from ase import * from gpaw import *
Then analyse the density cube file by running (use bader -h for a description of the possible options): $ bader -p all_atom -p atom_index water_density.cube
This will produce a number of files. The ACF.dat file, contains a summary of the Bader analysis: | | | | | | |
# X Y Z CHARGE MIN DIST ----------------------------------------------------------------1 7.0865 8.5038 9.0672 9.1121 1.3250 2 7.0865 9.9461 7.9403 0.4440 0.2834 3 7.0865 7.0615 7.9403 0.4440 0.2834 ----------------------------------------------------------------NUMBER OF ELECTRONS: 9.99999
Revealing that 0.56 electrons have been transferred from each Hydrogen atom to the Oxygen atom. The BvAtxxxx.dat files, are cube files for each Bader volume, describing the density within that volume. (I.e. it is just the original cube file, truncated to zero outside the domain of the specific Bader volume). AtIndex.dat is a cube file with an integer value at each grid point, describing which Bader volume it belongs to.
The plot below shows the dividing surfaces of the Hydrogen Bader volumes. This was achieved by plotting a contour surface of AtIndex.dat at an isovalue of 1.5.
176
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
You can attach the output charges from the bader program to the atoms for further processing: from ase import * from ase.io.bader import attach_charges # define the molecule as above
atoms = molecule(’H2O’) atoms.set_cell([7.5, 9, 9]) atoms.center() # the next two lines are equivalent (only one needed)
attach_charges(atoms) attach_charges(atoms, ’ACF.dat’) for atom in atoms: print ’Atom’, atom.symbol, ’Bader charge’, atom.charge
7.23 Electron transport The transport module of ASE assumes the generic setup of the system in question sketched below:
.. .
... There is a central region (blue atoms plus the molecule) connected to two semi-infinite leads constructed by infinitely repeated principal layers (red atoms). The entire structure may be periodic in the transverse direction, which can be effectively sampled using k -points (yellowish atoms). 7.23. Electron transport
177
ASE Manual, Release 3.9.0.3484
The system is described by a Hamiltonian matrix which must be represented in terms of a localized basis set such that each element of the Hamiltonian can be ascribed to either the left, central, or right region, or the coupling between these. The Hamiltonian can thus be decomposed as:
..
. V L † V L H L V L H = V L† H C V R V R† H R V R .. . V † R
where H L/R describes the left/right principal layer, and H C the central region. V L/R is the coupling between principal layers, and from the principal layers into the central region. The central region must contain at least one principal layer on each side, and more if the potential has not converged to its bulk value at this size. The central region is assumed to be big enough that there is no direct coupling between the two leads. The principal layer must be so big that there is only coupling between nearest neighbor layers. Having defined H L/R , V L/R , and H C , the elastic transmission function can be determined using the Nonequilibrium Green Function (NEGF) method. This is achieved by the class: TransportCalculator (in ase.transport.calculators) which makes no requirement on the origin of these five matrices. h, h1, h2, class ase.transport.calculators. TransportCalculator(energies , s=None, s1=None, s2=None, align_bf=False )
Determine transport properties of device sandwiched between semi-infinite leads using non-equillibrium Green function methods. energies is the energy grid on which the transport properties should be determined. h1 (h2) is a matrix representation of the Hamiltonian of two principal layers of the left (right) lead, and the coupling between such layers. h is a matrix representation of the Hamiltonian of the scattering region. This must include at least on lead principal layer on each side. The coupling in (out) of the scattering region is assumed to be identical to the coupling between left (right) principal layers. s, s1, and s2 are the overlap matrices corresponding to h, h1, and h2. Default is the identity operator. If align_bf is True, the onsite elements of the Hamiltonians will be shifted to a common fermi level.
This module is stand-alone in the sense that it makes no requirement on the origin of these five matrices. They can be model Hamiltonians or derived from different kinds of electronic structure codes. For an example of how to use the transport module, see the GPAW exercise on electron transport
7.24 The data module 7.24.1 Atomic data This module defines the following variables: data.atomic_masses data.atomic_names data.chemical_symbols data.covalent_radii data.cpk_colors data.reference_states
178
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
data.vdw_radii
All of these are lists that should be indexed with an atomic number: >>> from ase.data import * >>> atomic_names[92]
’Uranium’ >>> atomic_masses[2] 4.0026000000000002
data.atomic_numbers
If you don’t know the atomic number of some element, then you can look it up in the atomic_numbers dictionary: >>> atomic_numbers[’Cu’]
29 >>> covalent_radii[29]
1.1699999999999999
The covalent radii are taken from [Cordeo08]. The source of the van der Waals radii is given in vdw.py.
7.24.2 Molecular data The G1, G2, and G3-databases are available in the molecules module. Example: >>> from ase.data.molecules import molecule >>> atoms = molecule(’H2O’)
All molecular members of each database is conveniently contained in a list of strings (g1, g2, g3), and one can look up the experimental atomization energy for each molecule. This is extrapolated from experimental heats of formation at room temperature, using calculated zero-point energies and thermal corrections. Example: >>> from ase.data.molecules import molecule, g2, get_atomization_energy >>> g2[11]
where the last line converts the experimental atomization energy of H2O from units of kcal/mol to eV.
7.24.3 S22, s26, and s22x5 data The s22, s26, and s22x5 databases are available in the s22 module. Each weakly bonded complex is identified as an entry in a list of strings (s22, s26, s22x5), and is fully created by a ‘create’-function: >>> from ase.data.s22 import s22, create_s22_system >>> sys = s22[0] >>> sys
The coupled-cluster interaction energies for the s22 and s26 systems are retrieved like this: >>> from ase.data.s22 import s22, get_interaction_energy_s22 >>> get_interaction_energy_s22(s22[0])
-0.1375
in units of eV. For s22 these are not the original energies, but from more recent work where the same (large) basis set was used for all complexes, yielding more accurate coupled-cluster interaction energies. The s22x5 database expands on the original s22 data by introducing non-equilibrium geometries for each complex (0.9, 1.0, 1.2, 1.5, and 2.0 times original intermolecular distance). However, these calculations were done in accordance with the methods used in the original s22 work, and so is expected to inherit the same problems with mixed basis set sizes. Assuming the interaction energy error due to this is the same in all 5 geometries for each complex, the default s22x5 interaction energies are therefore corrected with the energy difference between original and newer energies at the original separation. Example: >>> from ase.data.s22 import * >>> sys1 = s22[0] >>> sys1
where sys1 is an s22 complex in the original geometry, while sys2 and sys3 are two different s22x5 geometries of the exact same complex. It is seen that the interaction energies for an s22 system and its s22x5 equivalent (indexed ‘_1.0’) does not necessarily match when the energy offset-correction is turned off. The last two functions are convenience functions, giving the number of atoms in the two molecules constituting a dimer and the relative intermolecular distance in a dimer (relative to the ‘1.0’ separation, and in Angstrom), respectively.
180
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
7.25 Trajectory files The io.trajectory module defines Trajectory objects, that is objects storing the temporal evolution of a simulation. A Trajectory file contains one or more Atoms objects, usually to be interpreted as a time series, although that is not a requirement. The io.trajectory module currently defines two kinds of Trajectory files, the PickleTrajectory and the BundleTrajectory. PickleTrajectory is the recommended Trajectory format, BundleTrajectory is only intended for large molecular dynamics simulations (large meaning millions of atoms). In the future, other kinds of Trajectories may be defined, with similar Python interface but with different underlying file formats.
7.25.1 PickleTrajectory The PickleTrajectory has the interface class ase.io.trajectory. PickleTrajectory( filename, mode=’r’, atoms=None, master=None, backup=True )
Reads/writes Atoms objects into a .traj file.
A PickleTrajectory can be created in read, write or append mode. Parameters: filename: The name of the parameter file. Should end in .traj. mode=’r’: The
mode.
‘r’ is read mode, the file should already exist, and no atoms argument should be specified. ‘w’ is write mode. If the file already exists, it is renamed by appending .bak to the file name. The atoms argument specifies the Atoms object to be written to the file, if not given it must instead be given as an argument to the write() method. ‘a’ is append mode. It acts a write mode, except that data is appended to a preexisting file. atoms=None:
The Atoms object to be written in write or append mode.
master=None: Controls which process does the actual writing. The default is that process number 0 does
this. If this argument is given, processes where it is True will write. backup=True:
Use backup=False to disable renaming of an existing file.
close()
Close the trajectory file. open( filename, mode)
Opens the file. For internal use only. post_write_attach( function, interval=1, *args, **kwargs)
Attach a function to be called after writing ends. function: The function or callable object to be called. interval: How often the function is called. Default: every time (1). All other arguments are stored, and passed to the function. pre_write_attach( function, interval=1, *args, **kwargs)
Attach a function to be called before writing begins. function: The function or callable object to be called. interval: How often the function is called. Default: every time (1). All other arguments are stored, and passed to the function. 7.25. Trajectory files
181
ASE Manual, Release 3.9.0.3484
set_atoms(atoms=None)
Associate an Atoms object with the trajectory. Mostly for internal use. write(atoms=None)
Write the atoms to the file. If the atoms argument is not given, the atoms object specified when creating the trajectory object is used. Note that there is apparently no methods for reading the trajectory. Reading is instead done by indexing the trajectory, or by iterating over the trajectory: traj[0] and traj[-1] return the first and last Atoms object in the trajectory. Examples
Reading a configuration: from ase.io.trajectory import PickleTrajectory
7.25.2 BundleTrajectory The BundleTrajectory has the interface class ase.io.bundletrajectory. BundleTrajectory( filename, mode=’r’, atoms=None, backup=True )
Reads and writes atoms into a .bundle directory.
The BundleTrajectory is an alternative way of storing trajectories, intended for large-scale molecular dynamics simulations, where a single flat file becomes unwieldy. Instead, the data is stored in directory, a ‘bundle’ (the name bundle is inspired from bundles in Mac OS, which are really just directories the user is supposed to think of as a single file-like unit). Parameters: filename:
The name of the directory. Preferably ending in .bundle.
The file opening mode. ‘r’ means open for reading, ‘w’ for writing and ‘a’ for appending. Default: ‘r’. If opening in write mode, and the filename already exists, the old file is renamed to .bak (any old .bak file is deleted), except if the existing file is empty.
mode (optional):
The atoms that will be written. Can only be specified in write or append mode. If not specified, the atoms must be given as an argument to the .write() method instead.
atoms (optional): backup=True:
Use backup=False to disable renaming of an existing file.
close()
Closes the trajectory. 182
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
classmethod delete_bundle( filename)
Deletes a bundle. static is_bundle( filename)
Check if a filename exists and is a BundleTrajectory. static is_empty_bundle( filename)
Check if a filename is an empty bundle. Assumes that it is a bundle. log(text )
Write to the log file in the bundle. Logging is only possible in write/append mode. This function is mainly for internal use, but can also be called by the user. post_write_attach( function, interval=1, *args, **kwargs)
Attach a function to be called after writing ends. function: The function or callable object to be called. interval: How often the function is called. Default: every time (1). All other arguments are stored, and passed to the function. pre_write_attach( function, interval=1, *args, **kwargs)
Attach a function to be called before writing begins. function: The function or callable object to be called. interval: How often the function is called. Default: every time (1). All other arguments are stored, and passed to the function. read_extra_data(name, n=0 )
Read extra data stored alongside the atoms. Currently only used to read data stored by an NPT dynamics object. The data is not associated with individual atoms. select_data(data, value)
Selects if a given data type should be written. Data can be written in every frame (specify True), in the first frame only (specify ‘only’) or not at all (specify False). Not all data types support the ‘only’ keyword, if not supported it is interpreted as True. The following data types are supported, the letter in parenthesis indicates the default: positions (T), numbers (O), tags (O), masses (O), momenta (T), forces (T), energy (T), energies (F), stress (F), magmoms (T) If a given property is not present during the first write, it will be not be saved at all. set_extra_data(name, source=None, once=False)
Adds extra data to be written. Parameters: name: The name of the data. source (optional): If specified, a callable object returning the data to be written. If not specified it is instead assumed that the atoms contains the data as an array of the same name. once (optional): If specified and True, the data will only be written to the first frame. write(atoms=None)
Write the atoms to the file. If the atoms argument is not given, the atoms object specified when creating the trajectory object is used.
7.25. Trajectory files
183
ASE Manual, Release 3.9.0.3484
7.25.3 See also The function ase.io.write() can write a single Atoms object to a Trajectory file. The function ase.io.read() can read an Atoms object from a Trajectory file, per default it reads the last one.
7.26 Utillity functions and classes 7.26.1 Equation of state The EquationOfState class can be used to find equilibrium volume, energy, and bulk modulus for solids: class ase.utils.eos. EquationOfState(volumes, energies, eos=’sjeos’)
Fit equation of state for bulk systems. The following equation is used: sjeos (default) A third order inverse polynomial fit 10.1103/PhysRevB.67.026103 2 3 E(V) = c + c t + c t + c t , 0 1 2 3
-1/3 t = V
taylor A third order Taylor series expansion about the minimum volume murnaghan PRB 28, 5480 (1983) birch Intermetallic compounds: Principles and Practice, Vol I: Principles. pages 195-210 birchmurnaghan PRB 70, 224107 pouriertarantola PRB 70, 224107 vinet PRB 70, 224107 antonschmidt Intermetallics 11, 23-32 (2003) p3 A third order polynomial fit
Use: eos = EquationOfState(volumes, energies, eos=’sjeos’) v0, e0, B = eos.fit() eos.plot()
7.27 Thermochemistry ASE contains a thermochemistry module that lets the user derive commonly desired thermodynamic quantities of molecules and crystalline solids from ASE output and some user-specified parameters. Three cases are currently handled by this module: the ideal-gas limit (in which translational and rotational degrees of freedom are taken into account), the harmonic limit (generally used for adsorbates, in which all degrees of freedom are treated harmonically), and a crystalline solid model (in which a lattice of N atoms is treated as a system of 3N independent harmonic oscillators). The first two cases rely on good vibrational energies being fed to the calculators, which can be calculated with the vibrations module. Likewise, the crystalline solid model depends on an accurate phonon density of states; this is readily calculated using the phonons module.
7.27.1 Ideal-gas limit The thermodynamic quantities of ideal gases are calculated by assuming that all spatial degrees of freedom are independent and separable into translational, rotational, and vibrational degrees of freedom. The IdealGasThermo class supports calculation of enthalpy ( H ), entropy (S ), and Gibbs free energy (G), and has the interface listed below. class ase.thermochemistry. IdealGasThermo(vib_energies , geometry, electronicenergy=None, atoms=None, symmetrynumber=None , spin=None, natoms=None)
Class for calculating thermodynamic properties of a molecule based on statistical mechanical treatments in the ideal gas approximation. Inputs for enthalpy calculations: [list] a list of the vibrational energies of the molecule (e.g., from ase.vibrations.Vibrations.get_energies). The number of vibrations used is automatically calculated by the geometry and the number of atoms. If more are specified than are needed, then the lowest numbered vibrations are neglected. If either atoms or natoms is unspecified, then uses the entire list. Units are eV.
vib_energies
geometry
[‘monatomic’, ‘linear’, or ‘nonlinear’] geometry of the molecule
electronicenergy [float]
the electronic energy in eV (if electronicenergy is unspecified, then the methods of this class can be interpreted as the enthalpy and free energy corrections)
natoms [integer]
the number of atoms, used along with ‘geometry’ to determine how many vibrations to use. (Not needed if an atoms object is supplied in ‘atoms’ or if the user desires the entire list of vibrations to be used.)
Extra inputs needed for for entropy / free energy calculations: atoms
[an ASE atoms object] used to calculate rotational moments of inertia and molecular mass
symmetrynumber [integer]
symmetry number of the molecule. See, for example, Table 10.1 and Appendix B of C. Cramer “Essentials of Computational Chemistry”, 2nd Ed.
spin
[float] the total electronic spin. (0 for molecules in which all electrons are paired, 0.5 for a free radical with a single unpaired electron, 1.0 for a triplet with two unpaired electrons, such as O_2.)
7.27. Thermochemistry
185
ASE Manual, Release 3.9.0.3484
get_enthalpy(temperature, verbose=True)
Returns the enthalpy, in eV, in the ideal gas approximation at a specified temperature (K). get_entropy(temperature, pressure, verbose=True)
Returns the entropy, in eV/K, in the ideal gas approximation at a specified temperature (K) and pressure (Pa). get_free_energy(temperature, pressure, verbose=True)
Deprecated: use ‘get_gibbs_energy’ instead. get_gibbs_energy(temperature , pressure, verbose=True)
Returns the Gibbs free energy, in eV, in the ideal gas approximation at a specified temperature (K) and pressure (Pa). Example
The IdealGasThermo class would generally be called after an energy optimization and a vibrational analysis. The user needs to supply certain parameters if the entropy or free energy are desired, such as the geometry and symmetry number. An example on the nitrogen molecule is: from ase.data.molecules import molecule from ase.calculators.emt import EMT from ase.optimize import QuasiNewton from ase.vibrations import Vibrations from ase.thermochemistry import IdealGasThermo
This will give the thermodynamic summary output: Enthalpy components at T = 298.15 K: =============================== E_elec 0.263 eV E_ZPE 0.076 eV Cv_trans (0->T) 0.039 eV Cv_rot (0->T) 0.026 eV Cv_vib (0->T) 0.000 eV (C_v -> C_p) 0.026 eV ------------------------------H 0.429 eV =============================== Entropy components at T = 298.15 K and P = 101325.0 Pa: ================================================= S T*S S_trans (1 atm) 0.0015579 eV/K 0.464 eV S_rot 0.0004101 eV/K 0.122 eV S_elec 0.0000000 eV/K 0.000 eV S_vib 0.0000016 eV/K 0.000 eV S (1 atm -> P) -0.0000000 eV/K -0.000 eV
186
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
------------------------------------------------S 0.0019695 eV/K 0.587 eV ================================================= Free energy components at T = 298.15 K and P = 101325.0 Pa: ======================= H 0.429 eV -T*S -0.587 eV ----------------------G -0.158 eV =======================
7.27.2 Harmonic limit In the harmonic limit, all degrees of freedom are treated harmonically. The HarmonicThermo class supports the calculation of internal energy, entropy, and Gibbs free energy. This class uses all of the energies given to it in the vib_energies list; this is a list as can be generated with the .get_energies() method of ase.vibrations.Vibrations , but the user should take care that all of these energies are real (nonimaginary). The class HarmonicThermo has the interface described below. class ase.thermochemistry. HarmonicThermo(vib_energies , electronicenergy=None )
Class for calculating thermodynamic properties in the approximation that all degrees of freedom are treated harmonically. Often used for adsorbates. Inputs: [list] a list of the harmonic energies of the adsorbate (e.g., from ase.vibrations.Vibrations.get_energies). The number of energies should match the number of degrees of freedom of the adsorbate; i.e., 3*n, where n is the number of atoms. Note that this class does not check that the user has supplied the correct number of energies. Units of energies are eV.
vib_energies
electronicenergy [float]
the electronic energy in eV (if electronicenergy is unspecified, then the methods of this class can be interpreted as the energy corrections)
get_entropy(temperature, verbose=True)
Returns the entropy, in eV/K, in the harmonic approximation at a specified temperature (K). get_free_energy(temperature, verbose=True)
Deprecated: use ‘get_gibbs_energy’ instead. get_gibbs_energy(temperature , verbose=True)
Returns the Gibbs free energy, in eV, in the harmonic approximation at a specified temperature (K). get_internal_energy(temperature, verbose=True)
Returns the internal energy, in eV, in the harmonic approximation at a specified temperature (K).
7.27.3 Crystals In this model a crystalline solid is treated as a periodic system of independent harmonic oscillators. The CrystalThermo class supports the calculation of internal energy ( U ), entropy (S ) and Helmholtz free energy (F ), and has the interface listed below. class ase.thermochemistry. CrystalThermo( phonon_DOS , phonon_energies , mula_units=None, electronicenergy=None)
for-
Class for calculating thermodynamic properties of a crystalline solid in the approximation that a lattice of N atoms behaves as a system of 3N independent harmonic oscillators. Inputs: phonon_DOS [list] a list of the phonon density of states, where each value represents the phonon DOS at
the vibrational energy value of the corresponding index in phonon_energies.
7.27. Thermochemistry
187
ASE Manual, Release 3.9.0.3484
[list] a list of the range of vibrational energies (hbar*omega) over which the phonon density of states has been evaluated. This list should be the same length as phonon_DOS and integrating phonon_DOS over phonon_energies should yield approximately 3N, where N is the number of atoms per unit cell. If the first element of this list is zero-valued it will be deleted along with the first element of phonon_DOS. Units of vibrational energies are eV.
phonon_energies
electronicenergy [float]
the electronic energy in eV (if electronicenergy is unspecified, then the methods of this class can be interpreted as the phonon energy corrections.) [int] the number of formula units per unit cell. If unspecified, the thermodynamic quantities calculated will be listed on a per-unit-cell basis.
formula_units
get_entropy(temperature, verbose=True)
Returns the entropy, in eV/K, of crystalline solid at a specified temperature (K). get_helmholtz_energy(temperature , verbose=True)
Returns the Helmholtz free energy, in eV, of crystalline solid at a specified temperature (K). get_internal_energy(temperature, verbose=True)
Returns the internal energy, in eV, of crystalline solid at a specified temperature (K). Example
The CrystalThermo class will generally be called after an energy optimization and a phonon vibrational analysis of the crystal. An example for bulk gold is: from ase.lattice.spacegroup import crystal from ase.calculators.emt import EMT from ase.optimize import QuasiNewton from ase.phonons import Phonons from ase.thermochemistry import CrystalThermo # Set up gold bulk and attach EMT calculator
This will give the thermodynamic summary output: Internal energy components at T = 298.15 K, on a per-formula-unit basis: ===============================
188
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
E_elec 0.0022 eV E_ZPE 0.0135 eV E_phonon 0.0629 eV ------------------------------U 0.0786 eV =============================== Entropy components at T = 298.15 K, on a per-formula-unit basis: ================================================= S T*S ------------------------------------------------S 0.0005316 eV/K 0.1585 eV ================================================= Helmholtz free energy components at T = 298.15 K, on a per-formula-unit basis: ======================= U 0.0786 eV -T*S -0.1585 eV ----------------------F -0.0799 eV =======================
7.27.4 Background The conversion of electronic structure calculations to thermodynamic properties in the ideal-gas limit is well documented; see, for example, Chapter 10 of Cramer, 2004. The key equations used in the IdealGasThermo class are summarized here. Ideal gas.
C.J. Cramer. Essentials of Computational Chemistry , Second Edition. Wiley, 2004. The ideal-gas enthalpy is calculated from extrapolation of the energy at 0 K to the relevant temperature (for an ideal gas, the enthalpy is not a function of pressure): T
H (T ) = E elec + E ZPE +
C P d T
0
where the first two terms are the electronic energy and the zero-point energy, and the integral is over the constantpressure heat capacity. The heat capacity is separable into translational, rotational, vibrational, and electronic parts (plus a term of kB to switch from constant-volume to constant-pressure): C P = k B + C V ,trans + C V ,rot + C V ,vib + C V ,elec
The translational heat capacity is 3/2 kB for a 3-dimensional gas. The rotational heat capacity is 0 for a monatomic species, k B for a linear molecule, and 3/2 kB for a nonlinear molecule. In this module, the electronic component of the heat capacity is assumed to be 0. The vibrational heat capacity contains 3N − 6 degrees of freedom for nonlinear molecules and 3N − 5 degrees of freedom for linear molecules (where N is the number of atoms). The integrated form of the vibrational heat capacity is: T
0
vib DOF
C V, vib dT =
i
i ei /kB T − 1
where i are the energies associated with the vibrational frequencies, i = hω i .
7.27. Thermochemistry
189
ASE Manual, Release 3.9.0.3484
The ideal gas entropy can be calculated as a function of temperature and pressure as: S (T, P ) = S (T, P ◦ ) − kB ln
P P ◦
= S trans + S rot + S elec + S vib − kB ln
P P ◦
where the translational, rotational, electronic, and vibrational components are calculated as below. (Note that the translational component also includes components from the Stirling approximation, and that the vibrational degrees of freedom are enumerated the same as in the above.) S trans = k B
S rot =
0 kB ln
ln
2
8π Ik B T
kB ln
σh2
A B C
vib DOF
S vib = k B
kB T
i
3/2
kB T 5 + ◦ 2 P
√ πI I I σ
2πM kB T h2
+1
8π 2 kB T
3/2
2
h
i ei /kB T
−1
+
3 2
, if monatomic , if linear , if nonlinear
− ln 1 − e−i /kB T
S elec = k B ln[2 × (spin multiplicity) + 1] I A through I C are the three principle moments of inertia for a non-linear molecule. I is the degenerate moment of inertia for a linear molecule. σ is the symmetry number of the molecule.
The ideal-gas Gibbs free energy is then just calculated from the combination of the enthalpy and entropy: G(T, P ) = H (T ) − T S (T, P ) Harmonic limit. The
conversion of electronic structure calculation information into thermodynamic properties is less established for adsorbates. However, the simplest approach often taken is to treat all 3N degrees of freedom of the adsorbate harmonically since the adsorbate often has no real translational or rotational degrees of freedom. This is the approach implemented in the HarmonicThermo class. Thus, the internal energy and entropy of the adsorbate are calculated as harm DOF
U (T ) = E elec + E ZPE +
i
harm DOF
S = k B
i
kB T ei /kB T − 1
i
i /k e i B T
−1
− ln 1 − e−i /kB T
and the Gibbs free energy is calculated as G(T, P ) = U (T ) − T S (T, P )
190
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
In this case, the number of harmonic energies ( i ) used in the summation is generally 3N , where N is the number of atoms in the adsorbate. Crystalline solid
The derivation of the partition function for a crystalline solid is fairly straight-forward and can be found, for example, in Chapter 11 of McQuarrie, 2000. D.A. McQuarrie. Statistical Mechanics . University Science Books, 2000. The treatment implemented in the CrystalThermo class depends on introducing normal coordinates to the entire crystal and treating each atom in the lattice as an independent harmonic oscillator. This yields the partition function 3N e− h¯ ω β Z = e−E elec β 1 − e−h¯ ω β
1 2
j
j
j =1
where ω j are the 3N vibrational frequencies, E elec is the electronic energy of the crystalline solid, and β = kB1T . Now, taking the logarithm of the partition function and replacing the resulting sum with an integral (assuming that the energy level spacing is essentially continuous) gives ∞ h ¯ ωβ − ln Z = E elec β + ln 1 − e−h¯ ωβ + σ(ω)dω
0
2
Here σ(ω) represents the degeneracy or phonon density of states as a function of vibrational frequency. Once this function has been determined (i.e. using the phonons module), it is a simple matter to calculate the canonical ensemble thermodynamic quantities; namely the internal energy, the entropy and the Helmholtz free energy. U (T ) = −
∂ ln Z ∂β
∞
= E elec +
0
N,V
h ¯ω ¯hω + σ(ω)dω h ωβ ¯ e −1 2
U + kB ln Z T ∞ ¯hω 1 = − kB ln 1 − e−¯hωβ h ωβ ¯ T e −1 0
S (T ) =
σ(ω)dω
F (T ) = U (T ) − T S (T, P )
7.28 Building neighbor-lists The EMT potential and the GPAW DFT calculator both make use of ASE’s built-in neighbor-list class: class ase.calculators.neighborlist. NeighborList(cutoffs, skin=0.3, sorted=False, self_interaction=True, bothways=False )
Neighbor list object.
cutoffs: list of float List of cutoff radii - one for each atom.
If no atom has moved more than the skin-distance since the last call to the update() method, then the neighbor list can be reused. This will save some expensive rebuilds of the list, but extra neighbors outside the cutoff will be returned.
skin: float
7.28. Building neighbor-lists
191
ASE Manual, Release 3.9.0.3484
self_interaction: bool Should an atom return itself as a neighbor? bothways: bool Return all neighbors. Default is to return only “half” of the neighbors.
Return neighbors of atom number a. A list of indices and offsets to neighboring atoms is returned. The positions of the neighbor atoms can be calculated like this: indices, offsets = nl.get_neighbors(42) for i, offset in zip(indices, offsets): print atoms.positions[i] + dot(offset, atoms.get_cell())
Notice that if get_neighbors(a) gives atom b as a neighbor, then get_neighbors(b) will not return a as a neighbor - unless bothways=True was used. update(atoms)
Make sure the list is up to date.
7.29 Setting up an OPLS force field calculation In order to facilitate the definition of structures for the use of OPLS force fields, there are some helper classes.
7.29.1 Modified xyz Suppose, we define the ethanal molecule as an modified xyz file ( 172_mod.xyz ): 7 # ethanal from ChemSpider O 1.613900000000000 CT -0.327900000000000 C 0.392400000000000 HC -0.960000000000000 HC -0.960000000000000 HC 0.346400000000000 H1 -0.104900000000000
Then we can read and view the structure using: from ase.visualize import view from ase.io.opls import OPLSStructure
s = OPLSStructure(’172_mod.xyz’) # 172_mod.xyz if the file name for the structure above view(s) # view with real elements elements = { ’CT’ : ’Si’, ’HC’ : ’H’, ’H1’ : ’He’ } view(s.colored(elements)) # view with fake elements
7.29.2 Defining the force field The definitions of the force field can be stored in an Amber like style ( 172_defs.par ):
192
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
# the blocks are separated by empty lines # comments are allowed # # one body - LJ-parameters and charge CT 0.0028619844 3.50 0.000 C 0.0028619844 3.50 0.000 O 0.0073717780 3.12 -0.683 HC 0.0013009018 2.50 0.000 H1 0 0 0 # bonds C -CT 3 17.0 C -O 570.0 CT-HC 340.0 C -H1 340.0 # angles CT-C -O HC-CT-HC CT-C -H1
1.522 1.229 1.090 1.090
80.0 35.0 70.0
# dihedrals O -C -CT-HC
JCC,7,(1986),230; AA JCC,7,(1986),230; AA,CYT,GUA,THY,URA changed from 331 bsd on NMA nmodes; AA, SUGARS
120.40 109.50 117.00
0.00000 6.02496E-01
-3
# cutoffs C -CT 2.0 C -O 1.8 CT-HC 1.4 C -H1 1.4 C3-O1 1.8 # extra stuff, should not bother
We can write LAMMPS input using the information above: from ase.io.opls import OPLSff, OPLSStructure
s = OPLSStructure(’172_mod.xyz’) opls = OPLSff(’172_defs.par’) opls.write_lammps(s, prefix=’lmp’)
which writes the LAMMPS input files lmp_atoms defining atoms, bonds, etc., and lmp_opls defining the corresponding OPLS force field. A rudimentary lmp_in is also written.
7.30 A database for atoms ASE has its own database that can be used for storing and retrieving atoms and associated data in a compact and convenient way. Note:
This is work in progress. Use at your own risk!
There are currently three back-ends: JSON: Simple human-readable text file with a .json extension. SQLite3:
Self-contained, server-less, zero-configuration database. Lives in a file with a .db extension.
PostgreSQL: Server based database.
The JSON and SQLite3 back-ends work “out of the box”, whereas PostgreSQL requires a server. There is a command-line tool called ase-db that can be used to query and manipulate databases and also a Python interface.
7.30. A database for atoms
193
ASE Manual, Release 3.9.0.3484
Contents
• A database for atoms – What’s in the database? – Command-line tool – Integration with other parts of ASE – Python Interface * More details
7.30.1 What’s in the database? Every row in the database contains: • all the information stored in the Atoms object (positions, atomic numbers, ...) • calculator name and parameters (if a calculator is present) • already calculated properties such as energy and forces (if a calculator is present) • keywords and key-value pairs (for finding the calculation again) • an integer ID (unique for each database) starting with 1 and always increasing for each new row • a unique ID which is a 128 bit random number which should be globally unique (at least in the lifetime of our universe) • constraints (if present) • user-name • creation time
7.30.2 Command-line tool The ase-db command can be used to query databases and for manipulating keywords and key-value pairs. Try: $ ase-db --help
Example: Show all rows of SQLite database abc.db: $ ase-db abc.db id|age|user |formula|calc|energy| fmax|pbc|keywords|keyvals | mass 1|6s |jensj|H2 |emt | 1.419|9.803|000|molecule|relaxed=False|2.016 2|5s |jensj|H2 |emt | 1.071|0.000|000|molecule|relaxed=True |2.016 3|5s |jensj|H |emt | 3.210|0.000|000| | |1.008
Show all details for a single row: $ ase-db abc.db id=3 -l id: 3 formula: H user: jensj age: 174s calculator: emt energy: 3.210 eV maximum atomic force: 0.000 eV/Ang magnetic moment: 0 periodic boundary conditions: [False False False] unit cell [Ang]: 1.000 0.000 0.000 0.000 1.000 0.000 0.000 0.000 1.000
194
Chapter 7. Documentation for modules in ASE
ASE Manual, Release 3.9.0.3484
volume: 1.000 Ang^3 mass: 1.008 au
Here are some example query strings: v3 abc=H v3,abc=H calculator=nwchem 2.2=10 H<3 id=2345 age<1h age>1y
has ‘v3’ keyword has key ‘abc’ with value ‘H’ both of the above calculations done with NWChem ‘bandgap’ key has value between 2.2 and 3.0 10 or more atoms less than 3 hydrogen atoms specific id not older than 1 hour older than 1 year
These names are special: id natoms energy charge magmom calculator user age
integer identifier number of atoms potential energy total charge total magnetic moment name of calculator who did it age of calculation (use s, m, h, d, w, M and y for second, minute, hour, day, week, month and year respectively)
7.30.3 Integration with other parts of ASE ASE’s ase.io.read() function can also read directly from databases: >>> from ase.io import read >>> a = read(’abc.db@42’) >>> a = read(’abc.db@id=42’) # same thing >>> b = read(’abc.db@v3,abc=H’)
Also the ase-gui program can read from databases using the same syntax.
7.30.4 Python Interface First, we connect() to the database: >>> from ase.db import connect >>> c = connect(’abc.db’)
or >>> import ase.db >>> c = ase.db.connect(’abc.db’)
Let’s do a calculation for a hydrogen molecule and write some results to a database: >>> from ase import Atoms >>> from ase.calculators.emt import EMT >>> h2 = Atoms(’H2’, [(0, 0, 0), (0, 0, 0.7)]) >>> h2.calc = EMT() >>> h2.get_forces()
7.30. A database for atoms
195
ASE Manual, Release 3.9.0.3484
array([[ 0. [ 0.
, ,
0. 0.
, -9.80290573], , 9.80290573]])
Write a row to the database with keyword ’molecule’ and a key-value pair (’relaxed’ , False): >>> c.write(h2, [’molecule’], relaxed=False)
1
The write() method returns an integer id. Do one more calculation and write results: >>> from ase.optimize import BFGS >>> BFGS(h2).run(fmax=0.01)
Loop over selected rows using the select() method: >>> for d in c.select(’molecule’): ... print d.forces[0, 2], d.relaxed ...
-9.8029057329 False -9.2526347333e-05 True
The select() method will generate dictionaries that one can loop over. The dictionaries are special in the sense that keys can be accessed as attributes also ( d.relaxed == d[’relaxed’] ). Write the energy of an isolated hydrogen atom to the database: >>> h = Atoms(’H’) >>> h.calc = EMT() >>> h.get_potential_energy()
3.21 >>> c.write(h) 3
Select a single row with the get() method: >>> d = c.get(relaxed=1, calculator=’emt’) >>> for k, v in d.items(): ... print ’%-25s: %s’ % (k, v) ...
user key_value_pairs timestamp energy relaxed calculator_parameters cell numbers forces positions keywords pbc id unique_id calculator
Create connection to database. name: str Filename or address of database.
One of ‘json’, ‘db’ or ‘pg’ (JSON, SQLite, PostgreSQL). Default is ‘extract_from_name’, which will ... guess the type from the name.
type: str
use_lock_file: bool
You can turn this off iff you know what you are doing ...
class ase.db.core. Database( filename=None, create_indices=True , use_lock_file=False )
Base class for all databases. write(*args, **kwargs)
Write atoms to database with keywords and key-value pairs. atoms: Atoms object Write
atomic numbers, positions, unit cell and boundary conditions. If a calculator is attached, write also already calculated properties such as the energy and forces.
keywords: list of str List of keywords. key_value_pairs: dict
Dictionary of key-value pairs. Values must be strings or numbers.
data: dict Extra stuff (not for searching).
Key-value pairs can also be set using keyword arguments: connection.write(atoms, name=’ABC’, frequency=42.0)
reserve(*args, **kwargs)
Write empty row if not already present. Usage: id = conn.reserve(’keyword1’, ’keyword2’, ..., key1=value1, key2=value2, ...)
Write an empty row with the given keywords and key-value pairs and return the integer id. If such a row already exists, don’t write anything and return None. get_atoms(selection=None, attach_calculator=False , add_additional_information=False , **kwargs )
Get Atoms object.
selection: int, str or list See the select() method. attach_calculator: bool
Attach calculator object to Atoms object (defaul value is False).
add_additional_information: bool Put
keywords, key-value pairs and data into Atoms.info dictio-
nary.
7.30. A database for atoms
197
ASE Manual, Release 3.9.0.3484
get(selection=None, fancy=True, **kwargs)
Select a single row and return it as a dictionary. selection: int, str or list See the select() method. fancy: bool
return fancy dictionary with keys as attributes (this is the default).
Return iterator with results as dictionaries. Selection is done using key-value pairs, keywords and the special keys: age, user, calculator, natoms, energy, magmom and/or charge. selection: int, str or list Can
be:
• an integer id • a string like ‘key=value’, where ‘=’ can also be one of ‘<=’, ‘<’, ‘>’, ‘>=’ or ‘!=’. • a string like ‘keyword’ • comma separated strings like ‘key1
return fancy dictionary with keys as attributes (this is the default).
filter: function
A function that takes as input a dictionary and returns True or False.
explain: bool Explain query plan. verbosity: int Possible values: 0, 1 or 2. limit: int or None Limit
selection.
update(*args, **kwargs)
Update row(s). ids: int or list of int ID’s of rows to update. add_keywords: list of str List of keyword strings to add to rows. add_key_value_pairs: dict
Key-value pairs to add.
returns number of keywords and key-value pairs added. delete(ids)
Delete rows.
198
Chapter 7. Documentation for modules in ASE
CHAPTER
EIGHT
FREQUENTLY ASKED QUESTIONS 8.1 ASE-GUI See also the documentation for ase-gui.
8.1.1 How do I export images from a trajectory to png or pov files? With ase-gui, you can choose File → Save, but this is not fun if you need to do it for many images. Here is how to do it on the command line for a number of images: ase-gui images.traj@0 -o image0.pov ase-gui images.traj@1 -o image1.pov ase-gui images.traj@2 -o image2.pov
If you have many images, it will be easier to do it using the Python interpreter: >>> from ase import * >>> for n, image in enumerate(read(’images.traj@:3’)): write(’image%d .pov’ % n, image, run_povray=True, pause=False, ... rotation=’-90x,10z’) ...
Here, we also: • run povray to generate png files • disable pausing between the images • set a rotation (choose View → Rotate ... in ase-gui to select the best rotation angles) Try: >>> help(write)
to see all possibilities or read more here.
8.2 General 8.2.1 Citation: how should I cite ASE? If you find ASE useful in your research please cite: S. R. Bahn and K. W. Jacobsen An object-oriented scripting interface to a legacy electronic structure code Comput. Sci. Eng., Vol. 4 , 56-66, 2002 BibTex (doc/ASE.bib):
199
ASE Manual, Release 3.9.0.3484
@Article{ISI:000175131400009, Author = {S. R. Bahn and K. W. Jacobsen}, Title = {An object-oriented scripting interface to a legacy electronic structure code}, JournalFull = {COMPUTING IN SCIENCE \& ENGINEERING}, Year = {2002}, Volume = {4}, Number = {3}, Pages = {56-66}, Month = {MAY-JUN}, Abstract = {The authors have created an object-oriented scripting interface to a mature density f code. The interface gives users a high-level, flexible handle on the code without rewriting the underlying number-crunching code. The authors also discuss the design issues and advantages of homogeneous interfaces}, Publisher = {IEEE COMPUTER SOC}, Address = {10662 LOS VAQUEROS CIRCLE, PO BOX 3014, LOS ALAMITOS, CA 90720-1314 USA}, Type = {Article}, Language = {English}, Affiliation = {Bahn, SR (Reprint Author), Tech Univ Denmark, Dept Phys, CAMP, Bldg 307, DK-2800 L Tech Univ Denmark, Dept Phys, CAMP, DK-2800 Lyngby, Denmark.}, ISSN = {1521-9615}, Keywords-Plus = {MULTISCALE SIMULATION; GOLD ATOMS}, Subject-Category = {Computer Science, Interdisciplinary Applications}, Author-Email = {[email protected][email protected]}, Number-of-Cited-References = {19}, Journal-ISO = {Comput. Sci. Eng.}, Journal = {Comput. Sci. Eng.}, Doc-Delivery-Number = {543YL}, Unique-ID = {ISI:000175131400009}, DOI = {10.1109/5992.998641}, }
8.3 Download Trying to checkout the code via SVN resulted: [~]$ svn checkout "https://svn.fysik.dtu.dk/projects/ase/trunk" svn: Unrecognized URL scheme ’https://svn.fysik.dtu.dk/projects/ase/trunk’
This error is diplayed in case the library ‘libsvn_ra_dav’ is missing on your system. The library is used by SVN, but is not installed by default.
200
Chapter 8. Frequently Asked Questions
CHAPTER
NINE
GLOSSARY API
Application Programming Interface. Automatically generated documentation from docstrings in the source code using Epydoc. See here.
ASE
Atomic Simulation Environment. XXX
Class
Constructor
XXX
XXX
Docstring DFT
Density Functional Theory.
EMT
Effective Medium Theory.
HF
Hartree-Fock approximation XXX ...
Instance
XXX
In the linearized augmented plane wave (LAPW) method the unit cell of the crystal is divided into two different types of regions. The first one, called the muffin-tin region, consists of spheres centered around the atoms, while the second one, called the interstitial region consists of the remaining part of the unit cell. In the muffin-tin spheres the basis consists of atomic like functions to account for the rapid changes of the wave function in this area, whereas in the interstitial region the basis functions are plane waves, since the wave function changes only slowly at some distance from the atomic sites.
LAPW
Namespace
An abstract container of the current scope‘s variables.
ndarray NumPy‘s n -dimensional array. See Numeric arrays in Python .
XXX See Numeric arrays in Python .
NumPy Method Python Scope
XXX XXX What is Python? .
An enclosing context where values and expressions are associated.
201
ASE Manual, Release 3.9.0.3484
202
Chapter 9. Glossary
CHAPTER
TEN
MAILING LISTS There is a mailing list for discussing ASE: • ase-users The mailing lists below are of interest for active ASE developers only: • ase-developers • ase-svncheckins or (mainly) dacapo / ASE-2 users / developers: • campos • campos-devel
10.1 Internet Relay Chat We have the IRC channel #campos on FreeNode. Please join us if you have any questions. For easy access, you can use this webclient.
203
ASE Manual, Release 3.9.0.3484
204
Chapter 10. Mailing Lists
CHAPTER
ELEVEN
LICENSE Contents
• License – Human-readable version – Legal version of the license – What happens when ASE Calculators are under another license?
11.1 Human-readable version ASE is released under the GNU Lesser General Public License (LGPL). In short, this means • NO WARRANTY: We provide the code free of charge. You cannot sue us if it does not work, gives wrong results, or even if it damages your computer and/or scientific reputation. • You may use the code for whatever you like. You may study and modify it. • You may distribute distribute modified or unmodified versions of ASE as long as you do it under the LGPL (or GPL) licence. You may distribute unmodified versions of ASE together with software under other licences (even commercial) as long as ASE itself is clearly identified as being under the LGPL, but if you modify ASE for such purposes you are required to make the modifications available under the LGPL. Note that we appreciate that you send modifications, bug fixes and improvements back to us instead of just distributing them, but the license has no such requirements. You can read more about the LGPL on Wikipedia.
11.2 Legal version of the license Please read the full text of the GNU Lesser General Public License (as published by the Free Software Foundation).
11.3 What happens when ASE Calculators are under another license? We are sometimes asked if it is problematic to use ASE together with calculators under other licenses, for example GPL. It is clear that a program under the GPL can use a library under the LGPL, whereas a program under the LGPL cannot be derived from (and link) a library under the GPL. Does this cause a problem if someone uses ASE with a calculator such as GPAW licensed under the GPL? We do not think so, for the following reasons: 1. The LGPL and GPL do not limit how you use the codes, only how you distribute them.
205
ASE Manual, Release 3.9.0.3484
2. ASE does not require any specific calculator to function, but many calculators require ASE to function, supporting the interpretation that ASE is a library for the calculator. 3. Although ASE includes a few cases where it imports calculators such as GPAW and Asap, these can be regarded as “hooks” helping ASE to support these calculators, ASE does not depend on these calculators for its functionality. 4. The LGPL / GPL concept of “derived work” relies on the concept of “linking” which only makes sense in compiled languages. It is generally agreed that it is unproblematic when an interpreted language uses different modules under different licenses. See e.g. this statement by Fedora: Mere use of independent modules in a true interpreted language environment (like Perl or Python) is not a situation where Fedora is generally concerned about license compatibility, as long as those multiply licensed modules are not compiled together into a single binary and there is no code copying between the two.
5. The actual executable doing the linkage is not ASE, but Python. However, nobody doubts that it is OK for Python (which has a very permissible license) to load modules licensed under the GPL. Probably because of point 1 above. 6. Point 5 is not valid when running parallel GPAW or Asap calculations. In these cases GPAW and Asap provide specially built Python executables with the GPAW or Asap code built-in, i.e. derived work based on Python but licensed under the GPL (or LGPL for Asap). In these cases it is absolutely clear that it is GPAW or Asap loading ASE, not the other way around; so there are no problems.
206
Chapter 11. License
CHAPTER
TWELVE
ASE DEVELOPMENT As a developer, you should subscribe to all ASE related Mailing Lists.
12.1 Development topics 12.1.1 Release notes Development version in trunk
trunk. Version 3.8.0
22 October 2013: tags/3.8.0. • ASE’s gui renamed from ag to ase-gui. • New STM module. • Python 2.6 is now a requirement. • The old ase.structure.bulk() function is now deprecated. (ase.lattice.bulk() ).
Use the new one instead
• We’re now using BuildBot for continous integration: https://ase-buildbot.fysik.dtu.dk/waterfall • New interface to the JDFTx code. Version 3.7.0
13 May 2013: tags/3.7.0. • ASE’s GUI can now be configured to be more friendly to visually impaired users: High contrast settings for ase-gui . • The ase.neb.NEB object now accepts a list of spring constants. • Important backwards incompatible change : The ase.lattice.surface.surface() function now returns a right-handed unit cell. • Mopac, NWChem and Gaussian interfaces and EAM potential added. • New set_initial_charges() and get_initial_charges() methods. The get_charges() method will now ask the calculator to calculate the atomic charges. • The Calculator interface proposal has been implemented and 6 ASE calculators are now based on the new base classes.
207
ASE Manual, Release 3.9.0.3484
• ASE now runs on Windows and Mac. • Constrained minima hopping (global optimization) added to ASE. Version 3.6.0
24 Feb 2012: tags/3.6.0. • ASE GUI translations added, available: da_DK, en_GB, es_ES. • New function for making surfaces with arbitrary Miller indices with the smallest possible surface unit cell: ase.lattice.surface.surface() • New ase.lattice.bulk() function. Will replace old ase.structure.bulk() function. The new one will produce a more natural hcp lattice and it will use experimental data for crystal structure and lattice constants if not provided explicitely. • New values for ase.data.covalent_radii from Cordeo et al.. • New command line tool: Command line tool and tests based on it: abinit, elk, fleur, nwchem. • New crystal builder for ase-gui • Van der Waals radii in ase.data • ASE’s GUI (ase-gui) now supports velocities for both graphs and coloring • Cleaned up some name-spaces: – ase now contains only Atoms and Atom – ase.calculators is now empty
Version 3.5.1
24 May 2011: tags/3.5.1. • Problem with parallel vibration calculations fixed: Ticket #80. Version 3.5.0
13 April 2011: tags/3.5.0. • Improved EMT potential: uses a NeighborList object and is now ASAP compatible. • BFGSLineSearch is now the default ( QuasiNewton==BFGSLineSearch ). • There is a new interface to the LAMMPS molecular dynamics code. • New phonons module. • Van der Waals corrections for DFT, see GPAW usage. • New BundleTrajectory added. • Updated GUI interface: – Stability and usability improvements. –
Povray render facility.
– Updated expert user mode. – Enabled customization of colours and atomic radii. – Enabled user default settings via ~/.ase/gui.py .
• Database library expanded to include:
208
Chapter 12. ASE development
ASE Manual, Release 3.9.0.3484
–
The s22, s26 and s22x5 sets of van der Waals bonded dimers and complexes by the Hobza group.
–
The DBH24 set of gas-phase reaction barrier heights by the Truhlar group.
• Implementation of the Dimer method. Version 3.4.1
11 August 2010: tags/3.4.1.
12.1.2 How to contribute Discussion of ASE development takes place on the ase-developer mailing list, and also sometimes on the #gpaw IRC channel on freenode. We welcome new developers who would like to help work on improving ASE. If you would like to contribute, your should first tell us what you want to work on. Use the mailing list for that. SVN access
We don’t give new contributers write access to our SVN repository from day one. So, you will have to create a patch and send it to the mailing list: $ $ $ $
svn checkout https://svn.fysik.dtu.dk/projects/ase/trunk myase cd myase # do your thing ... svn diff > patch.txt
Before you send the patch, please read our Coding Conventions and learn how to use pep8.py, pylint and epydoc: • Run pep8.py on your code • Using pylint to check your code • Run epydoc on your code One of the current committers will look at the patch and give you some feedback. Maybe the patch is fine and the committer will commit it to trunk. There could also be some more work to do like: • make it compatible with all supported pythons (see Installation requirements). • write more comments • fix docstrings • write a test • add some documentation Once everyone is happy, the patch can be applied. This patch-feedback loop is not something we have invented to prevent you from contributing - it should be viewed as an opportunity for you to learn how to write code that fits into the ASE codebase. After a couple of contributions, we will probably trust you enough to add you as a committer. Committers
Here is the list of current committers: user name
real name
anpet askhl
Andrew Peterson Ask Hjorth Larsen
12.1. Development topics
andrew_peterson:brown,edu asklarsen:gmail,com Continued on next page 209
Table 12.1 – continued from previous page real name
Jonas Bjork David Landis Marcin Dulak Elvar Örn Jónsson Gaël Donval George Tritsaris Lars Grabow Heine Anton Hansen Ivano Eligio Castelli Jakob Blomquist Jon Bergmann Maronsson Janne Blomqvist Jens Jørgen Mortensen Jesper Friis Jess Wellendorff Pedersen Jingzhe Chen John Kitchin Jussi Enkovaara Kristen Kaasbjerg Jesper Kleis Karsten Wedel Jacobsen Markus Kaukonen Michael Walter Poul Georg Moses Marco Vanin Lars Pastewka Christian Glinsvad Stephan Schenk Jakob Schiotz Mattias Slabanja Mikkel Strange Tao Jiang Thomas Olsen
Former committers: anro Anthony Goodrow carstenr Carsten Rostgaard hanke Felix Hanke s042606 Janosch Michael Rauba s052580 Troels Kofoed Jacobsen
12.1.3 Using version control (SVN) The version control system used in ASE development is subversion. A thorough subversion manual can be found at http://svnbook.red-bean.com/ , here is a brief overview of the most basic features needed when developing ASE. • perform svn checkout of ase. Place it, for example, in ase-svn directory: cd svn checkout https://svn.fysik.dtu.dk/projects/ase/trunk ase-svn
This retrieves the code tree from the subversion repository. Prepend PYTHONPATH and PATH environment variables as described at Manual installation . 210
Chapter 12. ASE development
ASE Manual, Release 3.9.0.3484
• Updating the working copy of the code (in the directory ase-svn): svn update
After each (important) update, remove ase/svnrevision.py * files, and run: python setup.py sdist
to keep the ase/svnrevision.py file up-to-date. • Checking the status of the working copy (in the directory ase-svn): svn stat
The status about the files which are not in version control can be surpassed with the -q flag, and the status with respect to latest additions in server can be checked with the -u flag. • Committing the changes to the repository Before sending the changes in the working copy to the repository, working copy should be updated. After that, the changes can be send with: svn commit -m "Message to describe the committed changes"
If the -m option is omitted and appropriate environment variable SVN_EDITOR is set, an editor is opened for writing the log message. • Adding files or directories to version control: svn add filename
If filename is directory, also all the files within the directory are added. Note that svn commit is required before the new files are actually included in version control. • ASE documentation resides under doc directory, and is also under subversion control. See more at Writing documentation.
12.1.4 Coding Conventions Importing modules
In code, like the implementation of ASE, we must not use the import * syntax. Import everything explicitly from exactly the place where it’s defined: from ase.io import read, write
We distinguish between scripts and code. In your own scripts, it’s OK to use: from ase.all import *
which will give you the most used symbols. Python Coding Conventions
Please run pep8.py and pylint on your code before committing. The rules for the Python part are almost identical to those used by the Docutils project: Contributed code will not be refused merely because it does not strictly adhere to these conditions; as long as it’s internally consistent, clean, and correct, it probably will be accepted. But don’t be surprised if the “offending” code gets fiddled over time to conform to these conventions. The project shall follow the generic coding conventions as specified in the Style Guide for Python Code and Docstring Conventions PEPs, summarized, clarified, and extended as follows:
12.1. Development topics
211
ASE Manual, Release 3.9.0.3484
• 4 spaces per indentation level. No hard tabs. • Very important: Read the Whitespace in Expressions and Statements section of PEP8. • Avoid introducing trailing whitespaces. • Try to use only 7-bit ASCII, no 8-bit strings. • No one-liner compound statements (i.e., no if x: return: use two lines & indentation), except for degenerate class or method definitions (i.e., class X: pass is OK.). • Lines should be no more than 78 characters long. • Use “StudlyCaps” for class names. • Use “lowercase” or “lowercase_with_underscores” for function, method, and variable names. For short names, maximum two words, joined lowercase may be used (e.g. “tagname”). For long names with three or more words, or where it’s hard to parse the split between two words, use lowercase_with_underscores (e.g., “note_explicit_target”, “explicit_target”). If in doubt, use underscores. • Avoid lambda expressions, which are inherently difficult to understand. Named functions are preferable and superior: they’re faster (no run-time compilation), and well-chosen names serve to document and aid understanding. • Avoid functional constructs (filter, map, etc.). Use list comprehensions instead. • Avoid from __future__ import constructs. They are inappropriate for production code. • Use ‘single quotes’ for string literals, and “”“triple double quotes”“” for docstrings. Double quotes are OK for something like "don’t". Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out. Georg Brandl Attention:
General advice
• Get rid of as many break and continue statements as possible. Writing documentation in the code
Here is an example of how to write good docstrings: http://projects.scipy.org/numpy/browser/trunk/doc/example.py Run pep8.py on your code
The pep8.py program is installed together with ASE tools/pep8.py. It will check the PEP8 conventions for you. Try: $ pep8.py --help
Using pylint to check your code
A pylintrc trying to follow ASE Coding Conventions can be found here: doc/development/pylintrc
212
Chapter 12. ASE development
ASE Manual, Release 3.9.0.3484
Running pylint yourself
Run pylint on a single file like this: [~]$ pylint mypythonfile.py
Run pylint on a module like this: [~]$ pylint path/to/module/root/dir
Output from pylint run on ASE
• pylint_ase Run epydoc on your code
Run: $ epydoc --docformat restructuredtext --parse-only --show-imports -v dir
12.1.5 Writing documentation We use the Sphinx tool to generate the documentation (both HTML and PDF). The documentation is stored in SVN as text files in the doc directory using the reStructuredText markup language. Installing Docutils and Sphinx
The reStructuredText parser that Sphinx needs, is part of the Docutils project. So, we need to install docutils and sphinx (version>= 0.5). Other requirements
When building the documentation, a number of png-files are generated. For that to work, you need the following installed: • matplotlib • povray • dvipng • pdflatex • bibtex • AUCTex • convert (ImageMagick) Using Sphinx
First, you should take a look at the documentation for Sphinx and reStructuredText. If you don’t already have your own copy of the ASE package, then get the Latest development release and install it. Then cd to the doc directory and build the html-pages:
12.1. Development topics
213
ASE Manual, Release 3.9.0.3484
$ cd ~/ase/doc $ sphinx-build . _build
Make sure that you build the Sphinx documentation using the corresponding ASE version by setting the environment variables $PYTHONPATH and $PATH. Note:
Make your changes to the .rst files, run the sphinx-build command again, check the results and if things looks ok, commit: $ emacs index.rst $ sphinx-build . _build $ firefox _build/index.html $ svn ci -m "..." index.rst
To build a pdf-file, you do this: $ sphinx-build -b latex . _build $ cd _build $ make ase-manual.pdf
Extensions to Sphinx
We have a couple of extensions to Sphinx: :mol:
Use :mol:‘CH_3OH‘ to get CH3 OH. :svn:
A role for creating a link to a file in SVN. If you write :svn:‘ase/atoms.py‘ , you will get: ase/atoms.py. :trac:
A role for creating a link to a file in Trac. If you write :trac:‘ase/atoms.py‘ , you will get: ase/atoms.py. :epydoc:
A role for creating a link to the API-documentation generated with epydoc. :epydoc:‘ase.atoms.Atoms‘ , you will get: Atoms.
If you write
:math:
This role is for inline LaTeX-style math. Example: :math:‘\sin(x_n^2)‘ gives you sin(x2n ). This role is actually the default for ASE’s documentation, so you can leave out the :math: part like here: ‘\sin(x_n^2)‘ . .. math::
If you want to include a picture in your page, you should not check in the png-file to our SVN repositoy! Instead, you should check in the Python script you used to generate the picture (you can also generate csv-files or pdf-files like this). The first line of the script should look like this: # creates: fig1.png fig2.png table1.csv
Sphinx will run the script and generate the files that you can then use in your rst-file. Examples: • Equation of state . Source: doc/tutorials/eos/eos.py, doc/tutorials/eos/eos.rst • Finding lattice constants . Source: doc/tutorials/lattice_constant.py, doc/tutorials/lattice_constant.rst reStructedText in emacs
For people using emacs, the reStructuredText extension is highly recommended. The intallation procedure is described in the top of the file, but for most people, it is enough to place it in your emacs load-path (typically .emacs.d/ ) and add the lines: (add-to-list ’load-path "~/.emacs.d") (require ’rst)
somewhere in your .emacs file. To make the mode auto load for relevant file extension, you can write something like: (setq auto-mode-alist (append ’(("\\.rst$" . rst-mode) ("\\.rest$" . rst-mode)) auto-mode-alist))
In your .emacs file. Updating Sphinx
Starting a new project with sphinx requires an initial configuration. This is achieved by running sphinxquickstart. When updating from a very old sphinx you may consider generating new configuration files and updating the old files accordingly. Note that the current project is configured up-to-date, so if you are “simply” writing the documentation you must skip the sphinx-quickstart step and focus on Using Sphinx .
Here is how do you setup the GPAW project with sphinx: • cd to the doc directory, • run sphinx-quickstart and answer the questions (example given for GPAW): > Root path for the documentation [.]: > Separate source and build directories (y/N) [n]: > Name prefix for templates and static dir [.]: _ > Project name: GPAW > Author name(s): 2008, CAMd et al. > Project version: 0.5 > Project release [0.5]: > Source file suffix [.rst]: > Name of your master document (without suffix) [index]: contents
12.1. Development topics
215
ASE Manual, Release 3.9.0.3484
> autodoc: automatically insert docstrings from modules (y/N) [n]: y > doctest: automatically test code snippets in doctest blocks (y/N) [n]: > intersphinx: link between Sphinx documentation of different projects (y/N) [n]: y
This will create doc/conf.py and doc/contents.rst . Both these files need to be edited further (doc/conf.py may for example include options for sphinx.ext.pngmath )
12.1.6 Adding new calculators Adding an ASE interface to your favorite force-calculator is very simple. Take a look at the Calculator and FileIOCalculator classes below (the code is here: ase/calculators/calculator.py). You should inherit from the FileIOCalculator and implement the read(), read_results() and write_input() methods. The methods set(), check_state() and set_label() may also need to be implemented. See Also:
• The code for our Abinit interface: ase/calculators/abinit.py • Calculator interface proposal • calculators Description of base-classes The Calculator base-class
class ase.calculators.calculator. Calculator(restart=None, ignore_bad_restart_file=False , label=None, atoms=None, **kwargs)
Base-class for all ASE calculators.
A calculator must raise NotImplementedError if asked for a property that it can’t calculate. So, if calculation of the stress tensor has not been implemented, get_stress(atoms) should raise NotImplementedError. This can be achieved simply by not including the string ‘stress’ in the list implemented_properties which is a class member. These are the names of the standard properties: ‘energy’, ‘forces’, ‘stress’, ‘dipole’, ‘charges’, ‘magmom’ and ‘magmoms’. Basic calculator implementation. restart: str Prefix for restart file. May contain a directory. Default is None: don’t restart. ignore_bad_restart_file: bool Ignore broken or missing restart file. By default, it is an error if the restart
file is missing or broken. label: str
Name used for all files. May contain a directory.
Optional Atoms object to which the calculator will be attached. When restarting, atoms will get its positions and unit-cell updated from file.
atoms: Atoms object
implemented_properties = []
Properties calculator can handle (energy, forces, ...) default_parameters = {}
Default parameters set_label(label)
Set label and convert label to directory and prefix. Examples: •label=’abc’: (directory=’.’, prefix=’abc’) •label=’dir1/abc’: (directory=’dir1’, prefix=’abc’)
216
Chapter 12. ASE development
ASE Manual, Release 3.9.0.3484
Calculators that must write results to files with fixed names can overwrite this method so that the directory is set to all of label. reset()
Clear all information from old calculation. read (label)
Read atoms, parameters and calculated properties from output file. Read result from self.label file. Raise ReadError if the file is not there. If the file is corrupted or contains an error message from the calculation, a ReadError should also be raised. In case of succes, these attributes must set: atoms: Atoms object The state of the atoms from last calculation. parameters: Parameters object results: dict
The parameter dictionary.
Calculated properties like energy and forces.
The FileIOCalculator.read() method will typically read atoms and parameters and get the results dict by calling the read_results() method. set(**kwargs )
Set parameters like set(key1=value1, key2=value2, ...). A dictionary containing the parameters that have been changed is returned. Subclasses must implement a set() method that will look at the chaneged parameters and decide if a call to reset() is needed. If the changed parameters are harmless, like a change in verbosity, then there is no need to call reset(). The special keyword ‘parameters’ can be used to read parameters from a file. check_state(atoms, tol=1e-15)
Check for system changes since last calculation. calculate(atoms=None, properties=[’energy’], system_changes=[’positions’, ‘numbers’, ‘cell’, ‘pbc’, ‘initial_charges’, ‘initial_magmoms’] )
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’. List of what has changed since last calculation. Can be any combination of these five: ‘positions’, ‘numbers’, ‘cell’, ‘pbc’, ‘initial_charges’ and ‘initial_magmoms’.
system_changes: list of str
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. calculate_numerical_forces(atoms, d=0.001)
Calculate numerical forces using finite difference. All atoms will be displaced by +d and -d in all directions.
12.1. Development topics
217
ASE Manual, Release 3.9.0.3484
The FileIOCalculator class
class ase.calculators.calculator. FileIOCalculator(restart=None, ignore_bad_restart_file=False , label=None, atoms=None, command=None, **kwargs)
Base class for calculators that write/read input/output files. File-IO calculator. command: str Command used to start calculation. command = None
Command used to start calculation write_input(atoms, properties=None, system_changes=None )
Write input file(s). Call this method first in subclasses so that directories are created automatically. read_results()
Read energy, forces, ... from output file(s).
12.1.7 Making movies using recordmydesktop
A video tutorial can be produced in the following way: • change the screen resolution to 1280x1024, • record the movie of the screen (without sound) using recordmydesktop (gtk-recordMyDesktop), • convert the resulting ogv into avi using mencoder: mencoder video.ogv -o video.avi -oac copy -ovc lavc
• record and edit the sound track using audacity: –
use 44100 Hz for recording and save the final file as sound.wav,
–
make sure not to keep the microphone to close to avoid signal peaks,
– cut microphone signal peaks, insert silences, ...
• edit the movie using avidemux (to match the sound track): – load the video.avi : File → Open, make sure to use the following options when editing and saving: Video → Copy, Audio → Copy, Format → AVI , – add
the sound.avi: Audio → Main Track → Audio Source → External WAV ,
–
cut video frames (or copy and insert still frames to extend the video) to match the sound track. Set beginning mark and end mark - the cut or copy/paste operation applies to the selected region,
–
make sure to save intermediate stages when working on the video File → Save → Save Video (as AVI): * avidemux caches the audio track so to match the audio to a freshly cut video you can copy the audio file into another name, and add the sound track from that name, * sometimes when cutting frames avidemux does not allow to set the markers correctly, and there is no undo the last step in avidemux!
– save
the video_final.avi (that matches the sound track), and encode it into mpeg4 format using mencoder, using two passes:
io.write(ofname, s, show_unit_cell=True, bbox=[-3, -5, 50, 22], # set bbox by hand, try and error )
In case you do not have avconv, install it (ubuntu): sudo apt-get install libav-tools libavcodec-extra-53 libavdevice-extra-53 libavformat-extra-53 li
Convert the png files to a movie (img.mov): avconv -i "%d.png" -r 25 -c:v libx264 -crf 20
-pix_fmt yuv420p img.mov
the options are: -i “img%d.png” uses these files as the input, %d is a placeholder for the number -r 25 the desired frame rate, 25 FPS in this case -c:v libx264 use the h264 codec x264 -crf 20 the video quality, 20 is pretty high, the default is 23 -pix_fmt yuv420p a compatible pixel format
12.1.8 New release When it is time for a new release of the code, here is what you have to do: ** Warning: use only three digits release numbers, e.g. 3.1.0, • Checkout the Latest development release . 12.1. Development topics
219
ASE Manual, Release 3.9.0.3484
• Run the tests . • Make sure version.py has the correct version number. • Make a tag in svn, using the current version number (to make sure not to include changes done by other developers in the meantime!): svn copy -r 845 https://svn.fysik.dtu.dk/projects/ase/trunk https://svn.fysik.dtu.dk/project
Note the resulting
tag’s revision tags_revision .
• Checkout the source, specyfing the version number in the directory name: svn co -r tags_revision https://svn.fysik.dtu.dk/projects/ase/tags/3.1.0 ase-3.1.0
• Create the tar file: cd ase-3.1.0 rm -f MANIFEST ase/svnversion.py *; python setup.py sdist
Note that the tags_revision is put into the name of the tar file automatically. Make sure that you are getting only tags_revision in the tar file name! Any changes to the source will be reflected as a mixed or modified revision tag! • Put the tar file on webX (set it read-able for all): scp dist/python-ase-3.1.0."tags_revision".tar.gz root@webX:/var/www/wiki/ase-files
• Add a link on News and update the information on the Installation requirements page and the Release notes page. • Add the new release on https://pypi.python.org/pypi/python-ase/ : – under
the edit menu increase the version number to 3.1.0
– under
the files menu add the tar file as File Type Source
• Increase the version number in ase/version.py, and commit the change: cd ~/ase svn ci -m "Version 3.2.0"
Now the trunk is ready for work on the new version. • Send announcement email to the ase-users mailing list (see Mailing Lists).
12.1.9 Testing the code All additions and modifications to ASE should be tested. Test scripts should be put in the ase/test directory. The scripts in this directory may be run by using the script tools/testase or by using the function: test.test(verbosity=1, dir=None)
Runs the test scripts in ase/test. When you fix a bug, add a test to the test suite checking that it is truly fixed. Bugs sometimes come back, do not give it a second chance! Important:
How to fail successfully
The test suite provided by test.test() automatically runs all test scripts in the ase/test directory and summarizes the results.
220
Chapter 12. ASE development
ASE Manual, Release 3.9.0.3484
Test scripts are run from within Python using the execfile() function. Among other things, this provides the test scripts with an specialized global namespace, which means they may fail or behave differently if you try to run them directly e.g. using python testscript.py. Note:
If a test script causes an exception to be thrown, or otherwise terminates in an unexpected way, it will show up in this summary. This is the most effective way of raising awareness about emerging conflicts and bugs during the development cycle of the latest revision. Remember, great tests should serve a dual purpose: Working interface To
ensure that the class‘es and method ‘s in ASE are functional and provide the expected interface. Empirically speaking, code which is not covered by a test script tends to stop working over time.
Replicable results Even if a calculation makes it to the end without crashing, you can never be too sure that the
numerical results are consistent. Don’t just assume they are, assert() it! test.assert(expression ) Raises an AssertionError if the expression does not evaluate to True.
assert everything_is_going_to_be_alright if __name__ in [’__main__’, ’__builtin__’]:
test(0.1) test(0.3) test(0.7)
Unlike normally, the module __name__ will be set to ’__builtin__’ when a test script is run by the test suite. Important:
12.1.10 Buildbot buildbot is a continuous integration system. The server called buildmaster defines and schedules processes of building and testing of software to be performed by so called builders on machines called buildslaves (or buildbots). One buildslave can have several builders associated (for example a given operating system version buildslave performs testing of several software branches builders). One builder can also be associated with several buildslaves (several, “identical” machines running the same operating system), in which case buildmaster will schedule the given builder to switch periodically between the buildslaves . At the time of writing (2012) buildbot does not offer satisfactory security mechanisms, and due to clear text passwords stored/transferred both on buildmaster and buildslaves external security measures like firewall, proxy, ssh/stunnel should be used. The sections below describe the configuration of buildmaster and buildslaves.
12.1. Development topics
221
ASE Manual, Release 3.9.0.3484
Configuration of buildmaster
The buildmaster should be running as unprivileged user (usually called buildmaster ). The user and group need to be created. In order to install buildbot on RHEL6 system you need: yum install python-twisted python-jinja2 python-tempita
Additional dependencies + buildbot itself need to be installed manually: wget https://downloads.sourceforge.net/project/sqlalchemy/sqlalchemy/0.7.9/SQLAlchemy-0.7.9.tar.g wget http://sqlalchemy-migrate.googlecode.com/files/sqlalchemy-migrate-0.7.2.tar.gz
It is sufficient to unpack the files and set PYTHONPATH , and PATH accordingly. Buildbot may need to be patched for twisted compatibility http://www.npcglib.org/~stathis/blog/2012/10/20/bug-buildbot-dies-withexceptions-importerror-cannot-import-name-noresource/ Proceed with buildbot configuration: • create the master: buildbot create-master --relocatable python-ase
• reconfigure the master with doc/development/master.cfg: cp master.cfg python-ase buildbot checkconfig python-ase/master.cfg buildbot start python-ase
• consider setting up a crontab which starts buildmaster after the server reboot (this solution is not reliable, deploy rather init scripts - see below): # run every 5 minutes */5 * * * * sh ~/python-ase-restart.sh
with the following python-ase-restart.sh : bot=python-ase # no pid file - assume buildbot is not running if ! test -f $bot/twistd.pid; then buildbot restart $bot || buildbot start $bot else # pid file exists but buildbot is not running pid=‘cat $bot/twistd.pid‘ if test -z ‘ps -p $pid -o pid=‘; then buildbot restart $bot fi fi
• or create a system V init script under /etc/init.d #!/bin/sh # # python-ase: # # chkconfig: # description: # LSB init-info ### BEGIN INIT INFO # Provides: # Required-Start: # Required-Stop:
# Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: python-ase buildmaster ### END INIT INFO # Source function library. if [ -e /etc/init.d/functions ]; then . /etc/init.d/functions fi # LSB functions . /lib/lsb/init-functions # Check that networking is configured. [ "${NETWORKING}" = "no" ] && exit 0 RUN_AS=buildmaster-username PYTHON_ASE_HOME=/home/$RUN_AS/python-ase test -d $PYTHON_ASE_HOME || exit 5 LOGFILE=$PYTHON_ASE_HOME/../python-ase.log PIDFILE=$PYTHON_ASE_HOME/../python-ase.pid LOCKFILE=$PYTHON_ASE_HOME/../python-ase.lock start() { echo -n $"Starting python-ase buildmaster: " dostatus > /dev/null 2>&1 if [ $RETVAL -eq 0 ] then echo -n $"python-ase buildmaster already running" log_failure_msg RETVAL=1 return fi #su - $RUN_AS -s /bin/sh -c "exec nohup /bin/sh $PYTHON_ASE_HOME/../python-ase-start. # don’t produce log su - $RUN_AS -s /bin/sh -c "exec nohup /bin/sh $PYTHON_ASE_HOME/../python-ase-start. RETVAL=$? if [ $RETVAL -eq 0 ] then sleep 5 su - $RUN_AS -s /bin/sh -c "cat $PYTHON_ASE_HOME/twistd.pid > $PIDFILE" su - $RUN_AS -s /bin/sh -c "touch $LOCKFILE" log_success_msg else log_failure_msg fi return $RETVAL } stop() { echo -n $"Shutting down python-ase buildmaster: " kill $(su - $RUN_AS -s /bin/sh -c "cat $PIDFILE 2>/dev/null") > /dev/null 2>&1 RETVAL=$? sleep 5 if [ $RETVAL -eq 0 ] then su - $RUN_AS -s /bin/sh -c "rm -f $PIDFILE $LOCKFILE" log_success_msg else log_failure_msg fi return $RETVAL
12.1. Development topics
223
ASE Manual, Release 3.9.0.3484
} restart() { stop start } condrestart() { [ -f $LOCKFILE ] && restart || : } dostatus() { kill -0 $(cat $PIDFILE 2>/dev/null) > /dev/null 2>&1 RETVAL=$? if [ $RETVAL -eq 0 ] then echo "python-ase buildmaster (pid $(cat $PIDFILE 2>/dev/null)) is running..." else if [ -f $PIDFILE ] then echo "python-ase buildmaster dead but pid file exists" RETVAL=1 return fi if [ -f $LOCKFILE ] then echo "python-ase buildmaster dead but subsys locked" RETVAL=2 return fi echo "python-ase buildmaster is stopped" RETVAL=3 fi } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) dostatus ;; restart|reload) restart ;; condrestart) condrestart ;; ) * echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}" exit 1 esac exit $RETVAL
The service is added with:
224
Chapter 12. ASE development
ASE Manual, Release 3.9.0.3484
chkconfig --add python-ase-buildmaster
started with: service python-ase-buildmaster start
end enabled for boot time with: chkconfig python-ase-buildmaster on
See also an example of systemd script in the section below. • consider protecting the buildmaster web interface by, e.g. apache reverse proxy (http://httpd.apache.org/docs/2.4/mod/mod_proxy.html). The basic configuration file may look like # EEE.EEE.EEE.EEE is the IP of your External apache server: # ase-buildbot.fysik.dtu.dk ServerName ase-buildbot.fysik.dtu.dk ServerAlias ase-buildbot ase-buildbot.fysik.dtu.dk Redirect / https://ase-buildbot.fysik.dtu.dk/ ServerName ase-buildbot.fysik.dtu.dk ServerAlias ase-buildbot ase-buildbot.fysik.dtu.dk # important http://httpd.apache.org/docs/current/mod/mod_proxy.html ProxyRequests Off # III.III.III.III:8080 the IP and port of the Internal buildbot web server ProxyPass / http://III.III.III.III:8080/ ProxyPassReverse / http://III.III.III.III:8080/ Options -Indexes Order deny,allow Deny from all Allow from 127.0.0.1 Allow from ::1 #Allow from all SSLProxyEngine on # provide an authority signed certificate SSLCertificateFile /etc/pki/tls/certs/localhost.crt SSLCertificateKeyFile /etc/pki/tls/private/localhost.key # vim: filetype=apache shiftwidth=4 tabstop=4 wrap!
Installation and configuration of buildslaves
Some examples are given below. The configuration should be performed under an unprivileged buildslave, or buildbot user account.
12.1. Development topics
225
ASE Manual, Release 3.9.0.3484
Installation
Fedora
Install with:
yum install buildbot-slave
You can configure systemd service by creating python-ase-fedora-18-x86_64-gcc-2.7.service file under /usr/lib/systemd/system . [Unit] Description=buildslave python-ase-fedora+18+x86_64+gcc+2.7 stock After=network.target [Service] Type=forking User=buildslave-username Group=buildslave-groupname ExecStart=/usr/bin/sh /home/buildslave-username/python-ase-fedora+18+x86_64+gcc+2.7-start.sh Restart=always [Install] WantedBy=multi-user.target
python-ase-fedora+18+x86_64+gcc+2.7-start.sh simply exports the necessary environment variables (if needed) and starts buildslave (use the full path), e.g.: #!/bin/sh bot=/home/buildslave-username/python-ase-fedora+18+x86_64+gcc+2.7 buildslave start $bot
Choose User and Group under which buildslave will be running. The service is started with: systemctl start python-ase-fedora-18-x86_64-gcc-2.7.service
In order to force the service to be started at boot time create a link: cd /etc/systemd/system/multi-user.target.wants ln -s /usr/lib/systemd/system/python-ase-fedora-18-x86_64-gcc-2.7.service .
OS X
Configure Homebrew, and:
brew install subversion
Configure a virtualenv, and then: pip install numpy pip install buildbot-slave
RHEL5
Install recent python-setuptools in order to get easy_install :
can be installed and configured to start as a service on Windows http://trac.buildbot.net/wiki/RunningBuildbotOnWindows. This involves several steps: Windows build-slave
1. install Python(x,y) from https://code.google.com/p/pythonxy/wiki/Downloads 2. configure distutils to use mingw. First enable showing file extensions: Open a folder with IE -> Folder and search options-> View -> Folder Options: Check: Show hidden files, ...; uncheck: Hide extensions for known file types.
Then, in notepad, create C:\python27\lib\distutils\distutils.cfg, containing: [build] compiler=mingw32
3. install build-slave on the command line: C:\python27\scripts\easy_install.exe buildbot-slave
4. create a local (domain computer-name ) user that will run the buildbot service: control panel->administrative tools->computer management->local users and groups->users->new Click the created user: member of: administrators->check names
5. grant buildslave-username
the
ability to run the services. Login as computer-name\buildslave-username : Run secpol.msc on the command line as administrator (task bar->cmd->right click: run as administrator): • Select the “Local Policies” folder • Select the “User Rights Assignment” folder • Double click “Log on as a service” • Use “Add User or Group...” to add your user here. Select the correct “from this location” (may require login as the current domain administrator) and Enter the object names: computer-name\buildslave-username .
6. on the command line install the buildbot service: buildbot_service.py --user computer-name\buildslave-username --password thepassword --startu
7. start the service (for the moment it does not start any buildslave , because they are not configured yet): Start->Control Panel> Administrative Tools->Services->Buildbot (Start)
There are additional steps mentioned in the buildbot wiki, but it seems just to work on Windows 7. 8. run regedit as administrator (type “regedit” on the command line) and add “directories” parameter of the String Value type, containing paths to all your buildslave instances (they will be configured in the Configuration section below): HKEY_LOCAL_MACHINE\System\CurrentControlSet\services\Buildbot->paramaters->new (String Value)
9. configure buildslave instance as described in the Configuration section below and start the service again (point 7.). Test that buildslave comes online, and verify that the service starts after reboot.
12.1. Development topics
227
ASE Manual, Release 3.9.0.3484
Configuration
After having installed the buildbot create a name which will identify your buildslave. Obtain the first part of the name for your buildslave by running doc/development/master.cfg: python master.cfg
This will return a string like redhat+6+x86_64+gcc+2.6 (OS+OSversion+Bitness+Ccompiler+PythonVersion). Append it with something that identifies your buildslave , for example gpu. For a very special system you can use a name like mycluster+x86_64+open64+2.5 gpu . Note that ASE buildbot will perform verification of python version based on the buildslave name so stay consistent! Generate a strong buildslave password with Creating an encrypted password for SVN access . Don’t reuse any valuable passwords. You don’t need to remember it, buildbot stores it plain text! Create the buildslave with: buildslave create-slave python-ase-redhat+6+x86_64+gcc+2.6 buildbot.fysik.dtu.dk:ASE_BB_PORT "red
ASE_BB_PORT is the port ASE buildbot uses for communication with the buildslave. You will have to tell us the name and password of your buildslave . Please contact ase-developers list Mailing Lists, but don’t send the name and password there! Edit the python-ase-redhat+6+x86_64+gcc+2.6/info/{admin,info} files: buildslave configuration relevant for the builder process in the info file.
describe your
Note that before starting the slave you need to perform an temporary svn checkout of ASE in order to accept the certificate permanently. Start the buildslave with: buildslave start python-ase-redhat+6+x86_64+gcc+2.6
Don’t forget to configure a crontab job or a service as described in the previous sections. By default all slaves run the continuous integration for the trunk. If you prefer your buildslave works also on one of the branches, write this in the email to ase-developers Mailing Lists.
12.1.11 Translate ASE You can contribute by translating the ASE GUI, ase-gui, into your language. How to translate
If any of the below steps prove difficult, be sure to ask on the developer mailing list . These steps should work on GNU/Linux. • Download ASE. • Go to ase/gui/po. There is a directory of the form ll or ll _ LL for each language, where ll is the language code and LL the country code. The latter is necessary only if variants of the same language are spoken in multiple countries. • If your language is not there already, run LANG=ll make init, substituting the desired language code. If necessary append the country code as well: LANG=ll_LL .... • There should now be a template file for your language, ll /LC_MESSAGES/ag.po , which can be filled out. You can edit the po-file with any text editor. It is easiest with a dedicated po-editor such as gtranslator, poedit or the gettext mode in EMACS (the package “ gettext-el ”). Fill out the missing msgstr entries like this:
228
Chapter 12. ASE development
ASE Manual, Release 3.9.0.3484
#: ../energyforces.py:61 msgid "Calculate potential energy and the force on all atoms" msgstr "Beregn potentiel energi og kræfter på alle atomer"
Your editor may wholly or partially hide some of the difficult formatting syntax. This next example shows a more syntactically complex case in case you need it: #: ../calculator.py:107 msgid "" "GPAW implements Density Functional Theory using a\n" "Grid-based real-space representation of the wave\n" "functions, and the Projector Augmented Wave\n" "method for handling the core regions. \n" msgstr "" "GPAW implementerer tæthedsfunktionalteori med en Gitterbaseret\n" "repræsentation af bølgefunktioner i det reelle rum, samt\n" "Projector Augmented Wave-metoden til behandling\n" "af regionen omkring atomkerner. \n"
If you are maintaining an existing translation, there may be some “fuzzy” messages. These are translations that were written previously but now need to be reviewed, maybe because the original string has been slightly modified. Edit them as appropriate and remove the “fuzzy” flag. There will be a few special constructs such as string substitution codes %(number)d or %s. These should remain unchanged in the translation as they are replaced by numbers or text at runtime. An underscore like in msgid "_File" indicates that F is a shortcut key. Conflicting shortcut keys are not a big problem, but avoid them if you see them. Finally, some messages may have a lot of whitespace in them. This is due to bad programming style; just try to get approximately the same spacing in your translation. Already after writing a few translations, you can check that the translation works as expected by following the instructions in the next section. Check and commit your translation
• You can check the syntax by running msgfmt -cv ag.po. This will report any syntax errors. • You can test your translation in ase-gui directly. First issue the command make in ase/gui/po, then reinstall ASE using the usual procedure. The translations will then be in the newly installed ASE. If you translate into the same language as your computer’s locale, you should see the translations when you start ase-gui normally. If you translate ASE into another language, then run LANG=ll _ LL.UTF-8 ase-gui . On some operating systems you may need to run LANGUAGE= ll _ LL.UTF-8 ase-gui instead. Depending on your operating system, you may need to install gettext or locales. Send the partially or completely translated po-file to the developers mailing list and ask to have it committed. In fact, we will be quite thrilled if you send an e-mail even before you start, and be sure to send one whenever you have questions. Certain uncommon languages such as Lojban, Anglo-Saxon or Klingon may not be compatible with our current build system. Please let us know if you want to translate ASE into such languages. Note:
Maintaining translations
Messages will once in a while be added or changed in the ASE. Running make in ase/gui/po automatically synchronizes all templates with the messages in the current source tree while maximally reusing the existing translations. Some strings may be marked “fuzzy”, indicating that they need review by translators (this happens e.g. if an English message is changed only slightly). One can then update the few fuzzy or untranslated messages. The obvious time to do this is shortly before a new stable release.
12.1. Development topics
229
ASE Manual, Release 3.9.0.3484
If you are a committer, please run make before committing and briefly check by running the translated ase-gui that nothing is obviously horrible.
12.1.12 To do Check our issue tracker. Documentation
• Put example of Verlet dynamics in ase/md • talk about writing files - pos, py and pckl • Write more about the parameters of the supported elements of the EMT calculator. Code
• Could the directions argument of ase.lattice.FaceCenteredCubic etc. have default values?
12.1.13 Python 3 strategy • One codebase for both 2 and 3. • Use “print(...)” if possible: print ’bla print(’bla print ’bla print(’bla
# no bla’ bla’) # yes bla:’, x bla: %s’ % x)
# no # yes
• Don’t do this: print >> f, .... Use f.write(... file=f) .
+ ’\n’) or ase.utils.prnt(...,
• More help here: http://packages.python.org/six/
12.1.14 ASE enhancement proposals Calculator interface proposal
All ASE calculators should behave similarly if there is no good reason for them not to. This s hould make it simpler for both users and developers. This proposal tries to define how a good ASE calculator should behave. The goal is to have ASE calculators: • that share more code • are more uniform to use • are better tested • are portable Setting some standards is a good thing, but we should also be careful not to set too strict rules that could limit each calculator to the lowest common denominator.
230
Chapter 12. ASE development
ASE Manual, Release 3.9.0.3484
Behavior
When a calculator calculates the energy, forces, stress tensor, total magnetic moment, atomic magnetic moments or dipole moment, it should store a copy of the system (atomic numbers, atomic positions, unit cell and boundary conditions). When asked again, it should return the value already calculated if the system hasn’t been changed. If calculational parameters such as plane wave cutoff or XC-functional has been changed the calculator should throw away old calculated values. Standards parameters
The standard keywords that all calculators must use (if they make sense) are: xc, kpts, smearing, charge and nbands. Each calculator will have its own default values for these parameters — see recommendations below. In addition, calculators will typically have many other parameters. The units are eV and Å. Initial magnetic moments are taken from the Atoms object. xc It is recommended that ’LDA’ and ’PBE’ are valid options. kpts
• (1,1,1): Gamma-point • (n1,n2,n3) : Monkhorst-Pack grid • (n1,n2,n3,’gamma’) : Shifted Monkhorst-Pack grid that includes Γ • [(k11,k12,k13),(k21,k22,k23),...] : Explicit list in units of the reciprocal lattice vectors • kpts=3.5: k-point density as in 3.5 k -points per Å−1 smearing
The smearing parameter must be given as a tuple:
• (’Fermi-Dirac’, width) • (’Gaussian’, width) • (’Methfessel-Paxton’, width, n) , where n is the order ( n = 0 is the same as ’Gaussian’ ) Lower-case strings are also allowed. The width parameter used for the chosen smearing method is in eV units. charge Charge of the system in units of |e| (charge=1 means one electron has been removed). nbands
Each band can be occupied by two electrons.
ABC calculator example
The constructor will look like this: ABC(restart=None, ignore_bad_restart=False, label=None, atoms=None, **kwargs)
A calculator should be able to prefix all output files with a given label or run the calculation in a directory with a specified name. This is handled by the label argument. There are three possibilities: • Name of a file containing all results of a calculation (possibly containing a directory). • A prefix used for several files containing results. The label may have both a directory part and a prefix part like ’LDA/mol1’. • Name of a directory containing result files with fixed names.
12.1. Development topics
231
ASE Manual, Release 3.9.0.3484
Each calculator can decide what the default value is: None for no output, ’-’ for standard output or something else. If the restart argument is given, atomic configuration, input parameters and results will be read from a previous calculation from the file(s) pointed to by the restart argument. It is an error if those files don’t exist and are corrupted. This error can be ignored bu using ignore_bad_restart=True . The atoms argument is discussed below. All additional parameters are given as keyword arguments. Example: Do a calculation with ABC calculator and write results to si.abc: >>> atoms = ... >>> atoms.calc = ABC(label=’si.abc’, xc=’LDA’, kpts=3.0) >>> atoms.get_potential_energy()
-1.2
Read atoms with ABC calculator attaced from a previous calculation: >>> atoms = ABC.read_atoms(’si.abc’) >>> atoms.calc
>>> atoms.get_potential_energy() -1.2
The ABC.read_atoms(’si.abc’) statement is equivalent to: ABC(restart=’si.abc’, label=’si.abc’).get_atoms()
If we do: >>> atoms = ABC.read_atoms(’si.abc’) >>> atoms.rattle() # change positions and/or >>> atoms.calc.set(xc=’PBE’) # change a calculator-parameter >>> atoms.get_potential_energy()
-0.7
then the si.abc will be overwritten or maybe appended to. An alternative way to connect atoms and calculator: >>> atoms = ... >>> calc = ABC(restart=’si.abc’, label=’si.abc’, atoms=atoms) >>> atoms.get_potential_energy()
-0.7
This will automatically attach the calculator to the atoms and the atoms will be updated form the file. If you add ignore_bad_restart=True , you will be able to use the same script to do the initial calculation where si.abc does not exist and following calculations where atoms may have been moved arround by an optimization algorithm. The command used to start the ABC code can be given in an environment variable called ASE_ABC_COMMAND or as a command keyword. The command can look like this: mpiexec abc PREFIX.input > PREFIX.output
or like this: ~/bin/start_abc.py PREFIX
The PREFIX strings will be substituted by the label keyword. Implementation
• Portability (Linux/Windows): os.system(’Linux commands’) not allowed.
232
Chapter 12. ASE development
ASE Manual, Release 3.9.0.3484
• Common base class for all calculators: Calculator . Takes care of restart from file logic, handles setting of parameters and checks for state changes. • A FileIOCalculator for the case where we need to: – write
input file(s)
– run Fortran/C/C++ code – read
output file(s)
• Helper function to deal with kpts keyword. Command line tools
This proposal tries to clean up the command line tools that we distribute with ASE. Current status
ASE currently has 7 command line tools that we install in /usr/bin: command ag ASE2ase testase ase asec foldtrajectory trajectoryinfo
description
ASE’s GUI Translate old ASE-2 code to ASE-3 style Run tests First attempt to create a command that can do everything Second attempt Wrap atoms outside simulation box to inside box Write information about trajectory file
Proposed set of command line tools
In the future things will look like this: command ase-gui ase-info ase-test ase-build ase-run ase-db
description
ASE’s GUI Write information about files Run tests Build simple molecule or bulk structure Run calculations with ASE’s calculators Put stuff into or query database
Comments
ag:
Renamed to ase-gui. ASE2ase:
Removed — no longer needed. testase:
Renamed to ase-test. Alternative: python setup.py test
ase and asec:
12.1. Development topics
233
ASE Manual, Release 3.9.0.3484
Replaced by new commands ase-build and ase-run. The old ase command is documented here and is hopefully not used a lot since we propose to get rid of it. foldtrajectory:
Too specialized to deserve its own command. Use: python -m ase.md.foldtrajectory
instead. trajectoryinfo:
Replaced by new more general command ase-info that can pull out information from anything that ASE can read. Naming convention
Any suggestions for better names or are the proposed ones OK? The good thing about using ase-something for all is that it is consistent and if you know one command, you will maybe discover the other ones when you do tab-completion. Implementation details
• Should we use the very nice argparse module, which is the future but only available in Python 2.7, or should we stick with the old and deprecated optparse module?
12.2 Creating an encrypted password for SVN access Use this command: htpasswd -nm
and type a good password twice. The encrypted password will be printed on the screen. Alternatively, you can use: openssl passwd -apr1
followed by your password (twice).
234
Chapter 12. ASE development
CHAPTER
THIRTEEN
BUGS! If you find a bug in the ASE software, please report it to the developers so it can be fixed. We need that feedback from the community to maintain the quality of the code.
13.1 Bug report • If you are unsure if it is a real bug, or a usage problem, it is probably best to report the problem on the ase-users mailing list (see Mailing Lists). Please provide the failing script as well as the information about your environment (processor architecture, versions of python and numpy). Then we (or other users) can help you to find out if it is a bug. Another advantage of reporting bugs on the mailing list: often other users will tell you how to work around the bug (until it is solved). • If you think it is a bug, you can also report it directly on our bug tracking system. The advantage of reporting bugs here is that it is not forgotten (which may be a risk on the mailing list). We do not guarantee to fix all bugs, but we will do our best.
13.2 Known bugs A list of known bugs (tickets) is on our Trac.
235
ASE Manual, Release 3.9.0.3484
236
Chapter 13. Bugs!
CHAPTER
FOURTEEN
PORTING OLD ASE-2 CODE TO VERSION 3 The old Numeric-Python based ASE-2 can coexist with the new numpy-based ASE-3, because the two packages have different names: ASE and ase respectively. Here is an example of combining both: from ASE.Trajectories.NetCDFTrajectory import NetCDFTrajectory
traj = NetCDFTrajectory(’a.nc’) loa = traj.GetListOfAtoms(-1) # Convert to new style Atoms object:
from ase import *
a = Atoms(loa)
The new ASE can actually read old NetCDF trajectory files, so this would be simpler: from ase import *
a = read(’a.nc’)
Reading old NetCDF files in the new ASE, works even without having the libnetcdf and Scientific.IO.NetCDF libraries installed. Note:
14.1 The ASE2ase tool Use the ASE2ase tool (source code tools/ASE2ase) to convert old scripts: $ ASE2ase oldscript.py $ diff -u oldscript.py.bak oldscript.py
Check that the differences look OK. The conversion tool isn’t clever enough to get everything right, so you will have to do some conversion manually also. If you have any problems doing this, then you should not hesitate to contact the campos-devel mailing list (see Mailing Lists) and ask for help.
237
ASE Manual, Release 3.9.0.3484
238
Chapter 14. Porting old ASE-2 code to version 3
BIBLIOGRAPHY
[Alfe] D. Alfe, PHON: A program to calculate phonons using the small displacement method, Comput. Phys. Commun. 180, 2622 (2009) [Wang] Y. Wang et al., A mixed-space approach to first-principles calculations of phonon frequencies for polar materials, J. Phys.: Cond. Matter 22, 202201 (2010) [MonkhorstPack] Hendrik J. Monkhorst and James D. Pack: Special points for Brillouin-zone integrations , Phys. Rev. B 13, 5188–5192 (1976) [Bader] R. F. W. Bader. Atoms in Molecules: A Quantum Theory. Oxford University Press, New York, 1990. [Tang] W. Tang, E. Sanville, G. Henkelman. A grid-based Bader analysis algorithm without lattice bias. J. Phys.: Compute Mater. 21, 084204 (2009). [Cordeo08] Covalent radii revisited , Beatriz Cordero, Verónica Gómez, Ana E. Platero-Prats, Marc Revés, Jorge Echeverría, Eduard Cremades, Flavia Barragán and Santiago Alvarez, Dalton Trans., 2008, 2832-2838 DOI:10.1039/B801115J